用jQuery繫結事件到動態建立的元素上
阿新 • • 發佈:2019-01-30
jQuery最常用的一個功能就是對DOM的操作,與之相關的比如對事件的繫結和Ajax動態內容載入。當我們繫結事件到Ajax load回來的內容上或其他動態建立的元素上時會發現事件沒響應,和你預想的結果不同,就像沒這會事兒一樣。這是前端開發 非常蛋疼的問題。jQuery在1.3的版本里面引入了.live()方法,後來jQuery團隊有在這基礎上加入了.delegate()和.on()方法來解決這種尷尬的局面。大家可以根據你自己專案使用的jQuery版本不同選擇下面的不同方法解決這個問題。
舉個例子,假設我們有這樣一個頁面:
</body></html> 我們要解決的問題就是當點增加節點按鈕時動態在ol下面新增一個節點並且給這個節點繫結alert事件。<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <script> $(document).ready(function(){ $('button').click(function(){ $('ol').append('<li><a href="#">動態增加的節點</a></li>'); }); }); </script> </head> <body> <ol> <li> <a href="#">靜態節點連線</a> </li> </ol> <button>增加節點</button><pre name="code" class="html">// 簡單粗暴,直接繫結到DOM物件 $(document).on('click', 'a', function(){ alert( $(this).text() ); return false; });
jQuery > 1.7.0 - 使用 .on() 事件繫結方法
如果你專案中使用的jQuery版本高於1.7.0,那麼推薦使用 .on() 方法,這個方法能夠直接繫結和代理事件。根據我們要實現的需求,我們需要使用代理事件來解決問題,也就是說我們吧事件的繫結交給父級元素,如何使用選擇器去實現事件繫結,來看一下程式碼://正確的做法 $('ol').on('click', 'a', function(){ alert( $(this).text() ); });
我們是首先把事件繫結到父級元素/或者說是容器,再通過類選擇器找到"a"元素,然後把事件傳遞到動態建立的子元素上。我們必須要把事件繫結放到父級,不然像下面這樣的程式碼是不得行的:
//這樣的程式碼是不行的
$('a').on('click', function(){
alert( $(this).text() );
});
如果是單個事件的繫結,那推薦使用這種事件繫結方法,這樣能夠很好的提升效能。
如果你不知道父類元素,你甚至可以繫結到 document 物件,不過這樣繫結像click這樣的簡單事件還行,換成是mousemove那可能對效能就有比較大的影響
更多關於 .on() 方法的介紹,請看官方說明http://api.jquery.com/on/// 簡單粗暴,直接繫結到DOM物件 $(document).on('click', 'a', function(){ alert( $(this).text() ); });
1.7 > jQuery >1.4.2 - 使用 .delegate() 事件繫結方法
.delegate()方法是 .on() 方法的前輩,在使用方法和效能方面都和.on() 方法類似,看程式碼:
// 具體父級元素繫結
$('ol').delegate('a', 'click', function(){
alert( $(this).text() );
});
// 繫結到DOM物件
$(document).delegate('a', 'click', function(){
alert( $(this).text() );
});
更多關於 .delegate() 方法的介紹,請看官方說明http://api.jquery.com/delegate/
1.4.2 > jQuery > 1.3 - 使用 .live() 事件繫結方法
.live()這個方法應該是屬於元老級的了,在jQuery 1.3的版本里面首次出現,就是為了解決繫結事件到動態元素的問題,這個在jQuery 1.7的版本里屬於是棄用的方法,jQuery 1.9以後就直接刪除了。
需要注意的是這個方法是實現原理是把事件繫結到document物件,然後通過選擇器和目標事件比較,如果匹配就觸發事件,前提條件要好保證事件的必須是連續正常執行的,如果其中一個事件出問題了,那所有的事件都不會觸發,另外,如果從document上取消事件繫結,那麼所有通過.live()方法繫結的事件都會取消。看程式碼:
// .live()實現動態繫結
$('li').live('click', function(){
alert( $(this).text() );
});
更多關於 .live() 方法的介紹,請看官方說明http://api.jquery.com/live/
1.3 > jQuery - 使用 .bind() 事件繫結方法
如果你的專案還在使用jQuery 1.3~以前的版本,那好最升級一下,實在沒法升級,那就按照下面兩個方法來解決這個問題。
1、自己實現事件的傳遞,類似上面的.live()方法
$('ol').click(functino(event){
if( $(event.target).is('a') ){
alert( $(this).text() );
}
});
2、明確的對動態載入的內容做操作,比如加上相應的css,重新繫結事件
$(document).ready(function(){
$('button').click(function(){
$('ol').append('<li class="dynamic-item"><a href="#">動態增加的節點</a></li>');
// 然後在繫結新的事件
$('a.dynamic-item:last').click(functino(){
alert( $(this).text() );
return false;
});
});
});
注:
不要把同一事件繫結到相同元素多次
儘量避免使用直接繫結到document物件,可以預先定義一個div, 比如<div id="ajax-loaded-container"></div>, 然後使用$('#ajax-loaded-container .my-link').click(...)這樣的方法去實現
需要動態繫結的css也可以在伺服器端的css檔案裡預先定義好