jquery事件綁定的幾種用法
常見的事件綁定的幾種方法
主要有on(),bind(),live(),delegate(),隨著版本的不斷更新,live(),bind(),delegate()被相繼棄用。
live():1.7版本之後被棄用
bind()、delegate():3.0版本之後被棄用
雖然在3.0之後的版本中有bind和delegate在,但在具體的實現上還是調用的on()
bind: function( types, data, fn ) { return this.on( types, null, data, fn ); }, delegate: function( selector, types, data, fn ) {return this.on( types, selector, data, fn ); },
本文主整理1.7之後的事件綁定有on(),one()
one():只執行一次並自動除
on():為當前選定的元素集附加事件處理方法,與之對應的解綁方法off();
$(function () { $("p").on("click", function () { alert($(this).text()) }); $("button").click(function () { $("p").off("click"); }); }); });
$(document).ready(function () { $("p").one("click", function () { $(this).animate({ fontSize: "+=6px" }); }); $("p").on("click", function () { $(this).animate({ fontSize: "+=6px" }); }); });
on()的使用(1.7和之後的版本)
on():為當前選定的元素集附加事件處理方法,與之對應的解綁方法off();
查看on的源碼可以發現,on的方法中是調用EventListener來綁定的
語法: .on( events [, selector ] [, data ], handler )
參數 | 描述 |
---|---|
events | 必需。類型是字符串,由空格分隔多個事件值。 |
selector | 可選。只能添加到指定的子元素上的事件處理程序(且不是選擇器本身)。 |
data | 可選。規定傳遞到函數的參數。 |
handler | 規定當事件發生時運行的函數。允許為false,false被作為是一個函數return false的一個簡寫 |
demo:
function myHandler( event ) { alert( event.data.foo ); } $( "p" ).on( "click", { foo: "bar" }, myHandler );
語法: .on( events [, selector ] [, data ] )
參數 | 描述 |
---|---|
events | 必需。類型是object,由空格分隔多個事件值。事件值是被事件調用的處理函數 |
selector | 可選。只能添加到指定的子元素上的事件處理程序(且不是選擇器本身)。 |
data | 可選。規定傳遞到函數的參數。 |
handler | 可選。規定當事件發生時運行的函數。允許為false,false被作為是一個函數return false的一個簡寫 |
demo:
$( "div.test" ).on({ click: function() { $( this ).toggleClass( "active" ); }, mouseenter: function() { $( this ).addClass( "inside" ); }, mouseleave: function() { $( this ).removeClass( "inside" ); }
直接和委托事件
- 當on函數省略了selector參數或者selector為null時,那麽事件被稱為直接事件或直接綁定事件。每次選中的元素觸發事件時,就會執行處理程序,不管它直接綁定在元素上,還是從後代(內部)元素冒泡到該元素的。
- 當提供了selector參數時,事件被稱為委托事件。事件不會在直接綁定的元素上觸發,但當selector參數選擇器匹配到後代(內部元素)的時候,事件處理函數才會被觸發。
1、一些區別:
- 直接事件處理只能綁定在當前被選中的元素上,而且,在您的代碼調用.on()的時候,他們必須在頁面文檔中已經存在。
- 委托事件除了可以給未創建的後代元素綁定事件外(即上面提到的優勢),委托事件的另一個好處就是,當需要監視很多元素的時候,代理事件的開銷更小
例子
下面的例子table有1,000行,給行上添加點擊事件
<script type="text/javascript"> $(function () { var tabledom = ""; for (var i = 0; i < 10; i++) { tabledom += "<tr ><td>測試" + i + "</td></tr>"; } $("#dataTable tbody").html(tabledom); $("#btnAddtr").click(function () { var html = ‘‘ for (var i = 0; i < 10; i++) { html += "<tr ><td>後添加行" + i + "</td></tr>"; } $("#dataTable tbody").append(html) }); //第一種事件綁定方式 $("#dataTable tbody tr").click(function () { console.log("第一種方式點擊:" + $(this).text()); }); // 第二種事件綁定方式 $("#dataTable tbody").on("click", "tr", function () { console.log("第二種方式點擊:" + $(this).text()); }); }) </script>
<table id="dataTable"> <tbody></tbody> </table> <button id="btnAddtr">添加table行</button>
代碼解釋
- 事件會綁定到選中元素的所有子元素,如果一個div有1,000行,那麽以下代碼會將處理函數綁定到1,000個元素
$( "#dataTable tbody tr" ).on( "click", function() {
console.log( $( this ).text() );
});
2.委派事件的方法只有一個元素的事件處理程序,tbody,並且事件只會向上冒泡一層(從被點擊的tr 到 tbody ):
$("#dataTable tbody").on("click", "tr", function(event){ console.log( $( this ).text() ); });
從圖片中可以出例1綁定了1000次,例2只綁定了一次,內存開銷例1也比例2的開銷會比較大,因此在使用時,盡量使用代理事件。
3.後添加的行,使用第一種方式事件綁定無效,但是第二種方式點擊事件有效
2、冒泡特性
默認情況下,大多數事件的冒泡從最初的event target(目標元素)開始的,直到document元素。每個元素都沿著DOM層級這條路,jQuery會調用任何匹配的已被綁定的事件處理程序。如果想要防止事件向上冒泡文檔樹(從而防止這些元素的處理程序運行)可以調用的event.stopPropagation()。但調用event.stopPropagation(),任何綁定到當前元素上的其他同類會繼續運行,為了防止這種情況,可以調用event.stopImmediatePropagation()。
調用event.stopPropagation()能阻止事件的冒泡,但默認事件事件還會觸發,需要調用event.preventDefault()。event.stopPropagation()和event.preventDefault()會從一個事件處理程序會自動返回false。也可以直接將 false 當作 handler 的參數,作為 function(){ return false; } 的簡寫形式。直接使用return false的時候冒泡和默認事件都會阻止。
總結:
- event.stopPropagation(); 只阻止了冒泡事件, 默認行為沒有阻止
- event.stopImmediatePropagation() 阻止了冒泡事件, 默認行為沒有阻止,另外還阻止了同類事件
- event.preventDefault(); 只阻止了默認事件:a的跳轉,冒泡事件沒有阻止
- return false; 冒泡事件和默認事件都阻止
以下是例子,可以查看效果
<script> $(function () { $("a").click(function (event) { $("div").append("<p>父元素被點擊</p>"); }) $("button").click(function (event) { $("#txtResult").append("<p>子按鈕被點擊</p>"); // event.stopPropagation(); //只阻止了冒泡事件, 默認行為沒有阻止 // event.stopImmediatePropagation() //阻止了冒泡事件, 默認行為沒有阻止,另外還阻止了同類事件 // event.preventDefault(); //只阻止了默認事件:a的跳轉,冒泡事件沒有阻止 //return false; //冒泡事件和默認事件都阻止 }) $("button").click(function (event) { $("#txtResult").append("<p>其他事件被觸發</p>"); }) }) </script>
<a href="http://www.baidu.com" target="_blank">超鏈接 </br> <button>子按鈕</button> </a> <div id="txtResult"> </div>
3、其他
- 多個事件綁定同一個函數
function Print(type) { $("#txtResult").append("<p>" + type + "</p>") } ///-------------多個事件綁定同一個函數-----------------/// $(function () { $("p").on("mouseover mouseout", function (event) { Print(event.originalEvent.type) }); });
- 多個事件綁定不同函數
///--------------多個事件綁定不同函數----------------/// $(function () { $("p").on({ mouseover: function (event) { Print(event.originalEvent.type) }, mouseout: function (event) { Print(event.originalEvent.type) }, click: function (event) { Print(event.originalEvent.type) } }); });
- 綁定自定義事件
///--------------綁定自定義事件----------------/// $(function () { $("p").on("myOwnEvent", function (event, showName) { $("#txtResult").append(showName + "! What a beautiful name!"); }); $("button").click(function () { $("p").trigger("myOwnEvent", ["Hello"]); }); });
- 傳遞數據到函數
///--------------傳遞數據到函數----------------/// $(function () { $("p").on("click", { msg: "clicked!" }, handlerName); }); function handlerName(event) { alert(event.data.msg); }
jquery事件綁定的幾種用法