Как работи веригата на събития за множество обекти?

Извършвам действие по изтриване на страница, когато потребителят щракне върху бутона за потвърждение на бутон за модален прозорец на twitter bootstrap.

Имам два бутона: един позволява на потребителя да отмени действието, а друг да потвърди.

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

Ако потребителят щракне върху няколко елемента, но неговият/нейният избор е бутона за отмяна, когато той/тя щракне върху елемента, който иска да изтрие, изтриването се извършва и върху елементите, за които изборът е бил да отмените.

Не трябва ли „скритото“ събитие да бъде отделено от елемента, след като бъде изпълнено?

Знам, че мога да отделя веригата на събития, променяйки $('#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 Bin: 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