JavaScript 函数中的事件触发了多次

JavaScript event in function triggered multiple times

我很难理解 JavaScript 函数和事件处理程序的某些方面。

在我正在处理的应用程序中,用户拥有一系列书籍。每次他连接时,都会显示他的书籍列表,如果他愿意,他有一个按钮可以删除一本书。首先,我编写了以下函数:

    function deleteBook(book_to_delete) {
        console.log('Called');
        // Other actions to perform to delete the book
    }

    $(document).on('click', '#user-books-list button.delete', function () {
        var self = $(this);
        var book_to_delete = self.attr('id').replace('delete-', '');
        console.log('Book to delete: ' + book_to_delete);

        // If the user wants to delete a book :
        // Then display a warning on a modal
        $('#confirm-book-deletion').removeClass('hidden');

        // If the user clicks 'no' then hide the warning and do nothing else
        $('#book-deletion-no').on('click', function () {
            // Hiding the modal
            $('#confirm-book-deletion').addClass('hidden');
        });

        // It the user clicks yes, then delete the book
        $('#book-deletion-yes').on('click', function () {

            // Display the book's id and call deletebook()
            console.log('Trigger for ' + book_to_delete);
            deleteBook(book_to_delete);

            // Hiding the modal
            $('#confirm-book-deletion').addClass('hidden');
        });

        // Make sure we exit this function
        return;

    });

问题是我的触发器 $('#book-deletion-yes') 被多次触发。 如果我执行以下操作:

然后,它不仅删除了第 3 本书,还删除了第 1、2 和 3 本书。 《书3》步骤returns如下:

Book to delete: 3
Trigger for 1
Called
Trigger for 2
Called
Trigger for 3
Called

我将代码更改为以下内容,将 $('#book-deletion-no') 和 $('#book-deletion-yes') 移出 main 函数,现在可以运行了:

    function deleteBook(book_to_delete) {
        // Make sure there is indeed a book to delete
        if (book_to_delete !== undefined) {
            console.log('Called');
            // Other actions to perform to delete the book
        } else {
            console.error('Book id undefined');
        }
    }

    var book_to_delete = undefined;
    $(document).on('click', '#user-books-list button.delete', function () {
        var self = $(this);
        book_to_delete = self.attr('id').replace('delete-', '');

        // Then display a warning
        $('#confirm-book-deletion').removeClass('hidden');
    });

    // If the user clicks 'no' then hide the warning and do nothing else
    $('#book-deletion-no').on('click', function () {
        $('#confirm-book-deletion').addClass('hidden');
        // Reset book_to_delete value
        book_to_delete = undefined;
    });

    // It the user clicks yes, then delete the book
    $('#book-deletion-yes').on('click', function () {
        $('#confirm-book-deletion').addClass('hidden');
        // Delete the book
        console.log('Trigger for ' + book_to_delete);
        deleteBook(book_to_delete);
    });

谁能帮我理解为什么我的第一次尝试没有成功,以及两者之间的主要区别?我真的不明白为什么第一个代码对所有以前的 book_to_delete 值进行这种奇怪的“循环”,因为这甚至不是一个数组。

谢谢

我在这里转发@Teemu 的回答以结束这个话题。

In the first snippet you're adding new click listeners every time the document is clicked. jQuery on is based on the native addEventListener, which is capable to attach multiple listeners of the same type to the elements, the newly-attached event doesn't override the existing events.

我的问题是我不明白 jQuery on 是如何工作的,并且在每次点击时为每本书附加一个事件,即使我选择“取消”删除也是如此。一旦我最终选择删除一本书,它触发了所有事件......因此删除了我至少点击过一次的所有书籍。

jQuery on 参考: https://api.jquery.com/on/

The .on() method attaches event handlers to the currently selected set of elements in the jQuery object.

此方法不断将事件附加到被单击的元素。它不会替换每次点击的事件。要分离事件,请使用 off 方法。