27

Assuming that there are a large number of elements throughout the site that have an unknown number and type of events bound to them.

If I need to override all of these events with one single bound event, and only that event will fire, what are some recommendations?

I would be binding the event to a click event handler, and I am using jQuery.

Thanks in advance.

jerome
  • 4,809
  • 13
  • 53
  • 70
  • 1
    You mean without actually unbinding the original events handlers? – user113716 Jan 11 '11 at 15:09
  • Ugh; this sounds like a really bad idea. However I suspect you could do it by figuring out the internal jQuery mechanism and subverting it with your own code. – Pointy Jan 11 '11 at 15:11
  • @patrick dw - Unbinding all of the original click event handlers is fine, as long as that does not require identifying the exact event that is associated with the click. If there is a way to "unbind all click events" then "bind this specific, overriding click event", then that would be just fine. – jerome Jan 11 '11 at 15:12
  • Will all the elements get the same handler for each event type? And were the original ones bound using jQuery? If not, how were they bound? – user113716 Jan 11 '11 at 15:17

4 Answers4

56

You’re looking for jQuery#unbind.

To remove all event handlers on an element or a set of elements, just do:

$('.some-selector').unbind();

To unbind only click handlers, use unbind('click'):

$('.some-selector').unbind('click');

To unbind all click handlers and immediately bind your own handler after that, you can do something like this:

$('.some-selector').unbind('click').click(function(event) {
  // Your code goes here
});

Note that this will only work for events bound using jQuery (using .bind or any jQuery method that uses .bind internally). If you want to remove all possible onclick events from a given set of elements, you could use:

$('.some-selector')
  .unbind('click') // takes care of jQuery-bound click events
  .attr('onclick', '') // clears `onclick` attributes in the HTML
  .each(function() { // reset `onclick` event handlers
    this.onclick = null;
  });
Mathias Bynens
  • 144,855
  • 52
  • 216
  • 248
8

I would like to provide a thought without removing all events all together (just override them).

If your new one single bound event (we call it "click" here) is specific to the element it binds to, then I believe you can ignore any other events simply by stopPropagation() function. Like this

$("specific-selector").on("click", ".specific-class", function (e) {
  e.stopPropagation()
  // e.stopImmediatePropagation()
  /* your code continues ... */
});

It will stop events bubbles up, so your other events won't fire. use stopImmediatePropagation() to prevent other events attached onto the same elements as "click" does.

For example, if "mouseleave" event is also bind to $("specific-selector .specific-class") element, it won't fire, too.

At last, all other events won't fire on this element but your new "click" element.

The unsolved question is, what if other events also use stopPropagation()? ... Then I think the one with best specification wins, so try to avoid complex, too many events is final suggestion.

You can see "Direct and delegated events" on jQuery site for more information.

francischan
  • 91
  • 1
  • 2
1

Try to use live instead of bind. Then you can easily remove live binding with die from selector which is fast operation and set another live equally fast.

   $('selection here').live('..', .....);  // multiple invocations
   $('selection here').die();
   $('selection here').live('click',.....);

DOM is not touched at all. Event condition is evaluated on event occurrence.

But generally if you just want to swap handler functions why not to do it this way:

var ahandler = function(evt) { /* first implementation */ }
$('.selector').bind('click', function(evt) { ahandler(evt); });

//and then if you want to change handlers
ahandler = function(evt) { /* new implementation */ };

This gives absolutely no cost of any changes, rebinding etc.

gertas
  • 16,869
  • 1
  • 76
  • 58
1

Looks like this is pretty simple actually:

$('#foo').unbind('click');
$('#foo').bind('click', myNewFunction);

Thanks for your responses though.

jerome
  • 4,809
  • 13
  • 53
  • 70
  • 1
    You don’t need two statements, you can chain them together (as I explained in [my answer](http://stackoverflow.com/questions/4659032/override-all-javascript-events-bound-to-an-element-with-a-single-new-event/4659067#4659067)). – Mathias Bynens Jan 11 '11 at 15:17