1、前言javascript
最近在作項目中要用到jQuery來綁定事件,首先想到的是$(selector).事件名();這樣綁定事件的方式,這種方式對事件進行綁定其實也就是bind()方法,但當選擇器匹配的元素過多,$(selector).事件名();對每一個元素進行迭代綁定,會影響性能。除了這種方式能夠綁定事件之外,還有live()(已過時)、delegate()、on()方法綁定事件,接下來分析一下它們的區別,以及使用哪一種方式最值得推薦。因爲live()方法已過時,只分析另外三種,歡迎拍磚、吐槽~~~css
2、用法與區別html
先準備一個example,用於不一樣方法綁定事件測試與對比。java
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>on()、delegate()、bind()事件綁定測試</title> <link rel="stylesheet" type="text/css" href="bootstrap.css"> </head> <body> <div style="width:800px;margin:50px auto;"> <botton class="btn btn-success" id="btn">新增一個p元素</botton> <p>1</p> <p>2</p> </div> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript"> $(document).ready(function(){ $('#btn').click(function(){ $('div').append('<p>新增一個p元素</p>'); }); }); </script> </body> </html>
接下來對全部的p元素綁定click事件,如:jquery
bind()方法:爲被選元素添加一個或多個事件處理程序,並規定事件發生時運行的函數。bootstrap
使用方式 $(selector).bind(event,data,function)app
event 必需。規定添加到元素的一個或多個事件。由空格分隔多個事件。必須是有效的事件。 函數
data 可選。規定傳遞到函數的額外數據。 性能
function 必需。規定當事件發生時運行的函數。 測試
$('div p').bind('click', function(){ alert($(this).text()); });
這樣就爲全部的p元素綁定了click事件,當點擊後會彈出其內容。但有兩個問題,
第一個問題,這裏用了隱式迭代的方法,若是匹配到的元素特別多的時候,好比若是我在div裏放了10個p元素,就得執行綁定10次。對於大量元素來講,影響到了性能。
可是若是是id選擇器,由於id惟一,用bind()方法就很快捷了。
第二個問題,對於還沒有存在的元素,沒法綁定。點擊頁面上的按鈕,將動態新增一個p元素,點擊這個p元素,會發現沒有點擊響應。
bind()方法的另一種寫法是:
$('div p').click(function(){ alert($(this).text());
});
delegate()方法:爲指定的元素(屬於被選元素的子元素)添加一個或多個事件處理程序,並規定當這些事件發生時運行的函數,使用delegate() 方法的事件處理程序適用於當前或將來的元素(好比由腳本建立的新元素)。
childSelector 必需。規定要附加事件處理程序的一個或多個子元素。
event 必需。規定附加到元素的一個或多個事件。由空格分隔多個事件值。必須是有效的事件。
data 可選。規定傳遞到函數的額外數據。
function 必需。規定當事件發生時運行的函數。
$('div').delegate('p', 'click', function(){ alert($(this).text()); });
delegate()方式根據事件委託的機制,不是爲p元素直接綁定點擊事件,而是爲其父元素(或祖先元素)綁定點擊事件,當點擊任意p元素時,事件會一層層的冒泡,直到綁定事件的元素,在冒泡過程當中事件流捕獲的對象與選擇器匹配時,就會執行這段alert($(this).text());代碼。
因此使用delegate()方法就解決了用bind()方法的上面兩個問題,沒必要爲每一個p元素綁定事件,也能夠爲動態新增的p元素綁定事件。雖然綁定是實現了,可是調用的時候也可能出現問題。若是事件目標在DOM樹中很深的位置,這樣一層層冒泡上來查找與選擇器匹配的元素,又影響到性能了。
on() 方法:爲指定的元素,添加一個或多個事件處理程序,並規定當這些事件發生時運行的函數。使用 on() 方法的事件處理程序適用於當前或將來的元素(好比由腳本建立的新元素)。
使用方式:$(selector).on(event,childselector,data,function)
event:必需項;添加到元素的一個或多個事件,例如 click,dblclick等;
childSelector: 可選;須要添加事件處理程序的元素,通常爲selector的子元素;
data:可選;須要傳遞的參數;
function:必需;當綁定事件發生時,須要執行的函數;
$('div').on('click', 'p', function(){ alert($(this).text()); });
on()方法的效果和delegate()方法的效果相同,經過查看jQuery源碼你會發現不管bind()仍是delegate()其實都是經過on()方法實現的,只是參數不一樣。三種方法的源碼(jQuery source viewer)以下:
jQuery.fn.bind = function (types, data, fn) { return this.on(types, null, data, fn); }; jQuery.fn.delegate = function (selector, types, data, fn) { return this.on(types, selector, data, fn); }; jQuery.fn.on = function (types, selector, data, fn,one) { var origFn, type; // Types can be a map of types/handlers if (typeof types === "object") { // ( types-Object, selector, data ) if (typeof selector !== "string") { // ( types-Object, data ) data = data || selector; selector = undefined; } for (type in types) { this.on(type, selector, data, types[type], one); } return this; } if (data == null && fn == null) { // ( types, fn ) fn = selector; data = selector = undefined; } else if (fn == null) { if (typeof selector === "string") { // ( types, selector, fn ) fn = data; data = undefined; } else { // ( types, data, fn ) fn = data; data = selector; selector = undefined; } } if (fn === false) { fn = returnFalse; } else if (!fn) { return this; } if (one === 1) { origFn = fn; fn = function (event) { // Can use an empty set, since event contains the info jQuery().off(event); return origFn.apply(this, arguments); }; // Use same guid so caller can remove using origFn fn.guid = origFn.guid || (origFn.guid = jQuery.guid++); } return this.each(function () { jQuery.event.add(this, types, fn, data, selector); }); };
jQuery官方推薦使用on()綁定事件。
3、總結
當選擇器匹配到的元素比較多時,不要用bind()迭代綁定,會影響性能;用id選擇器時,可使用bind(),簡單便捷;要給動態新增的元素綁定事件時,用delegate()或on(),官方推薦使用on()。
如需轉載本文,請註明來源: http://www.cnblogs.com/changjianqiu/