event delegation -- 事件委托

事件代理或者說是事件委托,就是利用事件的冒泡特性,將事件綁定到外層元素上,而不是觸發(fā)事件的元素上。可以減少綁定的事件數(shù)量,而且對于動態(tài)加載的內(nèi)容來說,十分有利。

// html
<ul id="lists">
    <li class="list"></li>
    <li class="list"></li>
    <li class="list"></li>
</ul>

// js
var lists = document.getElementById('lists');
var delegate = function(element, selector, event, hanlder) {
    element.addEventListener(event, function(e) {
        var target = e.target;
        if(!target.matches(selector)) {
            return;
        }
        hanlder(e);
    });
};

delegate(lists, 'li', 'click', function(e){console.log('event delegation')});

上面這個代碼,應(yīng)該是我們經(jīng)常看到的簡易版的事件委托。把點擊事件綁定到ul上,只有點擊的元素為li時,這個事件處理函數(shù)才被執(zhí)行。

這樣做的好處就是

  1. 如果事件是綁定在li上時,則需要綁定三次事件,而現(xiàn)在事件綁定在ul上,綁定次數(shù)減少到一次
  2. 如果事件是綁定是li上時,后面還要動態(tài)加載li元素時,還要繼續(xù)為加載的li元素綁定事件,而現(xiàn)在事件綁定在ul上,就無需綁定了。

這樣寫,也明顯有個不足,就是如果觸發(fā)事件的元素不是li,而是li的子元素時,上面的那個事件不會被觸發(fā)。但講道理,li子元素觸發(fā)點擊事件,也是可以認(rèn)為是li觸發(fā)點擊事件的。

所以,我們可以按照下面的方式實現(xiàn)事件委托。

// html
<ul id="lists">
    <li class="list"><span>list 1</span></li>
    <li class="list"><span>list 2</span></li>
    <li class="list"><span>list 3</span></li>
</ul>

// js
var lists = document.getElementById('.lists');
var isParentOfTarget = function(selector, target, until) {
    if(!until) {
        until = document.documentElement;
    }
    var parent = target;
    while(parent != until) {
        if(parent.matches(selector)) {
            return parent;
        }
        parent = parent.parentNode;
    }
    return false;
}

var delegate = function(element, selector, event, hanlder) {
    element.addEventListener(event, function(e) {
      var target = e.target;
      var res = isParentOfTarget(selector, target, element)
      if(!res) {
        return;
      }
      hanlder.call(res, e);
    }, false);
}
delegate(lists, 'span', 'click', function(e){console.log('evnet delegation');});

通過isParentOfTarget函數(shù),判斷觸發(fā)事件的元素(即event.target),是不是我們需要委托的元素的子元素,如果是,則返回這個委托的元素,不是,就返回false。

最后,再利用call函數(shù),將事件處理函數(shù)的this綁定到所需委托的元素上。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容