Копировать события из одного элемента в другой, используя jquery - PullRequest
20 голосов
/ 25 февраля 2010

У меня DOM выглядит так:

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

А это javascript:

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

Теперь когда-нибудь в будущем я захочу скопировать все события, связанные на ссылке1, на ссылку2 Я делаю это, как написано ниже, пожалуйста, предложите лучший способ, если это возможно или доступно.

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

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

Ответы [ 6 ]

14 голосов
/ 26 февраля 2010

Если вы хотите скопировать все события из одного объекта в другой без клонирования, вы можете сделать это, обратившись непосредственно к данным событий.

Например, если вы сделали:

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

Вы можете получить доступ к этим ассоциированным событиям в данных 'events' элемента

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

Это будет объект, ключи которого представляют тип события, каждый из которых содержит массив ассоциаций событий. Несмотря на это, вот простой пример, не учитывающий пространства имен.

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 );
        }
    }
}
4 голосов
/ 28 апреля 2016

Это очень хорошо сработало в моем сценарии.

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

Я нашел это здесь (источник): http://snipplr.com/view/64750/

4 голосов
/ 05 июня 2013

Принятый ответ не работал для меня, так как я использую пространства имен и другие события (например, "вставка"), которые не являются методом в jQuery.

Это сработало для меня:

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);
        });
    });
}
1 голос
/ 25 февраля 2010

Вы можете клонировать элемент и манипулировать новым элементом по своему усмотрению, однако jQuery не предоставляет простого способа скопировать обработчики событий из одного элемента в другой. Тем не менее, код, который будет делать это будет:

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

Но так как он в некоторой степени зависит от внутренних компонентов jQuery, я бы попытался найти решение с использованием клона.

0 голосов
/ 01 июня 2018

Отредактированный ответ @Rikco в соответствии с более новым 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);
            });
       });
    });
}
0 голосов
/ 18 июня 2013

Это основано на работе Brandons , но обновлено для работы со всеми версиями jQuery. Проверено на 1.6.4 до 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);
    });
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...