2010-02-25 10 views
15

ich DOM haben, ist wie folgt:Kopieren Ereignisse von einem Element zum anderen jquery mit

<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> 

Und das javascript:

$(function(){ 
    $('#link1').bind('click',function(){alert('do something to make me happy');}) 
}); 

Nun einige Zeit in der Zukunft ich alle Ereignisse kopieren möchten gebunden an link1 zu link2. Ich mache es wie unten beschrieben, 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); 
     }); 
    }); 
} 
+0

Für jede der folgenden Erläuterungen es gefragt ist wichtig, dass Sie beachten jQuery hat sich nun geändert und um die Ereignisse auf einem Element zu bekommen Sie $ verwenden müssen ._data ($ ("# foo") [0], "Ereignisse"). (Funktioniert ab jQuery v2.1.4) Andernfalls erhalten Sie undefined von keiner der folgenden Methoden. Für Referenz Siehe: http://stackoverflow.com/questions/2008592/can-i-find-events-bound-on-an-element-with-jquery – Zanderi

Antwort

13

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.

Zum Beispiel, wenn Sie getan haben:

$("#the_link").click(function(e){ 
    // do some stuff 
    return false; 
}.mouseover(function(e){ 
    // do some other stuff 
}); 

Sie diese Veranstaltung Mitarbeiter in den Daten des Elements ‚Ereignisse‘ zugreifen können

var events = $("#the_link").data('events'); 

Es wird ein Objekt, dessen Schlüssel repräsentieren die Veranstaltung Typ, der jeweils ein Array von Ereigniszuordnungen enthält. Trotzdem, hier ist ein einfaches Beispiel, das keine Namespaces berücksichtigt.

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); 
     } 
    } 
} 
+0

Diese Lösung funktionierte nicht für mich und berücksichtigt keine Ereignisnamespaces. Ich habe eine neue Antwort hinzugefügt, die sie behandelt (und in meinem Fall funktioniert). –

1

Auschecken this resource.

+0

Hmm, gut zu wissen. Sorta wünschte, ich hätte diesen Kommentar gesehen, bevor ich im Wesentlichen dieses Plugin in meinem geschrieben habe.:) – BBonifield

+0

Beachten Sie, dass 'clone' ein Argument verwendet, das Ereignisse kopiert, wodurch diese Lösung von 2007 etwas überflüssig wird. –

1

Sie können clone ein Element und bearbeiten Sie das neue Element, wie Sie wollen, aber jQuery bietet keine einfache Möglichkeit, Ereignishandler von einem Element zu einem anderen zu kopieren. der Code jedoch, dass es tun würde, wäre:

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); 
    } 
} 

Aber da es etwas auf jQuery Interna angewiesen ist, würde ich versuchen, eine Lösung unter Verwendung von Klon zu machen.

3

akzeptierte Antwort nicht für mich arbeiten, wie ich verwende Namespaces und andere Ereignisse (wie „Paste“), die keine Methode in jQuery ist.

Dieser arbeitete für mich:

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); 
     }); 
    }); 
} 
0

Diese auf Brandons Arbeit basiert, aber aktualisiert mit allen jQuery-Versionen zu arbeiten. Getestet auf 1.6.4 bis 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); 
    }); 
}; 
1

Dieser arbeitete sehr gut in meinem Skript.

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

ich es hier (Quelle): http://snipplr.com/view/64750/

Verwandte Themen