Как работает цепочка событий для нескольких объектов?

Я выполняю действие удаления на странице, когда пользователь нажимает кнопку подтверждения на кнопке модального окна начальной загрузки Twitter.

У меня есть две кнопки: одна позволяет пользователю отменить действие, а другая — подтвердить.

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

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

Не должно ли «скрытое» событие отсоединяться от элемента после его выполнения?

Я знаю, что могу отсоединить цепочку событий, изменив $('#confirmDeleteModal').on('hidden', function() { на $('#confirmDeleteModal').off('hidden').on('hidden', function() {, но мне действительно понятно, почему это происходит. Я что-то упустил?

Код:

$(document).ready(function(){
    $('.delete').on('click', function() {
        var itemID = $(this).data('product-id')

        $('#confirmDeleteModal').modal('show');

        $('#confirmDelete').on('click', function() {

            $('#confirmDeleteModal').on('hidden', function() {
                // Here I do my stuff to perform deletion
                $('#result').append('This method has been called for ' + itemID + ' <br />' )
            });
        });
    });
});

Надеюсь, я ясно изложил свой вопрос. Я также подготовил JS-бин: http://jsbin.com/inulaw/5/edit.


person Mimo    schedule 30.04.2013    source источник
comment
Не уверен, о чем вы спрашиваете, но да, вы должны отсоединять события или, по крайней мере, не вкладывать такие вложения событий.   -  person bfavaretto    schedule 30.04.2013
comment
Я хотел бы знать, почему это происходит: когда «скрытое» событие завершено, почему оно снова запускается? Поскольку вы говорите, что я не должен вкладывать такие события, есть ли лучший способ сделать это?   -  person Mimo    schedule 30.04.2013


Ответы (1)


Проблема здесь в том, что вы каждый раз подключаете дополнительных слушателей к событиям click и hidden. Чтобы исправить это, свяжите метод jQuery .off('eventName') перед повторным вызовом .on('eventname').

Вот ваш код, обновленный и отлично работающий в JS Bin:

$(document).ready(function(){
    $('.delete').on('click', function() {
        var itemID = $(this).data('product-id')

        $('#confirmDeleteModal').modal('show');

        $('#confirmDeleteModal').off('hidden'); // must reset from previous
        $('#confirmDelete').off('click').on('click', function() {

            $('#confirmDeleteModal').on('hidden', function() {

                    // Here I do my stuff to perform deletion
                    $('#result').append('This method has been called for ' + itemID + ' <br />' )
            });
        });
    });
});

РЕДАКТИРОВАТЬ: я переместил $('#confirmDeleteModal').off('hidden'); над событием клика, чтобы он сбрасывался независимо от того, было ли нажато подтверждение.

person Mike Marcacci    schedule 30.04.2013
comment
Я попробовал это, и похоже, что это не работает. Я все еще получаю такое же поведение. Я думаю, это потому, что с тех пор, как вы отсоединили событие hidden, само событие еще не было поставлено в очередь. - person Mimo; 30.04.2013
comment
Хм... посмотрите этот jsFiddle, который я сделал. Это не работает так, как вы намеревались? - person Mike Marcacci; 30.04.2013
comment
Ясно.. Я пропустил отключение («щелчок») на самой кнопке. Это тоже странно... поскольку я нажимаю эту кнопку только один раз, как к ней могут быть привязаны другие события? - person Mimo; 30.04.2013
comment
Когда диалоговое окно закрывается, оно фактически не удаляет диалоговое окно или кнопку; просто скрывает их. Поэтому, когда вы прикрепляете другой дескриптор события, вы прикрепляете его к той же кнопке. Рад, что это сработало! - person Mike Marcacci; 30.04.2013