上次咱們說了一些,關於 JavaScript中事件委託的 基礎知識,此次咱們繼續來看。javascript
先來一段代碼css
<!doctype html> <html lang="en"> </head> <body> <ul id=ul> <li id='li1'>1</li> <li id='li2'>2</li> </ul> <script> ul.onclick = function (e){ if(e.target.nodeName == 'LI'){ console.log('li 被點擊了'); } } </script> </body> </html>
上面這段代碼,用了事件委託,把事件綁在了ul上,沒有給每一個 li 都去綁定事件,看上去也是實現效果了,可是若是 li 裏面還有子元素,那麼這麼去綁定事件就不行了,當點擊 li 裏面的子元素時,就出現問題了。
好比,咱們把上面的代碼改爲這樣,看看效果。html
<!doctype html> <html lang="en"> <head> <style> li{ padding:20px; background:red; } span{ padding:10px; background:blue; } </style> </head> <body> <ul id=ul> <!-- 增長子元素 --> <li id='li1'><span>1</span></li> <li id='li2'><span>2</span></li> </ul> <script> ul.onclick = function (e){ console.log('span 被點擊了'); if(e.target.nodeName == 'LI'){ console.log('li 被點擊了'); } } </script> </body> </html>
效果圖
前端
看圖,當點擊 藍色 span 的時候,沒有打印 li 被點擊了 ,當點擊 紅色 li 的時候,才都打印出來,這是由於當點擊 span 的時候,事件源是 span,雖然也能觸發事件,可是並無走 if判斷,因此就不會打印 li 被點擊了 ,當點擊 li 的時候,事件源是 li ,因此就能夠了,可是咱們每每須要的是,無論是點擊li,仍是點擊 了 li 的子元素,都須要執行操做。
好的,咱們來改改代碼。
此次咱們須要 Element.matches( ) 這個方法, java
做用:
判斷當前DOM節點是否能徹底匹配對應的css選擇器規則;若是匹配成功,返回true,不然返回false。node
語法:jquery
let result = element.matches(selectorString);
result 的值爲 true 或 false
selectorString 是個css選擇器字符串 segmentfault
舉例:瀏覽器
<div id="d"> 這是一個div元素 </div> <script type="text/javascript"> var el = document.getElementById("d"); if (el.matches("div")) { alert("匹配到了!"); //能顯示彈框,由於"div"選擇器能夠選擇到el元素 } </script>
至於更多關於 Element.matches( ) 方法的細節,和對於不支持 Element.matches( ) 方法的瀏覽器的替代方案,請到這裏查看
Element.matches( )函數
<!doctype html> <html lang="en"> <head> <style> li{ padding:20px; background:red; } span{ padding:10px; background:blue; } </style> </head> <body> <ul id=ul> <!-- 增長子元素 --> <li id='li1'><span>1</span></li> <li id='li2'><span>2</span></li> </ul> <script> ul.onclick = function (e){ //獲取事件源 var target = e.target; //若是 事件源 不是 li 就進入循環 while(!target.matches('li')){ //若是事件源 是 ul 就把事件源 賦值爲null,跳出循環 //若是事件源 不是 ul 就把事件源 賦值爲事件源的父元素 if(target === ul){ target = null; break; } target = target.parentNode; } // 若是 target爲 true //也就是說 事件源是 li,就執行if語句裏的代碼 if(target){ console.log('li 被點擊了'); } } </script> </body> </html>
效果圖
看圖,如今這樣,無論是點擊 li 仍是 li 的子元素,就均可以打印出內容了。
jQuery中的事件委託
jQuery中事件委託主要是靠on( ) 方法,咱們先來看看 on( ) 方法的使用說明
on( ) 方法主要有如下兩種形式的用法
用法一
jQueryObject.on( events [, selector ] [, data ], handler )
用法二
jQueryObject.on( eventsMap [, selector ] [, data ] )
參數 | 描述 |
---|---|
events | String類型,一個或多個用空格分隔的事件類型和可選的命名空間,例如"click"、"focus click"、"keydown.myPlugin"。 |
eventsMap | Object類型,一個Object對象,其每一個屬性對應事件類型和可選的命名空間(參數events),屬性值對應綁定的事件處理函數(參數handler)。 |
selector | 可選/String類型,一個jQuery選擇器,用於指定哪些後代元素能夠觸發綁定的事件。若是該參數爲null或被省略,則表示當前元素自身綁定事件(實際觸發者也多是後代元素,只要事件流能到達當前元素便可)。 |
data | 可選/任意類型,觸發事件時,須要經過event.data傳遞給事件處理函數的任意數據。 |
handler | Function類型,指定的事件處理函數。 |
咱們再用jQuery的 on( ) 方法實現下,最開始的例子
<!doctype html> <html lang="en"> <head> <style> li{ padding:20px; background:red; } span{ padding:10px; background:blue; } </style> </head> <body> <ul id=ul> <!-- 增長子元素 --> <li id='li1'><span>1</span></li> <li id='li2'><span>2</span></li> </ul> <script src="http://code.jquery.com/jquery-2.2.4.js"></script> <script> $('#ul').on('click','li',function (){ console.log('li 被點擊了'); }); </script> </body> </html>
更加詳細的關於 JQuery中on( )方法的解釋,推薦看這裏
jQuery.on() 函數詳解
用到 事件委託 的地方,應該仍是比較多的,但願你們都能理解這個東西。