2010-02-25 7 views
15

tengo DOM es así:eventos de copia de un elemento a otro usando 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> 

Y esto javascript:

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

Ahora algún tiempo en el futuro quiero copiar todos los eventos de la envolvente en el link1 a link2. Lo estoy haciendo como se describe a continuación, por favor sugiera una forma mejor si es posible o disponible.

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

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

Para cualquiera de las observaciones formuladas a continuación es importante que anote jQuery ahora ha cambiado y con el fin de obtener los eventos en un elemento que se debe utilizar $ ._data ($ ("# foo") [0], "eventos"). (Funciona a partir de jQuery v2.1.4) De lo contrario, recibirá indefinido de cualquiera de los métodos a continuación. Para referencia Consulte: http://stackoverflow.com/questions/2008592/can-i-find-events-bound-on-an-element-with-jquery – Zanderi

Respuesta

13

Si desea copiar todos los eventos de un objeto a otro sin clonar, puede hacerlo accediendo directamente a los datos de los eventos.

Por ejemplo, si se hizo:

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

Se puede acceder a los asociados de eventos en los datos del elemento de los 'eventos'

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

Será un objeto cuyas teclas representan el evento tipo, cada uno contiene una matriz de asociaciones de eventos. De todos modos, aquí hay un ejemplo simple, sin tener en cuenta los espacios de nombres.

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

Esta solución no funcionó para mí y no tiene en cuenta los espacios de nombres de eventos. Agregué una nueva respuesta que los maneja (y funciona en mi caso). –

1

Echa un vistazo this resource.

+0

Hmm, es bueno saberlo. Sorta deseaba haber visto este comentario antes de que esencialmente escribiera este complemento en el mío.:) – BBonifield

+0

Tenga en cuenta que 'clone' toma un argumento que copia eventos, haciendo que esta solución de 2007 sea algo superfluo. –

1

Puede clone un elemento y manipular el nuevo elemento como desee, sin embargo, jQuery no proporciona una manera fácil de copiar manejadores de eventos de un elemento a otro. Sin embargo, el código que haría sería:

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

Pero ya que se basa tanto en la parte interna de jQuery, me gustaría tratar de hacer una solución usando clon.

3

respuesta aceptada no funcionó para mí, como yo uso espacios de nombres y otros eventos (como "pasta") que no son un método en jQuery.

Esto funcionó para mí:

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

Esto se basa en Brandons trabajo, pero actualizado para trabajar con todas las versiones de jQuery-. Probado en 1.6.4 hasta 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

Este funcionó muy bien en mi script.

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

lo encontré aquí (fuente): http://snipplr.com/view/64750/

Cuestiones relacionadas