Kopieren Sie Ereignisse mit jquery von einem Element zum anderen
Lesezeit: 5 Minuten
Praveen Prasad
Ich habe DOM ist wie folgt:
<a href="https://stackoverflow.com/questions/2337521/javascript:void(0)" id='link1'>Element with events bound initially</a>
<a href="https://stackoverflow.com/questions/2337521/javascript:void(0)" id='link2'>Element to which events are bound in future</a>
Und dieses Javascript:
$(function(){
$('#link1').bind('click',function(){alert('do something to make me happy');})
});
Jetzt möchte ich irgendwann in der Zukunft alle an Link1 gebundenen Ereignisse nach Link2 kopieren. Ich mache es wie unten geschrieben, bitte schlagen Sie einen besseren Weg vor, wenn möglich oder verfügbar.
var _elmEvents = $(#link1).data('events');
if (_elmEvents) {
$.each(_elmEvents, function (event, handlers) {
$.each(handlers, function (j, handler) {
$('#link2').bind(event, handler);
});
});
}
Für alle unten abgefragten Kommentare ist es wichtig, dass Sie beachten, dass sich jQuery jetzt geändert hat, und um die Ereignisse für ein Element abzurufen, müssen Sie $._data( $(“#foo”) verwenden.[0], “Veranstaltungen” ). (Funktioniert ab jQuery v2.1.4) Andernfalls erhalten Sie undefined von einer der folgenden Methoden. Als Referenz siehe: stackoverflow.com/questions/2008592/…
– Zanderi
22. Juni 2015 um 21:34 Uhr
BBonifield
Wenn Sie alle Ereignisse ohne Klonen von einem Objekt auf ein anderes kopieren möchten, können Sie dies tun, indem Sie direkt auf die Ereignisdaten zugreifen.
Wenn Sie zum Beispiel Folgendes getan haben:
$("#the_link").click(function(e){
// do some stuff
return false;
}).mouseover(function(e){
// do some other stuff
});
Sie können auf diese Ereignisverknüpfungen in den „Ereignissen“-Daten des Elements zugreifen
var events = $("#the_link").data('events');
Es wird ein Objekt sein, dessen Schlüssel den Ereignistyp darstellen, wobei jeder ein Array von Ereigniszuordnungen enthält. Unabhängig davon ist hier ein einfaches Beispiel, bei dem Namespaces nicht berücksichtigt werden.
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 );
}
}
}
Diese Lösung hat bei mir nicht funktioniert und berücksichtigt keine Ereignis-Namespaces. Ich habe eine neue Antwort hinzugefügt, die sie behandelt (und in meinem Fall funktioniert).
– Deutscher Latorre
5. Juni 2013 um 15:51 Uhr
Warum wird dies für mich “undefiniert” zurückgegeben: alert($("#a").data('events')); ?! sehen: jsfiddle.net/NabiKAZ/mbkL6gp3/1
– Nabi KAZ
30. April 2020 um 1:42 Uhr
Dieser funktionierte sehr gut in meinem Skript.
$.each($('#original').data('events'), function() {
// iterate registered handler of original
$.each(this, function() {
$('#target').bind(this.type, this.handler);
});
});
Es funktioniert gut, aber vielleicht ist das Ersetzen des ersten Parameters notwendig: siehe Kommentar von Zanderi unter der Frage. (Danke an beide.)
– mirek
12. August 2019 um 14:26 Uhr
Warum wird dies für mich “undefiniert” zurückgegeben: alert($("#a").data('events')); ?! sehen: jsfiddle.net/NabiKAZ/mbkL6gp3/1
– Nabi KAZ
30. April 2020 um 1:44 Uhr
Deutsch Latorre
Die akzeptierte Antwort hat bei mir nicht funktioniert, da ich sie verwende Namensräume und Andere Ereignisse (z. B. “Einfügen”), die keine Methode in jQuery sind.
Das hat bei mir funktioniert:
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);
});
});
}
Noah
Du kannst Klon ein Element und bearbeiten Sie das neue Element nach Belieben, jedoch bietet jQuery keine einfache Möglichkeit, Ereignishandler von einem Element in ein anderes zu kopieren. Der Code, der dies tun würde, wäre jedoch:
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 );
}
}
Da es jedoch etwas auf jQuery-Interna angewiesen ist, würde ich versuchen, eine Lösung mit Klonen zu finden.
yckart
Dies basiert auf Brandons funktionieren, aber aktualisiert, um mit allen jQuery-Versionen zu arbeiten. Getestet auf 1.6.4 bis zu 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 ([email protected] || http://brandonaaron.net)
* @author Yannick Albert ([email protected] || 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);
});
};
Daniel
Bearbeitete @Rikco-Antwort gemäß einer neueren 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);
});
});
});
}
Timur. Z
$.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');
Für alle unten abgefragten Kommentare ist es wichtig, dass Sie beachten, dass sich jQuery jetzt geändert hat, und um die Ereignisse für ein Element abzurufen, müssen Sie $._data( $(“#foo”) verwenden.[0], “Veranstaltungen” ). (Funktioniert ab jQuery v2.1.4) Andernfalls erhalten Sie undefined von einer der folgenden Methoden. Als Referenz siehe: stackoverflow.com/questions/2008592/…
– Zanderi
22. Juni 2015 um 21:34 Uhr