js原生之事件委托

什么是事件委托?

委托是啥意思?就是本來吧中午啊你要自己去買飯,結(jié)果這個(gè)時(shí)候室友問你要不要帶飯?你說好??!于是帶飯這個(gè)操作就被你委托給室友了。
事件委托 的意思是,本來這個(gè)事件是由節(jié)點(diǎn)本身去執(zhí)行的,現(xiàn)在用其他節(jié)點(diǎn)委托執(zhí)行。

怎么進(jìn)行事件委托?

我們來看一個(gè)再普通不過的例子吧,有以下html結(jié)構(gòu)

<ul  id="delegate">
  <li>item1</li>
  <li>item2</li>
  <li>item3</li>
  <li>item4</li>
  <li>item5</li>
</ul>

假設(shè)這時(shí)候有需求如下,我希望鼠標(biāo)經(jīng)過li節(jié)點(diǎn)的時(shí)候,節(jié)點(diǎn)的背景色變?yōu)榧t色,鼠標(biāo)移出則變回來,我們通常會(huì)這么寫

<script type="text/javascript">
var aUl=document.querySelector('#delegate');
var aLis=div.querySelectorAll('li');
for (var i = 0; i < aLis.length; i++) {
  aLis[i].onmouseover=function(){
    this.style.backgroundColor='red';
  }

  aLis[i].onmouseout=function(){
    this.style.backgroundColor='';
  }
}
</script>

沒毛病哈~那么問題來了,我們?cè)趺窗?code>li的事件委托給其他節(jié)點(diǎn)替他執(zhí)行呢?
首先說下事件委托的原理是利用什么,大家都知道js里面事件有冒泡機(jī)制,當(dāng)我們鼠標(biāo)經(jīng)過li的時(shí)候它的onmouseover事件會(huì)觸發(fā),它的父親元素ulonmouseover事件也會(huì)被觸發(fā),事件委托就是利用事件冒泡機(jī)制來完成的。不多說上代碼

var aUl=document.querySelector('#delegate');
var aLis=div.querySelectorAll('li');

aUl.onmouseover=function(ev){
  var ev=ev||window.event;//事件對(duì)象兼容
  var target=ev.target||ev.srcElement;//冒泡時(shí)拿到當(dāng)前的觸發(fā)事件的元素(事件源)
  target.style.backgroundColor='red';
}
aUl.onmouseout=function(ev){
  var ev=ev||window.event;
  var target=ev.target||ev.srcElement;
  target.style.backgroundColor='';
}

以上代碼就完成了最簡單的事件委托,是不是很簡單?但是問題來了,這樣寫有沒有問題?
答案是:有?。?!
我們給 ul 添加的onmouseoveronmouseout事件,那么鼠標(biāo)經(jīng)過 ul ,ul的背景也是會(huì)邊紅的?。?!
那么怎么辦?
其實(shí)我們獲取到事件源之后,事件源是一個(gè) DOM 節(jié)點(diǎn),我們是可以拿到節(jié)點(diǎn)的名字 target.nodeName,我們只需要判斷下節(jié)點(diǎn)名字就行啦?。?!來來來!?。?/p>

aUl.onmouseover=function(ev){
  var ev=ev||window.event;
  var target=ev.target||ev.srcElement;
  console.log(target.nodeName);
  if(target.nodeName=='LI'){
      target.style.backgroundColor='red';
    }
}
aUl.onmouseout=function(ev){
  var ev=ev||window.event;
  var target=ev.target||ev.srcElement;
  if(target.nodeName=='LI'){
      target.style.backgroundColor='';
    }
}

這么寫有什么好處呢?

1、對(duì)比委托前和委托后的代碼就知道,本來每個(gè) li 上都有兩個(gè)事件句柄,委托后我們只給 ul 增加了兩個(gè)事件句柄,可以大量節(jié)省內(nèi)存占用,減少事件注冊(cè)
2、通過js代碼新添加li節(jié)點(diǎn)同樣有事件,不用單獨(dú)注冊(cè)(相似如jquery.delegate())

注:事件委托雖然好,但是還是有需要注意的地方的,最明顯的就是我的例子中判斷是不是 li 節(jié)點(diǎn)這個(gè)處理,當(dāng)前節(jié)點(diǎn)結(jié)構(gòu)簡單,如果被委托元素內(nèi)節(jié)點(diǎn)類型眾多,判斷條件就會(huì)很復(fù)雜。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)載自 http://www.cnblogs.com/liugang-vip/p/5616484.html 一、概...
    涅磐廣廣閱讀 555評(píng)論 0 8
  • 1.背景介紹 1.1什么是事件委托? 事件委托還有一個(gè)名字叫事件代理,JavaScript高級(jí)程序設(shè)計(jì)上講:事件委...
    我叫于搞吧閱讀 1,715評(píng)論 4 9
  • 大家好,我是IT修真院成都分院第07期學(xué)員,一枚正直善良的web程序員。 一、小課堂簡述JS中的事件委托 1.背景...
    120De丶L閱讀 386評(píng)論 0 0
  • (續(xù)jQuery基礎(chǔ)(1)) 第5章 DOM節(jié)點(diǎn)的復(fù)制與替換 (1)DOM拷貝clone() 克隆節(jié)點(diǎn)是DOM的常...
    凜0_0閱讀 1,518評(píng)論 0 8
  • 風(fēng)一起 蒲公英就走了 沒成熟的小胖墩 緊緊抓著不肯放手 月光下的山谷閃著微光 照著蒲公英一路飄 飄去大河落腳 小胖...
    橙小沒閱讀 242評(píng)論 0 0

友情鏈接更多精彩內(nèi)容