11

How do you copy an event handler from one element to another? For example:

$('#firstEl')
    .click(function() {
        alert("Handled!");
    })
;

// here's where the magic happens 
$('#secondEl').click = $('#firstEl').click; // ????

Note that the second element is being processed at a different time to when the first element is getting its handler, meaning that this:

$('#firstEl, #secondEl').click(function() { ... });

...won't work.

Kaspar Lee
  • 5,446
  • 4
  • 31
  • 54
nickf
  • 537,072
  • 198
  • 649
  • 721

6 Answers6

24

This question was already answered but for future reference: you could copy them by iterating the events of the original element and binding their handlers to the target.

> see edit below!

// iterate event types of original
$.each($('#original').data('events'), function() {
  // iterate registered handler of original
  $.each(this, function() {
    $('#target').bind(this.type, this.handler);
  });
});

This is handy when you have no control of the original element (e.g. when using a plugin) and just want to clone the behavior of a certain element.

Edit: Access to an elements event handlers has been changed in later jQuery versions. This should work for newer versions:

$.each($._data($('#original').get(0), 'events'), function() {
  // iterate registered handler of original
  $.each(this, function() {
    $('#target').bind(this.type, this.handler);
  });
});

Cheers

Christof
  • 3,777
  • 4
  • 37
  • 49
  • Using the `triggerHandler()` JQuery method is a better solution. @KenBrowing has an answer on that below: http://stackoverflow.com/a/442305/1988326 – mark.monteiro Dec 09 '15 at 14:25
  • 1
    @Chris: Thank you for the edit. After searching for days for a solution to save events and handle them later, this is the only place i found where the access to the event handlers of jquery is described. Thank you very much :) – zreptil Dec 05 '17 at 08:07
4

You can't easily (and probably shouldn't) "copy" the event. What you can do is use the same function to handle each:

var clickHandler = function() { alert('click'); };
// or just function clickHandler() { alert('click'); };

$('#firstEl').click(clickHandler);

// and later
$('#secondEl').click(clickHandler);

Alternatively you could actually fire the event for the first element in the second handler:

$('#firstEl').click(function() {
    alert('click');
});

$('secondEl').click(function() {
    $('#firstEl').click();
});

Edit: @nickf is worried about polluting the global namespace, but this can almost always be avoided by wrapping code in an object:

function SomeObject() {
    this.clickHandler = function() { alert('click'); };
}
SomeObject.prototype.initFirstEvent = function() {
    $('#firstEl').click(this.clickHandler);
};
SomeObject.prototype.initSecondEvent = function() {
    $('#secondEl').click(this.clickHandler);
};

or wrapping your code in an anonymous function and calling it immediately:

(function() {
    var clickHandler = function() { alert('click'); };
    $('#firstEl').click(clickHandler);
    $('#secondEl').click(clickHandler);
})();
Prestaul
  • 83,552
  • 10
  • 84
  • 84
  • ah yes that would work, but I was hoping for a method which wouldn't pollute the global namespace. – nickf Jan 14 '09 at 03:57
2

You might be interested in the triggerHandler method

// here's where the magic happens 
//$('#secondEl').click = $('#firstEl').click; // ????
$('#secondEl').click(function() {
    $('#firstEl').triggerHandler('click');
});
Ken Browning
  • 28,693
  • 6
  • 56
  • 68
0

Is this what you are looking for?

var clickHandler = function() { alert("Handled!"); }
$('#firstEl').click(clickHandler);
$('#secondEl').click(clickHandler);
Beau Simensen
  • 4,558
  • 3
  • 38
  • 55
-3

$('#secondEl').click = $('#firstEl').click.bind($('#secondEl'));

Assuming you are using Prototype JS (http://www.prototypejs.org/api/function/bind)

TRF
  • 548
  • 1
  • 5
  • 7