Today I had to solve a task wich seemed to be quite easy... I had to copy a "click" event from an element. To copy an "onclick" attribute...it's a piece of cake. BUT, how do you copy a jQuery "click" event?
I found an interesting conversation about this problem here, but I couldn't find a solution for my problem:
http://forum.jquery.com/topic/how-do-i-copy-the-click-event-from-one-element-to-another.
I'm not 100% sure you understand my problem, so here are some example codes:
This is a common "a" tag with an onclick attribute:
<a href="javascript:void(null)" onclick="alert('onclick event triggered')" id="test_element">Trigger OnClick</a>
This click event can be copied with this code:
jQuery("#test_element").attr("onclick")
BUT, what's the case with this method?
<a href="javascript:void(null)" id="test_element">Trigger OnClick</a>
And with this Javascript:
jQuery("#test_element").click(function() {
alert("jQuery click event triggered");
})
How do I copy this click event?
Well, I dove in jQuery-s source code because I knew it can be done. jQuery has a .clone() function which has an attribute to decide, whether to copy the events too or not. This is what I found:
function cloneCopyEvent( src, dest ) {
if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
return;
}
var type, i, l,
oldData = jQuery._data( src ),
curData = jQuery._data( dest, oldData ),
events = oldData.events;
if ( events ) {
delete curData.handle;
curData.events = {};
for ( type in events ) {
for ( i = 0, l = events[ type ].length; i < l; i++ ) {
jQuery.event.add( dest, type, events[ type ][ i ] );
}
}
}
// make the cloned public data object a copy from the original
if ( curData.data ) {
curData.data = jQuery.extend( {}, curData.data );
}
}
The most interesting part is this:
oldData = jQuery._data( src ),
curData = jQuery._data( dest, oldData ),
events = oldData.events;
The events are saved inside (jQuery._data( src )).events. To stay by my example, the solution will look like this:
(jQuery._data( jQuery("#test_element")[0] )).events.click[0].handler
This way I can make a copy of the function bound to the element. And of course, if there are more bindings to one element, they can be reached with "...click[1].handler", "...click[2].handler", etc.
I hope this little trick helped you too.