event delegationhtml
參考連接:https://learn.jquery.com/events/event-delegation,https://davidwalsh.name/event-delegatenode
當咱們須要爲一些節點綁定事件時,咱們一般會這麼作jquery
<ul id ="test"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> </ul> <script> $("#test li").on("click", function(event) {
event.proventDefalut(); console.log($(this).text()); }) </script>
因而,咱們觸發點擊事件後,就會彈出對應的text值;dom
可是,後來咱們發現須要添加新的li標籤了函數
$("test").apend("<li>5</li>")
雖然咱們在理想中認爲新添加的元素也應該在被點擊後可以輸出它的text,然而現實很骨感,點擊它並不會有什麼事情發生,由於新添加元素並無綁定到event handler;this
如今咱們須要理解一個概念,Event Propagation。spa
在咱們點擊了某個li標籤,它的click事件會被觸發,而後向上冒泡,直達dom tree的根節點(document root);本例中的示意圖大體是這樣的代理
licode
ulhtm
body
html
document root
這就意味着我每次點擊一個小小的li標籤,就至關於點擊了整個文檔。——這就是eventPropagation 或者稱爲 eventbubbling的概念;
在咱們瞭解event bubble是如何做用以後,咱們就能夠實現一個代理事件delegated event
// Attach a delegated event handler $( "#test" ).on( "click", "a", function( event ) { event.preventDefault(); console.log( $( this ).text() ); });
咱們如今在.on()函數的第二個參數添加了一個「a」,它是做爲ul標籤的子元素存在的。當咱們點擊到ul下的任意一個a標籤(不管它是在點擊事件綁定前就存在的仍是後來建立的),它會觸發event bubble,當事件冒泡到ul上時(即觸發ul的點擊事件),會執行咱們爲ul綁定的回調函數,而後阻止點擊事件繼續冒泡(避免影響到其餘元素)。
至此,咱們能夠發現,咱們不須要再爲某個父元素下的每一個子元素都綁定諸如click事件,而是去爲該父元素綁定事件。這個就是事件代理,藉助冒泡機制將子元素的事件放在父元素上託管。
JQuery中咱們經過.on()的第二個參數來實現event delegation,如今咱們看看原生JS的實現方式,區別主要體如今如何匹配到指定的子元素上。
document.getElementById("test").addEventListener("click", function(e) { // e.target is the clicked element! // If it was a list item if(e.target && e.target.nodeName == "LI") { // List item found! Output the ID! console.log("List item",e.target," was clicked!"); } });
//實現ul下li點擊事件的代理。
一個div#test下有多個子節點,咱們須要爲a.classA的子元素綁定點擊事件,實現方式以下:
// Get the parent DIV, add click listener... document.getElementById("test").addEventListener("click",function(e) { // e.target was the clicked element if (e.target && e.target.matches("a.classA")) { console.log("Anchor element clicked!"); } });
在上方實現匹配到咱們所關心的帶有classA的class名的元素還可使用正則匹配的方式:
var re = new RegExp('\\b'+class+'\\b'); re.test(e.target.className);
re.test(e.target.className)會返回一個bool類型的變量,當匹配到咱們關心的元素,返回true,不然返回false;