1. 程式人生 > 實用技巧 >事件委託與繫結問題

事件委託與繫結問題

問題描述:前端動態生成的按鈕元素,通過js方式委託事件,在通過ajax向後端請求資料,會造成程式的重複執行。

好像是比較簡單,但是沒經歷過的,可能還是不知所云。那就從事件繫結開始說起:

這裡說到的兩種事件繫結分別是這樣嬸兒的:

js方式的事件委託:

document.querySelector(".popUp_ok").addEventListener('click', function(e) {
   console.log("原生事件委託"); 
})

jquery方式繫結:

$(".popUp_ok").on('click', function(e) {
    console.log(
"jquery事件繫結"); })

然後上一段碰到問題的程式碼:

document.querySelector(".popUp_ok").addEventListener("click", function(e) {  
       ...
            $.ajax({
                type: "POST",
                url: ...,
                data: {...},               
                dataType: 'json',            
                cache: false,
                success: function (data, textStatus) {
                    if (!data.error) {
                        ...       
                    }
                },
                error: function () {}
})

這裡的過程是:點選按鈕之後,觸發委託的事件,ajax獲取資料成功後,就會區域性重新整理頁面的內容。

當第一次操作時,沒什麼問題,但是當第二次重新整理的時候,同樣會將之前的過程執行一趟,而且會將之前已經區域性重新整理的資料,再一次修改成另外一個數據,第三次,同樣會把之前兩次修改過的資料,再修改成其他的資料,...以此類推。很明顯有問題!

最後,經過一番折騰,發現:這樣的操作,會給每一個同樣className的元素,建立一個委託事件佇列(如下圖);

所以就想到了每一次操作完成之後,給元素解綁。但是,在js原生方法中,remove委託事件,不起作用,最後就換成了jquery中的辦法:前面不用委託事件,直接給元素繫結事件,頁面區域性重新整理之後,解綁,搞定!(非前端人員,不求甚解,歡迎指點)

正確做法:

$(".popUp_ok").on('click', function(e) {
            ...

            $.ajax({
                type: "POST",
                url: ...,
                data: {...},               
                dataType: 'json',            
                cache: false,
                success: function (data, textStatus) {
                    if (!data.error) {
                        ...
                        //以上步驟執行完成之後,將事件解綁
                        $(".popUp_ok").off('click');         
                    }
                },
                error: function () {}
            });
        });