[javascript] jQuery: more than one handler for same event



Answers

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.

Question

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?




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.




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.




Related