事件委託與繫結問題
阿新 • • 發佈:2020-09-15
問題描述:前端動態生成的按鈕元素,通過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 () {} }); });