I have been reading a lot on the order in which events are handled in JavaScript. All articles I have read are about bubbling and capturing. That's all about the same kind of event being bubbled/captured from children to parents or from parent to children. You can't really predict in which order these events will be executed. That stuff is really clear.
My question is about the order of events in the following case:
Suppose a screen with a textfield with an onChange listener on it. Next to the field there's a button with an onClick listener on it.
Suppose you alter the textfield's value and keep the cursor in the field and directly press the button.
In all my testing it was always the onChange being executed before the onClick. I have reason to believe that this order is not always the same.
Does this sound familiar to you?
What can be said about the order in which these onChange and onClick events are handled? Does this also depend on the js implementation, or other factors?
Kind regards,
Guus
Related
I have a bunch of jQuery functions that use the .on event because I want to prevent reapplying the event to the same element.
However some people created plugins (e.g. Owl Carousel) and I don't know how to prevent this event from reapplying.
Currently I am using the plugin as following:
HTML:
<div class="init-owl"></div>
JS:
$('.init-owl').owlCarrousel();
$('.init-owl').removeClass('init-owl');
Whenever a second element gets loaded in the page using e.g. AJAX, I want to only apply the event to the newly added element.
Question: What I dont understand is how the event stays stuck to the DOM?
To better grip what is happening, I was wondering how an event in general gets connected to the DOM?
Is there a better way to prevent events applying to the same DOM elements?
If I wish to write my own plugins, I would need to know how javascript works, right?
Question: What I dont understand is how the event stays stuck to the DOM?
Once an event is bound to an object, it gets removed when the object gets garbaged collected. So if a DOM element is really gone and there are no references to it, then the event will get swept up as well.
To better grip what is happening, I was wondering how an event in general gets connected to the DOM?
I'm not sure how far you want to dive into this. Maybe it would help if you stop thinking about the DOM and events and look more at just regular events bound to objects. Basically an object does something, or something is done to it and some underlying code (in the browser's code in this case) triggers an event on that object. The implementations between browsers may differ, but basically you will have a key or string (the event name) that maps to a collection of functions. When you add an event listener, you add another function to this collection. Then when something triggers that event, it iterates through the functions and executes them. That's a real basic explanation, but I hope it makes things a little more clear.
Is there a better way to prevent events applying to the same DOM elements?
Make sure you don't add the events again by writing better code. I don't believe you can dive down into an element and look to see if it has events bound to it. You can however change your jQuery selector to only target newly added elements. If you have to, mark the elements that you have added events to with a class or something. Then you could target your elements by doing $('.init-owl:not(.already-bound)'). There is a better solution to your problem, I can assure you, but we might need more context and code to see a better way to help you.
EDIT:
You can look into jQuery's off() function to remove events. That may help you too.
I'm working on a JavaScript 'form' (it's not actually a form - it's a Knockout interface that makes a request to another JavaScript object, but that's not important) and I'm a bit worried about some behavior I'm not sure I can rely upon.
Let's say I have an input and I've attached a change event, either natively through onChange or via jQuery change. That change event updates a model that I'm going to validate and then send off to the server as part of my form 'submission'.
I also have a button with a click event that performs the submission.
If I click the button, as far as I can tell, the form element change event triggers first. But can I rely on this behaviour? Is the fact the change event fires first part of a recognized specification, or just a browser implementation detail?
I took a look at the events specification (http://www.w3.org/TR/2014/WD-DOM-Level-3-Events-20140925/) but couldn't find an answer to my specific question, just that click, blur and focus events are treated synchronously - that is, they're added to a queue and executed in order. But I don't know if the order is consistent between user agents.
Is this behaviour guaranteed by any specification?
Other javascript is changing the value of an input and I was wondering if there was a way to detect the change.
This question has nothing to do with Keyup or Change. This is not being typed in by the user it is being changed by other javascript though various actions of the user.
When changing an event programatically, you can trigger a change event to make sure event handlers that are attached to the element are fired. jQuery has a trigger() method to do this:
$('#elementID').on('change', function() {
alert( this.value );
});
$('#elementID').val('some new value').trigger('change');
The quick run-down of what I am going to say is: there is no way other than to modify the third-party scripts to output stuff, or to use setInterval (costly).
The bottom line of this issue is a simple one, that does not appear to be so at first: How can you get your scrips to communicate with each other?
When a script modifies the value of an input through JS methods (i.e. not user input), they have to go through specific hoops to get the "change" event to fire (they can fire it manually by calling it, which most devs never do and is easily forgotten when writing code). In practice, people tend to rely on the observation events (user-defined ones) to track code changes. This is very similar to DOM events - you bind callbacks to your script, which allow you to tap callbacks in that will fire whenever your scripts do something interesting (like modifying inputs. This is just one example). You then teach your scripts and developers to fire events on useful stuff using the callbacks to notify other scripts.
A great library for this is Postal, which is originally a Node library. jQuery also has an event system you can tap into. However, if you want to roll your own, all you have to read into is the Observer design pattern. It is trivial: you bind a function to your object to pick up callbacks, and another to fire them. Whenever you change the thing, you fire the callback. Simples.
Failure to do so means setInterval. Sucks, but there you go :-(
In the case of a game where user have to click/use keys mutli and many times,
Is there any advantage to use event.stopPropagation() in all event
handler which i know bubbling is useless?
Suppose i have a div with a click event binded,
<div id="mydiv">CLICK</div>
$('#mydiv').click(function(){...});
if i click on it, this event will propagate to all ancestors elements of this div (e.g body/html/document/window). So just wondering if this could be better or same or worst to stop immediatly propagation of event.
In fact, i don't know how javascript engine internally deal with events binded (or not) to elements, if this works as a listener or what...
It is a bit general, but to answer your direct question, unless you need to stop propagation then there is no reason to do so. Propagation is not what is going to hinder the efficiency of your game, it's having too many event bindings. Consider using a generic binding on a parent element and then processing the actual target of the event to determine what action to take.
in javascript, when I receive a focus event, how can I work out which element has lost focus? I'm trying to avoid having to put an onblur event handler on all elements within my web page.
#pbrodka: the target/srcElement property would refer to the element with focus for onfocus events
offhand I can't see a way to get this short of onblur, or if the set of objects you care about all have focus methods you could store a reference to that object instead. It's also possible event bubbling could get you out of jail
this all feels like a bit of a code smell though - perhaps you need to describe the problem in more detail
Difficult this. You cannot use event delegation to find out which control last produced a blur as focus/blur do not bubble up. There have been some attempts to 'fix' this but they are buggy and not resiliant cross browser.
Could I ask you why do you need this information as maybe there is an alternative solution.
Unfortunately, the onblur event doesn't bubble, otherwise you could have handled it at the window level to always know when an element lost focus.
As things are, I do believe it will be hard to do without, as you say, adding an onblur event handler to all elements (a truly nasty solution ;-).
It is possible to delegate the focus and blur events, if you follow PPK's advice, here:
http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html
The most simple solution is to write a function that walks all forms and then all elements within the form and installs an onblur handler for each (which will probably call some global function). This handler will get an event and this event will contain the info you seek.
This way, you just have to call this method once in body.onload and it will work no matter how complex your document is.
The only drawback is that you will need to call it if you dynamically add forms to your current document. In this case, you must make sure not to install the handler again (or you will get spurious duplicate events).