Jquery通过append新元素之后事件绑定问题的解决方案
昨天在項目中發現一個問題:在DOM加載之后為標簽綁定的事件對于新加進來的標簽并不起作用,通過查找發現事件并沒有綁定到新加入的標簽,因此今天特意總結一下這種問題的解決方案。
在jquery中,我們通常是在DOM加載完成后,再對元素綁定事件。以下面的情景為例:制作一個表格,每一欄最后有個button可以刪除這一欄。然后還有一個添加按鈕,可以給表格添加一欄。代碼如下:
HTML代碼:
<table><thead><tr><th>學號</th><th>成績</th><th>操作</th></tr></thead><tbody><tr><td>100</td><td>98</td><td><button class="del">刪除</button></td></tr><tr><td>101</td><td>88</td><td><button class="del">刪除</button></td></tr><tr><td>102</td><td>78</td><td><button class="del">刪除</button></td></tr></tbody> </table> <button class="add">添加</button>jquery代碼:
$(function(){$('.del').click(function(){$(this).parents("tr").remove();});$('.add').click(function() {$("<tr><td>103</td><td>68</td><td><button class='del'>刪除</button></td></tr>").appendTo('tbody');}); });上述代碼在DOM加載完后,通過jquery向class="del"的刪除按鈕添加了一個click事件,用于刪除該欄。通過運行測試我們可以發現,給刪除按鈕添加的點擊事件對DOM中存在的前三欄是起作用,但是如果我們再點擊添加按鈕添加一欄,則新增的這一欄中的刪除按鈕并沒有綁定點擊事件。
js的事件監聽跟css不一樣,我們知道css只要設定好了樣式,不論是原來就有的還是新添加的,都有一樣的表現。而事件監聽不是,新增加的雖然設置了相同的class,但是并沒有綁定事件,你必須給每一個元素單獨綁定事件。
這種問題的處理方法主要有三種:
第一種:重復綁定
重復綁定法:DOM加載時,先對DOM中存在的元素進行事件綁定,每次新增的元素時,再對新增元素綁定一次事件,jquery代碼如下:
$(function(){$('.del').click(deleteTr);$('.add').click(function() {$("<tr><td>103</td><td>68</td><td><button class='del'>刪除</button></td></tr>").find(".del").click(deleteTr).end().appendTo('tbody');});function deleteTr(){$(this).parents("tr").remove();}});第二種:使用onclick
這種方法就是直接在標簽上添加onclick屬性,如果不考慮結構與行為分離的準則,這個方法也是能達到效果的:具體代碼如下:
HTML代碼:
<table><thead><tr><th>學號</th><th>成績</th><th>操作</th></tr></thead><tbody><tr><td>100</td><td>98</td><td><button class="del" onclick='deleteTr(this)'>刪除</button></td></tr><tr><td>101</td><td>88</td><td><button class="del" onclick='deleteTr(this)'>刪除</button></td></tr><tr><td>102</td><td>78</td><td><button class="del" onclick='deleteTr(this)'>刪除</button></td></tr></tbody> </table> <button class="add">添加</button>jquery代碼:
$(function(){$('.add').click(function() {$("<tr><td>103</td><td>68</td><td><button class='del' onclick='deleteTr(this)'>刪除</button></td></tr>").appendTo('tbody');});});function deleteTr(btn){$(btn).parents("tr").remove();}這里有一點需要注意就是onclick='deleteTr(this)'中的deleteTr()函數不能定義在$(function(){});中,如果定義在$(function(){});中,在解析HTML時,無法調用,因此需要定義在外面。
第三種:事件委托
通過查看jquery API文檔,發現有個live()事件,對live()事件的概述如下:“jQuery 給所有匹配的元素附加一個事件處理函數,即使這個元素是以后再添加進來的也有效。”但是很不幸的是,live()在jquery 1.7之后就不推薦使用了。
因此我們需要另外找路,通過查看文檔我們發現:.live() 方法能對一個還沒有添加進DOM的元素有效,是由于使用了事件委托:綁定在祖先元素上的事件處理函數可以對在后代上觸發的事件作出回應。傳遞給 .live() 的事件處理函數不會綁定在元素上,而是把他作為一個特殊的事件處理函數,綁定在 DOM 樹的根節點上。
既然知道了原理,那么我們可以自己實現事件委托,我們不在button上直接綁定事件,而在把事件綁定在tbody上,通過判斷事件的目標event.target對象的某些屬性來判斷這個對象是不是我們要找的事件觸發的對象。
下面,我們通過className來判斷是否是我們的目標對象:
$(function(){$('tbody').click(function(event){if (event.target.className == "del") {$(event.target).parents("tr").remove();}});$('.add').click(function() {$("<tr><td>103</td><td>68</td><td><button class='del'>刪除</button></td></tr>").appendTo('tbody');});});總結
以上是生活随笔為你收集整理的Jquery通过append新元素之后事件绑定问题的解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VBA实现KMP和LCS算法
- 下一篇: Python-从PDF中提取图片、压缩P