javascript和jq的事件委託

今天在公司,有個需求是,經過ajax動態查詢數據,回來,再添加到一個ul的li元素中,例如(點擊生成 li 模擬,加載數據生成相應的數據, 事件: 點擊):javascript

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
    <button>create</button>
    <ul id="parent">
        <li class="son-1">Item 1</li>
        <li class="son-2">Item 2</li>
    </ul>
    <script>
        $(function () {
            $('button').on('click', function (e) {
                $('#parent').append('<li>add</li>')
            });
        });
    </script>
</body>
</html>

平時本身的添加事件:html

$('#parent li').on('click', function (e) {
    alert('這是第' + $(this).index() + 'li');
});

這樣子能夠爲,dom元素中已經通過渲染的li元素綁定事件,若是點擊 craete按鈕新生成的li元素,因爲,事件綁定的js已經執行完畢,因此沒法對新生成的li進行事件的綁定。一開始,在沒有用jq的事件委託,本身簡單的粗暴的對新生的元素,再一次動態綁定:java

//在生成新生元素後, 再次執行這段 函數 ,綁定須要的事件。
$('#parent li').on('click', function (e) {
    alert('這是第' + $(this).index() + 'li');
});

明顯是很挫的作法,不只不易維護,並且性能也大打折扣,由於這樣雖然會爲新的元素綁定到事件,可是已經存在的元素也會再次綁。node

jq提供的事件委託,能夠頗有效的解決這種問題。delegate 和 on 都提供了相應的方法jquery

$('#parent').delegate('li', 'click', function(event) {
    console.log($(this))
});
$('#parent').on('click', 'li', function (e) {
    console.log($(this))
});

這兩個函數都可提供相應的效果,我的更傾向於使用 on :ajax

下面是從jq的api copy過來的使用文檔:api

on(events,[selector],[data],fn)

概述

在選擇元素上綁定一個或多個事件的事件處理函數。app

on()方法綁定事件處理程序到當前選定的jQuery對象中的元素。在jQuery 1.7中,.on()方法 提供綁定事件處理程序所需的全部功能。幫助從舊的jQuery事件方法轉換,see .bind().delegate(), 和 .live(). 要刪除的.on()綁定的事件,請參閱.off()。要附加一個事件,只運行一次,而後刪除本身, 請參閱.one()dom

參數

events,[selector],[data],fnV1.7

events:一個或多個用空格分隔的事件類型和可選的命名空間,如"click"或"keydown.myPlugin" 。函數

selector:一個選擇器字符串用於過濾器的觸發事件的選擇器元素的後代。若是選擇的< null或省略,當它到達選定的元素,事件老是觸發。

data:當一個事件被觸發時要傳遞event.data給事件處理函數。

fn:該事件被觸發時執行的函數。 false 值也能夠作一個函數的簡寫,返回false。

events-map,[selector],[data]V1.7

events-map:個用字符串表示的,一個或多個空格分隔的事件類型和可選的命名空間,值表示事件綁定的處理函數。

selector:一個選擇器字符串過濾選定的元素,該選擇器的後裔元素將調用處理程序。若是選擇是空或被忽略,當它到達選定的元素,事件老是觸發。

data:當一個事件被觸發時要傳遞event.data給事件處理函數。


javascript也有原生的事件委託

DEMO:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <input type="button" id="btn" />
    <ul id="ul">
      <li>aaaaaaaa</li>
      <li>bbbbbbbb</li>
      <li>cccccccc</li>
    </ul>
    <script>
        window.onload = function(){
          var oUl = document.getElementById("ul");
          var aLi = oUl.getElementsByTagName("li");
          var oBtn = document.getElementById("btn");
          var iNow = 4;

          oUl.onmouseover = function(ev){
            var ev = ev || window.event;
            var target = ev.target || ev.srcElement;
            if(target.nodeName.toLowerCase() == "li"){
                alert('觸發了')
            }
          }
          oUl.onmouseout = function(ev){
            var ev = ev || window.event;
            var target = ev.target || ev.srcElement;
            if(target.nodeName.toLowerCase() == "li"){
               alert('觸發了')
            }
          }
          oBtn.onclick = function(){
            iNow ++;
            var oLi = document.createElement("li");
            oLi.innerHTML = iNow;
            oUl.appendChild(oLi);
          }
        }
    </script>
</body>
</html>

從原生的js中能夠看出:事件委託是經過,事件的冒泡。實現的。經過子元素的點擊事件,冒泡到父元素,父元素再經過event的內容判斷 爲該元素觸發相應的事件, 在demo中的,獲取對應的 tagName 判斷子元素 是否是 li。是的話觸發對應的事件,從而 達到事件的委託。

相關文章
相關標籤/搜索