143

What happens if I bind two event handlers to the same event for the same element?

For example:

var elem = $("...")
elem.click(...);
elem.click(...);

Does the last handler "win", or will both handlers be run?

stephenwade
  • 1,057
  • 2
  • 20
  • 37
flybywire
  • 261,858
  • 191
  • 397
  • 503

8 Answers8

176

Both handlers will run, the jQuery event model allows multiple handlers on one element, therefore a later handler does not override an older handler.

The handlers will execute in the order in which they were bound.

Russ Cam
  • 124,184
  • 33
  • 204
  • 266
  • 1
    what happens with the native way? and how does the native know how to remove a specific one? – SuperUberDuper Aug 11 '15 at 21:09
  • 1
    According to DOM Level 3 (referencing HTML 5 spec), event handlers are executed in the order in which they are registered -http://www.w3.org/TR/DOM-Level-3-Events/#event-phase and http://www.w3.org/TR/2014/REC-html5-20141028/webappapis.html#event-handler-attributes. Event handlers can be removed by passing a reference to the handler that was registered – Russ Cam Aug 11 '15 at 23:26
  • @RussCam what happens if a same handler is bound more then once lets just say `jQuery('.btn').on('click',handlerClick);` is called at various places without actually `.off` it anywher? – techie_28 May 24 '16 at 09:01
  • Note that for jQueryUI widgetfactory widgets, this isn't true if you set the handler as an option. For both the old and new handler to be called, you need to use the `bind` method. See this for details: http://learn.jquery.com/jquery-ui/widget-factory/how-to-use-the-widget-factory/#adding-callbacks – Michael Scheper Feb 12 '18 at 01:23
  • @MichaelScheper feel free to edit the answer and update with additional info – Russ Cam Feb 12 '18 at 01:30
  • @RussCam: Thanks. Do you think it's sufficiently relevant, though, given that the question is about jQuery in general, and not jQueryUI? – Michael Scheper Feb 13 '18 at 19:38
  • also , if you want just one to run, you would need to use EVENT NAMESPACE --- just putting out there – Karun May 30 '19 at 13:06
37

Suppose that you have two handlers, f and g, and want to make sure that they are executed in a known and fixed order, then just encapsulate them:

$("...").click(function(event){
  f(event);
  g(event);
});

In this way there is (from the perspective of jQuery) only one handler, which calls f and g in the specified order.

Stephan202
  • 59,965
  • 13
  • 127
  • 133
  • 3
    +1, encapsulation inside a function is the way to go. And even better conditional logic can be contained inside the handler function to control the event(s) that get triggered. – Gordon Potter Sep 29 '09 at 10:49
  • A collection of handlers whose sequence is programmatically determined. – Aaron Blenkush Mar 25 '14 at 05:54
18

jQuery's .bind() fires in the order it was bound:

When an event reaches an element, 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.

Source: http://api.jquery.com/bind/

Because jQuery's other functions (ex. .click()) are shortcuts for .bind('click', handler), I would guess that they are also triggered in the order they are bound.

Peter O.
  • 32,158
  • 14
  • 82
  • 96
allicarn
  • 2,859
  • 2
  • 28
  • 47
11

You should be able to use chaining to execute the events in sequence, e.g.:

$('#target')
  .bind('click',function(event) {
    alert('Hello!');
  })
  .bind('click',function(event) {
    alert('Hello again!');
  })
  .bind('click',function(event) {
    alert('Hello yet again!');
  });

I guess the below code is doing the same

$('#target')
      .click(function(event) {
        alert('Hello!');
      })
      .click(function(event) {
        alert('Hello again!');
      })
      .click(function(event) {
        alert('Hello yet again!');
      });

Source: http://www.peachpit.com/articles/article.aspx?p=1371947&seqNum=3

TFM also says:

When an event reaches an element, 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.

anddoutoi
  • 9,973
  • 4
  • 29
  • 28
  • 1
    Neither that code nor that article defines an order of handler execution. Yes, that is the order the event *binding* will occur, but the order the event handlers get called is still officially undefined. – Crescent Fresh Sep 29 '09 at 10:58
  • ehh? what about "Now when the click event occurs, the first event handler will be called, followed by the second, followed by the third." is unclear? – anddoutoi Sep 29 '09 at 11:00
  • and yes, i know that the official recs do not define this and PPK has already proved that the event execution is random but maybe jQuery has fixed this ^^ – anddoutoi Sep 29 '09 at 11:04
  • Ahh, missed that sentence. In fact, the author is misinformed. jQuery has not "fixed" this. Because the spec does not formally define the order, technically nothing needs fixing. – Crescent Fresh Sep 29 '09 at 11:50
  • Yeah, I find it weird. The same example and code is also in the book jQuery in Action by Bibeault and Katz with foreword by jresig himself. Wish that John could confirm or refute this once in for all. I know your here on SO John so could you? Please ^^ – anddoutoi Sep 29 '09 at 13:31
  • 5
    @CrescentFresh: Sorry for such a late reply, I just saw the question, but I'd like you to point to [link](http://api.jquery.com/bind/), it is official documentation of jQuery and it clearly says that `When an event reaches an element, 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.` – Razort4x Sep 05 '12 at 08:52
  • THANK YOU @Razort4x Too bad I was downvoted by ppl high on FUD >. – anddoutoi Sep 05 '12 at 11:39
2

Both handlers get called.

You may be thinking of inline event binding (eg "onclick=..."), where a big drawback is only one handler may be set for an event.

jQuery conforms to the DOM Level 2 event registration model:

The DOM Event Model allows registration of multiple event listeners on a single EventTarget. To achieve this, event listeners are no longer stored as attribute values

Crescent Fresh
  • 115,249
  • 25
  • 154
  • 140
2

Made it work successfully using the 2 methods: Stephan202's encapsulation and multiple event listeners. I have 3 search tabs, let's define their input text id's in an Array:

var ids = new Array("searchtab1", "searchtab2", "searchtab3");

When the content of searchtab1 changes, I want to update searchtab2 and searchtab3. Did it this way for encapsulation:

for (var i in ids) {
    $("#" + ids[i]).change(function() {
        for (var j in ids) {
            if (this != ids[j]) {
                $("#" + ids[j]).val($(this).val());
            }
        }
    });
}

Multiple event listeners:

for (var i in ids) {
    for (var j in ids) {
        if (ids[i] != ids[j]) {
            $("#" + ids[i]).change(function() {
                $("#" + ids[j]).val($(this).val());
            });
        }
    }
}

I like both methods, but the programmer chose encapsulation, however multiple event listeners worked also. We used Chrome to test it.

1

There is a workaround to guarantee that one handler happens after another: attach the second handler to a containing element and let the event bubble up. In the handler attached to the container, you can look at event.target and do something if it's the one you're interested in.

Crude, maybe, but it definitely should work.

David
  • 815
  • 8
  • 18
0

jquery will execute both handler since it allows multiple event handlers. I have created sample code. You can try it

demo

Dushyant Joshi
  • 3,672
  • 3
  • 28
  • 52
Vikram Rajput
  • 101
  • 1
  • 9