21

I've noticed that the order of 'click' and 'change' events are different in Chrome and Firefox.

See this JSFiddle for example: http://jsfiddle.net/5jz2g/3/

JavaScript:

var el = $('foo');
var fn = function(e) {
    console.log(e.type);
}
el.addEvent('change', fn);
el.addEvent('click', fn);

In Chrome this logs:

change
click

And in Firefox this logs:

click
change

Is there a standard for the order of events? Which should fire first? The MDN doesn't seem to mention this and I couldn't find a thing about this in the W3C documents.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
stroborobo
  • 448
  • 1
  • 4
  • 10
  • 10
    If it's not mentioned, I would not rely on it. Same thing for the blur event. As a side note, you should surely never rely on one listener being called before the other (when you register two listeners for the same event, since that is specified as undefined) http://stackoverflow.com/questions/2706109/are-event-handlers-in-javascript-called-in-order – Ruan Mendes Jul 29 '14 at 12:10
  • Could you please share with us the requirement that led you to investigate this? Perhaps we can suggest a solution if we understand the context. – Lix Jul 29 '14 at 12:11
  • 1
    It is not relevant for checkboxes at least, you need to listen only change event – micnic Jul 29 '14 at 12:11
  • 3
    If your architecture design relies on those events order, then 99% that you should reconsider that architecture – Alma Do Jul 29 '14 at 12:12
  • 3
    @micnic the reason "change" event is problematic is behavior of older versions of Internet Explorer. They do not fire the "change" event until the element loses focus. – Pointy Jul 29 '14 at 12:13
  • Interestingly, you can put `.preventDefault()` in the click handler. In Chrome, the change handler still fires, even though the state of the checkbox didn't change. But in FF this prevents the change handler. See http://jsfiddle.net/barmar/5jz2g/9/ – Barmar Jul 29 '14 at 12:21
  • 2
    IMHO, FF is doing it right. It's similar to the relationship between the click event on a form's submit button and the form's submit event. – Barmar Jul 29 '14 at 12:22
  • 1
    @JuanMendes: Please notice that I have just updated the thread you did link to :-) – Bergi Jul 29 '14 at 13:41
  • @Barmar I agree with you, but I still wouldn't rely on it. Same thing with wanting JavaScript object (or JSON) keys to be iterated in the order you added them. It'd be nice, but it's not specified. – Ruan Mendes Jul 29 '14 at 13:44
  • @Bergi Thanks, I was not aware of that. Too bad I can't edit my comment now. Let's give Bergi's answer there more upvotes to spread the knowledge – Ruan Mendes Jul 29 '14 at 13:45

4 Answers4

9

DOM3 Events document has a recommendation about events order. According to it, in case of checkbox, the correct order will be click then change and not vice versa, because change event obviously is a part of default actions for checkbox, see Example 5 and fiddle, which works as expected in FF but not in Chrome. That's logical, anyway. But! Let's read default actions section carefully:

Default actions should be performed after the event dispatch has been completed, but in exceptional cases may also be performed immediately before the event is dispatched.

Did you see that? W3C uses RFC's words SHOULD and MAY in one sentence! Nothing to be done, they're cautious guys. IMO, that's why we have what we have :)

raidendev
  • 2,729
  • 1
  • 22
  • 23
0

No, but if you want to make it consistent, you can fire one event off the other rather than having them fire separately since for a check box and change amount to the same event...or perhaps you could use an interval timer to to delay the response on one of the events.

Dale Corns
  • 225
  • 1
  • 6
0

try this

$(function(){

    var $select = $('foo');
    var store = function(e) {
        console.log(e.type);
    };

    $select.addEvent('change', store).addEvent('click', store);

});

http://jsfiddle.net/donddoug/Du7z5/

raidendev
  • 2,729
  • 1
  • 22
  • 23
0

Couldn't find a way to sync events cross browser...

the following does work in the same order in both FF and Chrome;

JavaScript Code (use mouseup / mousedown to catch the "click"):

var el = $('foo');
var fn = function(e) {
    console.log(e.type);
}
el.addEvent('change', fn);
el.addEvent('mouseup', fn);

http://jsfiddle.net/5jz2g/17/

Yonatan Ayalon
  • 1,959
  • 18
  • 19