標籤:style blog http io ar color 使用 sp for
jquery為動態添加元素添加事件
還有這裡:http://www.cnblogs.com/dumuqiao/archive/2011/09/09/2172511.html
Event names and namespaces(事件名稱和命名空間)
http://www.css88.com/jqapi-1.9/on/
任何事件的名稱,可以作為events 參數。jQuery將通過所有瀏覽器的標準JavaScript事件類型,當使用者操作事件,如click,瀏覽器會調用handler參數的函數。此外,.trigger()方法可以觸發標準的瀏覽器事件 和 自訂事件名綁定的處理常式。
事件名稱可以添加指定的event namespaces(命名空間) 來簡化刪除或觸發事件。例如,"click.myPlugin.simple"為 click 事件同時定義了兩個命名空間 myPlugin 和 simple。通過上述方法綁定的 click 事件處理,可以用.off("click.myPlugin") 或 .off("click.simple")刪除綁定到相應元素的Click事件處理常式,而不會干擾其他綁定在該元素上的“click(點擊)” 事件。命名空間類似CSS類,因為它們是不分層次的;只需要有一個名字相匹配即可。以底線開頭的名字空間是供 jQuery 使用的。
在.on()方法的第二種用法中,events參數是一個JavaScript對象或者索引值對。鍵等同於events參數,用空格分隔的事件名稱字串和可選命名空間。每個鍵的值是一個函數(或false 的值),相當於 handler 參數,但是該值並不是方法中的最後一個參數。在其它方面,這兩種形式在下面描述的內容中其行為都是相同的。如下所述。
.bind(), .live(), 和 .delegate()之間的區別並不明顯。但是理解它們的不同之處有助於寫出更簡潔的代碼,並防止我們的互動程式中出現沒有預料到的bug。
基礎
DOM樹
首先,圖形化的HTML文檔能協助我們更好的理解。一個簡單的HTML頁面看起來應該像這樣
事件冒泡(也稱作事件傳遞)(Event bubbling aka event propagation)
點擊一個連結,觸發綁定在連結元素上的 click 事件,進而觸發綁定到這個元素的click事件的函數。
?
| 1 |
$(‘a‘).bind(‘click‘, function() { alert("That tickles!") }); |
所以一次點擊會觸發一個alert。
然後,這個 click 事件會從DOM樹向上傳遞,傳播到父元素,然後傳遞給每一個祖先元素。
在DOM樹中, document 是根節點。
現在我們能容易的解釋.bind(), .live(), 和 .delegate()之間的差別了
.bind()?
| 1 |
$(‘a‘).bind(‘click‘, function() { alert("That tickles!") }); |
這是最直接的Binder 方法。jQuery 掃描文檔找到所有 $(‘a’) 元素,然後給每一個找到的元素的 click 事件綁定處理函數。
.live()?
| 1 |
$(‘a‘).live(‘click‘, function() { alert("That tickles!") }); |
jQuery綁定處理函數到 $(document) 元素,並把 ‘click’ 和 ‘a’ 作為函數的參數。有事件冒泡到document節點的時候,檢查這個事件是不是 click 事件,target element能不能匹配 ‘a’ css選取器,如果兩個條件都是true,處理函數執行。
live方法也可以綁定到指定的元素(或者說“上下文(context)”)而不用綁定到document,比如:
?
| 1 |
$(‘a‘, $(‘#container‘)[0]).live(...); |
.delegate()?
| 1 |
$(‘#container‘).delegate(‘a‘, ‘click‘, function() { alert("That tickles!") }); |
jQuery掃描文檔找到 $(‘#container’),綁定處理函數到他的 click 事件,’a’ css選取器作為函數的參數。當有事件冒泡到 $(‘#container’),檢查事件是不是 click,並檢查target element是不是匹配css選取器,如果兩者都符合,執行函數。
注意這次和 .live() 方法很相似,除了把事件綁定到特定元素與跟元素的區別。精明的JS’er 或許會總結成 $(‘a’).live() == $(document).delegate(‘a’),真的是這樣嗎? 不,不全是。
為什麼 .delegate() 比 .live() 好
jQuery 的 delegate方法比 live 方法更應該成為首選有一個原因。考慮以下的情境:
?
| 123 |
$(‘a‘).live(‘click‘, function() { blah() });// or$(document).delegate(‘a‘, ‘click‘, function() { blah() }); |
速度
上面第二個執行比第一個快,因為第一個會遍曆整個文檔尋找 $(‘a’) 元素,並儲存為jQuery對象,但是live方法只需要傳一個字串參數’a‘而已,$() 方法並不知道我們會用鏈式運算式在後面用上.live()。
delegate 方法就只需要找到並存貯 $(document)元素就夠了。
有一種hack是在 $(document).ready()之外調用live方法,這樣就會立即執行。這時候DOM還沒有填充,也就不會尋找元素或建立jQuery對象。
靈活性和鏈式文法
這方面live方法依然令人費解。想一下,它鏈在$(‘a’)對象,但實際上是在$(document)對象起作用。因為這個原因,在鏈式運算式中使用live讓人很不安,我覺得live方法變成一個全域的jQuery方法 $.live(‘a’,…) 會更有意義。
只支援css選取器
最後,live方法有一個最大的缺點,只能用css選取器,用起來很不方便。
有關css選取器的缺點,參看 Exploring jQuery .live() and .die()。
原作者更新
為什麼使用 .live() 或 .delegate() 而不用 .bind()
最後,bind 方法看起來更清晰,更直接,是嗎?但是這裡有兩個原因我們推薦 delegate 或 live:
- 綁定事件處理函數到還不存在DOM中的元素。 bind 方法直接綁定函數到每個單獨的元素,不能綁定到還沒有添加到頁面裡的元素,如果你寫了$(‘a’).bind(…),然後用ajax給頁面增加了新的連結,新添加的連結不會綁定事件。live 或 delegate 或者其它綁定到祖先元素的事件,讓現在有的元素,或者以後增的元素都可以使用。
- 綁定處理函數到一個元素或者少數幾個元素,監聽後代元素,而不是綁定100個相同的處理函數到單獨的元素。這樣更有效能優勢。
阻止冒泡
最後注意一下事件冒泡。通常我們能用這樣的方法阻止其他處理函數:
?
| 12345 |
$(‘a‘).bind(‘click‘, function(){e.preventDefault();//ore.stopPropagation();}) |
其實關於live被刪除的事件早就在1.7.2版本以後就有通知過了 不過在官方一直提倡使用.on代替.live的過程中 .live事件一直沿用
今天更新了 看下jQuery1.9的相關資訊 發現api中完全的刪除掉了.live事件
我猜肯定有人關於.on事件 並沒有以前.live事件那麼好用 甚至有的時候綁定不上事件
其實關於這個答案是這樣的, .on事件不同於以往的.live和.bind事件使用方法:
$(‘selecter‘).live(‘click‘, function(){ // do something... });
而轉到.on事件應該這樣:
$(document).on(‘click‘, ‘selecter‘, function(){ // do something... });
而.on事件可以完全代替以往的.bind, .delegate等事件
// Bind
$( "#members li a" ).on( "click", function( e ) {} );
$( "#members li a" ).bind( "click", function( e ) {} );
// Live
$( document ).on( "click", "#members li a", function( e ) {} );
$( "#members li a" ).live( "click", function( e ) {} );
// Delegate
$( "#members" ).on( "click", "li a", function( e ) {} );
$( "#members" ).delegate( "li a", "click", function( e ) {} );
但是在這裡,用 live 或 delegate 方法綁定的事件會一直傳遞到事件真正綁定的地方才會執行。這時其他的函數已經執行過了。
以前我們定義事件,比如為元素定義單擊事件是這樣寫的:
代碼如下:
$(‘input‘).click(function () {
//處理代碼
});
或
代碼如下:
$(‘.clickme‘).bind(‘click‘, function() {
// Bound handler called.
});
但是這隻能是對已經載入好的元素定義事件,那些後來添加插入的元素則需要另行綁定。即使你使用jquery的clone函數,它並不能將事件也複製(到目前為止我還不清楚它是為什麼這樣定義,是沒法複製還是刻意這麼處理,以防止出現某些異常,這還有待去分析一下jquery的原始碼)。
現在,使用live你可以輕鬆搞定,
$(‘.clickme‘).live(‘click‘, function() { // Live handler called. });這樣,你即使在後面動態插入的元素,也會被綁定事件,$(‘body‘).append(‘<div class="clickme">Another target</div>‘);
定義和用法
live() 方法為被選元素附加一個或多個事件處理常式,並規定當這些事件發生時啟動並執行函數。
通過 live() 方法附加的事件處理常式適用於匹配選取器的當前及未來的元素(比如由指令碼建立的新元素)。
問題:使用jQuery的live()方法綁定事件,有時會出現重複綁定的情況,如,當點擊一個按鈕時,此按鈕所綁定的事件會並執行n遍。
解決:使用die()方法,在live()方法綁定前,將此元素上的前面被綁定的事件統統解除,然後再通過live()方法綁定新的事件。
Js代碼
//先通過die()方法解除,再通過live()綁定
$("#selectAll").die().live("click",function(){
//事件運行代碼
});
//先通過die()方法解除,再通過live()綁定
$("#selectAll").die().live("click",function(){
//事件運行代碼
});die()方法簡介:
Js代碼
die([type], [fn])<SPAN style="WHITE-SPACE: normal"> </SPAN>
die([type], [fn])
概述
jQuery 1.3新增。此方法與live正好完全相反。
如果不帶參數,則所有綁定的live事件都會被移除。
你可以解除用live註冊的自訂事件。
如果提供了type參數,那麼會移除對應的live事件。
如果也指定了第二個參數function,則只移出指定的事件處理函數。
給Jquery動態添加的元素添加事件2