2010-02-25 3 views
15

j'ai DOM est comme ceci:événements Copie d'un élément à l'autre en utilisant jquery

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

Et ce javascript:

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

maintenant un peu de temps à l'avenir je veux copier tous les événements liés à link1 à link2. Je le fais comme écrit ci-dessous s'il vous plaît suggérer une meilleure façon si possible ou disponible.

var _elmEvents = $(#link1).data('events'); 

if (_elmEvents) { 
    $.each(_elmEvents, function (event, handlers) { 
     $.each(handlers, function (j, handler) { 
      $('#link2').bind(event, handler); 
     }); 
    }); 
} 
+0

Pour tous les commentaires posées ci-dessous, il est important que vous notez jQuery a maintenant changé et afin d'obtenir les événements sur un élément que vous devez utiliser $ ._data ($ ("# foo") [0], "événements"). (Fonctionne à partir de jQuery v2.1.4) Sinon, vous recevrez undefined de l'une des méthodes ci-dessous. Pour référence Voir: http://stackoverflow.com/questions/2008592/can-i-find-events-bound-on-an-element-with-jquery – Zanderi

Répondre

13

Si vous souhaitez copier tous les événements d'un objet à un autre sans cloner, vous pouvez le faire en accédant directement aux données d'événements.

Par exemple, si vous avez:

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

Vous pouvez accéder à ces associés d'événement dans les données 'événements de de l'élément

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

Ce sera un objet dont les clés représentent l'événement type, contenant chacun un tableau d'associations d'événements. Peu importe, voici un exemple simple, ne pas tenir compte des espaces de noms.

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

Cette solution n'a pas fonctionné pour moi, et ne prend pas en compte les espaces de noms d'événements. J'ai ajouté une nouvelle réponse qui les gère (et fonctionne dans mon cas). –

1

Découvrez this resource.

+0

Hmm, bon à savoir. Sorta souhaite que j'aurais vu ce commentaire avant que j'ai essentiellement écrit ce plugin dans le mien.:) – BBonifield

+0

Notez que 'clone' prend un argument qui copie les événements, rendant cette solution de 2007 quelque peu superflue. –

1

Vous pouvez clone un élément et manipuler le nouvel élément comme vous le souhaitez, mais jQuery ne fournit pas un moyen facile de copier des gestionnaires d'événements d'un élément à un autre. Cependant, le code qui le ferait serait:

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

Mais puisqu'il repose un peu sur jQuery internes, je voudrais essayer de faire une solution à l'aide clone.

3

réponse acceptée n'a pas fonctionné pour moi comme je l'utilise namespaces et autres événements (tels que « coller ») qui ne sont pas une méthode dans jQuery.

Cela a fonctionné pour moi:

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

Ceci est basé sur Brandons travail, mais mis à jour pour fonctionner avec toutes les versions de jQuery. Testé sur 1.6.4 jusqu'à 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

Celui-ci a très bien fonctionné dans mon script.

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

Je l'ai trouvé ici (source): http://snipplr.com/view/64750/

Questions connexes