Can someone explain what is the proper way to make certain actions call functions in javascript? Should I use event handlers like onclick="callFunction();"? Or should I use an event listener? If yes, how do they work?
Related
I am learning JavaScript I have a question while I studied to Event.
As I know we have two ways to handle an event, Event Handler and Event Listener.
I can only have one event handler for a specific event type, but I can add multiple event listeners for it.
It seems like event listener is better than handler, and why or when do we need the Event Handler ?
MDN explains:
If an EventListener is added to an EventTarget while it is processing an event, that event does not trigger the listener. However, that same listener may be triggered during a later stage of event flow, such as the bubbling phase.
What are the ways to prevent this from happening?
Possible Solutions:
Call event.stopPropagation() when the event is invoked.
I'm not a fan of this solution because the solution is not localized near the problem. The solution is in where the click originates and the problem is the code that adds the new event listener.
Add the event listener inside of a setTimeout:setTimeout(() => {element.addEventListener('click', clickHandler},0)
This solution is cohesive: the problem of the new eventListener triggering immediately is solved right where the event listener is added. Also it doesn't stop propagation for an event that other listeners might depend on. However, it feels like a hack to wrap it inside a setTimeout like this.
Do better solutions exist to prevent the new event listener from firing immediately due to the click that caused the event listener to be added?
This problem occurred for me when attempting to make a popup appear that closes itself for a click outside. Since the click that creates the popup is also a click outside. The popup closes immediately.
Link to example use-case including solutions
is there any universal way to instrument javascript event handler firing using javascript?
for example, I want to do something before the event handler firing, so when to fire an event, I would like to execute my code first then the event handler code.
The problem is that there are multiple ways to register event handlers, I would like to handle all of them: html, javascript
No, there's not.
You can hook addEventListener and removeEventListener, which would allow you to intercept both the registration and invocation of event listeners by JS code. However, this will not capture event listeners set in ways such as elt.onclick. Nor of course will it catch listeners set up via the old IE attachEvent API. Most importantly, it will not help with you that events that are generated and listened for internally, such as a mouse click on a check box.
You might be tempted to hook createEvent and dispatchEvent in similar fashion, but that will capture only events that are explicitly created or dispatched in the JS code.
How do I prevent JavaScript from handling two events at once?
I have an event handler declared such as document.addEventListener('keydown',function(e)
{},false)
in this case, I do not want the handler to handle any events until it has finished with the current one.
Javascript is single threaded so the current event processing will finish before the next event is triggered. You do not have to do anything to guarantee that only one event is processed at a time.
You can learn more about this topic from these other posts:
How does JavaScript handle AJAX responses in the background? (describes how event queues in javascript operate)
Can JS event handlers interrupt execution of another handler?
Race conditions with JavaScript event handling?
There is nothing as simultaneous event handling. Event order depends upon which browser is being used. It is you who decides how to register an event either in capture or bubbling model or use both theses in w3c model.
For example in W3c model any event taking place in the W3c model is captured till the target is reached, and then it starts bubbling up again.
You can decide to register your event in either capturing or bubbling phases through the addEventListner() method.
If more than one event handlers will response to one event, and the event handler callback function is defined in different places, how can i tell which handler will be triggered first, e.g.when checking on/off a radio, the radio binds several handlers, so how to tell which one will be executed first?
Javascript event handler order
If you use JQuery to bind your events, it guarantees that handlers are
fired in the same order that they were bound. Otherwise the order is
officially undefined.
If you cannot use JQuery or a similar framework you can easily
simulate this by using your own custom even binding, where your
generic handler is a function which keeps an array of functions and
calls them in order.
Documentation -
All handlers bound to that event type for the element are fired. If there are multiple handlers registered, they will always execute in the order in which they were bound. After all handlers have executed, the event continues along the normal event propagation path.