I have DOM is like this:
<a href='javascript:void(0)' id='link1'>Element with events bound initially</a>
<a href='javascript:void(0)' id='link2'>Element to which events are bound in future</a>
And this javascript:
$(function(){
$('#link1').bind('click',function(){alert('do something to make me happy');})
});
Now some ti开发者_Go百科me in future i want to copy all events bound on link1 to link2. I am doing it as written below please suggest some better way if possible or available.
var _elmEvents = $(#link1).data('events');
if (_elmEvents) {
$.each(_elmEvents, function (event, handlers) {
$.each(handlers, function (j, handler) {
$('#link2').bind(event, handler);
});
});
}
If you want to copy all events from one object to another without cloning, you can do so by accessing the events data directly.
For instance, if you did:
$("#the_link").click(function(e){
// do some stuff
return false;
}).mouseover(function(e){
// do some other stuff
});
You can access those event associates in the 'events' data of the element
var events = $("#the_link").data('events');
It will be an object whose keys represent the event type, each containing an array of event associations. Regardless, here's a simple example, not accounting for namespaces.
var events = $("#the_link").data('events');
var $other_link = $("#other_link");
if ( events ) {
for ( var eventType in events ) {
for ( var idx in events[eventType] ) {
// this will essentially do $other_link.click( fn ) for each bound event
$other_link[ eventType ]( events[eventType][idx].handler );
}
}
}
This one worked very well in my script.
$.each($('#original').data('events'), function() {
// iterate registered handler of original
$.each(this, function() {
$('#target').bind(this.type, this.handler);
});
});
I found it here (source): http://snipplr.com/view/64750/
Accepted answer did not work for me as I use namespaces and other events (such as "paste") that are not a method in jQuery.
This worked for me:
function copyEvents(source, destination) {
// Get source events
var events = source.data('events');
// Iterate through all event types
$.each(events, function(eventType, eventArray) {
// Iterate through every bound handler
$.each(eventArray, function(index, event) {
// Take event namespaces into account
var eventToBind = event.namespace.length > 0
? (event.type + '.' + event.namespace)
: (event.type);
// Bind event
destination.bind(eventToBind, event.data, event.handler);
});
});
}
You can clone an element and manipulate the new element however you want, however jQuery doesn't provide an easy way to copy event handlers from one element to another. However, the code that would do it would be:
var events = jQuery.data( originalElement, "events" );
for ( var type in events ) {
for ( var handler in events[ type ] ) {
jQuery.event.add( targetElement, type, events[ type ][ handler ], events[ type ][ handler ].data );
}
}
But since it relies somewhat on jQuery internals, I would try to make a solution using clone.
This is based on Brandons work, but updated to work with all jQuery-versions. Tested on 1.6.4
upto 2.0.x
.
/**
* Logic for copying events from one jQuery object to another.
*
* @private
* @name jQuery.event.copy
* @param jQuery|String|DOM Element jQuery object to copy events from. Only uses the first matched element.
* @param jQuery|String|DOM Element jQuery object to copy events to. Copies to all matched elements.
* @type undefined
* @cat Plugins/copyEvents
* @author Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
* @author Yannick Albert (mail@yckart.com || http://yckart.com)
*/
jQuery.event.copy = function (from, to) {
from = from.jquery ? from : jQuery(from);
to = to.jquery ? to : jQuery(to);
var events = from[0].events || jQuery.data(from[0], "events") || jQuery._data(from[0], "events");
if (!from.length || !to.length || !events) return;
return to.each(function () {
for (var type in events)
for (var handler in events[type])
jQuery.event.add(this, type, events[type][handler], events[type][handler].data);
});
};
Edited @Rikco answer according to a newer jquery.
function assingEvents() {
//if you have multiple just use jQuery._data(jQuery('.copy-from-single-item')[0]
jQuery.each(jQuery._data(jQuery('.copy-from-single-item'), 'events'), function() {
// iterate registered handler of original
jQuery.each(this, function() {
var parentEvent = this;
jQuery.each(jQuery('.copy-to-multiple-item'),
function() {
jQuery(this).bind(parentEvent.type, parentEvent.handler);
});
});
});
}
$.fn.copyEvents = function( to, filter )
{
var to = to.jquery ? to : jQuery(to);
var filter = filter ? filter.split(" ") : null;
var events = this[0].events || jQuery.data(this[0], "events") || jQuery._data(this[0], "events");
return this.each(function()
{
if (!to.length || !events) {
return;
}
$.each(events, function(eventType, eventArray) {
$.each(eventArray, function(index, event) {
var eventToBind = event.namespace.length > 0
? (event.type + '.' + event.namespace)
: (event.type);
if (filter && $.inArray(eventToBind, filter) == -1) {
return true;
}
to.bind(eventToBind, event.data, event.handler);
});
});
});
}
// Add some events to a element
$('#element').click(function() { });
$('#element').dblclick(function() { });
$('#element').change(function() { });
// Default usage, copy *all* events from one element to another
$('#element').copyEvents('#another-element');
// ... or you can copy only specific event types
$('#element').copyEvents('#another-element', 'change click');
original is here https://blog.armin-pfaeffle.de/2014/08/jquery-copy-events-from-one-element-to-another
精彩评论