JQuery: Любой способ "обновить" обработчики событий?

У меня есть два divs, один из которых содержит некоторые вещи, а другой - все возможное. Щелчок по одному из divs перенесет элементы в другой div. Код, который я придумал, это:

$("#holder > *").each(function() {
    $(this).click(function(e) {
        $(this).remove();
        $("#bucket").append(this);
    });
});

$("#bucket > *").each(function() {
    $(this).click(function(e) {
        $(this).remove();
        $("#holder").append(this);
        });
});

Это работает отлично, за исключением того, что обработчики событий нужно обновлять после добавления или удаления элементов. Я имею в виду, что если я сначала нажму на элемент, он будет добавлен в другой div, но если я снова нажму на этот элемент, ничего не произойдет. Я могу сделать это вручную, но есть ли лучший способ достичь этого?

Ответы

Ответ 1

Попробуйте jquery live events.. $.live(eventname, function) будет привязываться к любым текущим элементам, которые соответствуют, а также к элементам добавлен в Dom в будущем с помощью обработки javascript.

Пример:

$("#holder > *").live("click", function(e) { 
        $(this).remove(); 
        $("#bucket").append(this); 
}); 

$("#bucket > *").live("click", function(e) { 
        $(this).remove(); 
        $("#holder").append(this); 
});

Важно:

Обратите внимание, что с тех пор, как $.live был удален из jQuery (далее 1.9) и вместо этого вы должны использовать $.on.

Я предлагаю вам обратиться к этому ответу для обновленного примера.

Ответ 2

Здесь вы, используя более интуитивный делегат API:

var holder = $('#holder'),
    bucket = $('#bucket');

holder.delegate('*', 'click', function(e) {
    $(this).remove();
    bucket.append(this);
});

bucket.delegate('*', 'click', function(e) {
    $(this).remove();
    holder.append(this);
});

Ответ 3

РЕДАКТИРОВАТЬ: не использовать live, он устарел!

Воспользуйтесь тем, что события пузырятся. Используя .on():

var  = function( el1, el2 ) {

var things = $('#holder, #bucket');
things.each(function( index ) {
  // for every click on or in this element
  things.eq(index).on('click', '> *', function() {
    // append will remove the element
    // Number( !0 ) => 1, Number( !1 ) => 0
    things.eq( Number(!index) ).append( this );
  });
});

любой щелчок по любому элементу (существующий во время привязки или нет) будет пузыриться (если вы не вручную захватили событие и прекратили распространение). Таким образом, вы можете использовать этот event delegation для связывания только двух событий, по одному на каждом контейнере. Каждый щелчок, который прошел селекторный тест 2-го аргумента (в этом случае > *, удалит этот элемент, а затем добавит его в альтернативный контейнер, как это было добавлено things.eq( Number(!index) )

Ответ 4

Вы посмотрели на функцию jQuery live?

Ответ 5

Во-первых, live устарел. Во-вторых, освежение - это не то, что вы хотите. Вам просто нужно привязать обработчик кликов к правильному источнику, в этом случае: документ.

Когда вы делаете

$(document).on('click', <id or class of element>, <function>);

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