簡單說 JavaScript中的事件委託(下)

說明

上次咱們說了一些,關於 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() 函數詳解

總結

用到 事件委託 的地方,應該仍是比較多的,但願你們都能理解這個東西。

前端簡單說

相關文章
相關標籤/搜索