<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          20k的前端是這樣寫(xiě)事件委托的

          共 1085字,需瀏覽 3分鐘

           ·

          2021-10-23 13:18

          作者:純純純爺們 鏈接:https://juejin.cn/post/6844904097372438542 來(lái)源:稀土掘金

          要理解DOM相關(guān)事件,我們先要理解“事件流”這個(gè)概念,事件流描述的是從頁(yè)面中接收事件的順序。

          事件冒泡:事件開(kāi)始由最具體的元素接收,然后逐級(jí)向上傳播到較為不具體的節(jié)點(diǎn)或文檔。

          事件捕獲:事件開(kāi)始由不太具體的節(jié)點(diǎn)接收,然后逐級(jí)向下傳播到最具體的節(jié)點(diǎn)。它與事件冒泡是個(gè)相反的過(guò)程。

          DOM2 級(jí)事件規(guī)定的事件流包括三個(gè)階段:事件捕獲、目標(biāo)階段、事件冒泡。

          事件委托

          事件委托,通俗的說(shuō)就是將元素的事件委托給它的父級(jí)或者更外級(jí)的元素處理,它的實(shí)現(xiàn)機(jī)制就是事件冒泡。

          假設(shè)有一個(gè)列表,要求點(diǎn)擊列表項(xiàng)彈出對(duì)應(yīng)的字段:

          "myLink">
          ??"1">aaa
          ??"2">bbb
          ??"3">ccc

          不使用事件委托

          var?myLink?=?document.getElementById('myLink');
          var?li?=?myLink.getElementsByTagName('li');

          for(var?i?=?0;?i???li[i].onclick?=?function(e)?{
          ????var?e?=?event?||?window.event;
          ????var?target?=?e.target?||?e.srcElement;
          ????alert(e.target.id?+?':'?+?e.target.innerText);??
          ??};
          }

          存在問(wèn)題:

          • 給每一個(gè)列表都綁定事件,消耗內(nèi)存
          • 當(dāng)有動(dòng)態(tài)添加的元素時(shí),需要重新給元素綁定事件

          8k的前端寫(xiě)出的事件委托

          事實(shí)上很多同學(xué)在網(wǎng)上看到的事件委托的方法都是錯(cuò)的,雖然是錯(cuò)的,但是你面試的時(shí)候也可能會(huì)過(guò),因?yàn)槊婺愕拿嬖嚬倏赡芤膊恢勒_的事件委托應(yīng)該怎么寫(xiě)。

          下面我們就來(lái)看一下錯(cuò)誤版的事件委托是怎么寫(xiě)的:

          ?ul.addEventListener('click',?function(e){
          ?????if(e.target.tagName.toLowerCase()?===?'li'){
          ?????????fn()?//?執(zhí)行某個(gè)函數(shù)
          ?????}
          ?})

          20k的前端寫(xiě)出的事件委托

          錯(cuò)誤版事件委托的bug 在于,如果用戶點(diǎn)擊的是 li里面的 span,就沒(méi)法觸發(fā) fn,這顯然不對(duì)。那下面我們來(lái)看一下正確的事件委托應(yīng)該怎么寫(xiě):

          function?delegate(element,?eventType,?selector,?fn)?{
          ?????element.addEventListener(eventType,?e?=>?{
          ???????let?el?=?e.target
          ???????while?(!el.matches(selector))?{
          ?????????if?(element?===?el)?{
          ???????????el?=?null
          ???????????break
          ?????????}
          ?????????el?=?el.parentNode
          ???????}
          ???????el?&&?fn.call(el,?e,?el)
          ?????})
          ?????return?element
          ???}

          思路是點(diǎn)擊 span后,遞歸遍歷 span 的祖先元素看其中有沒(méi)有 ul 里面的 li。

          事件委托的優(yōu)點(diǎn)

          • 只需要將同類元素的事件委托給父級(jí)或者更外級(jí)的元素,不需要給所有的元素都綁定事件,減少內(nèi)存占用空間,提升性能。

          • 動(dòng)態(tài)新增的元素?zé)o需重新綁定事件

          需要注意的點(diǎn)

          • 事件委托的實(shí)現(xiàn)依靠的冒泡,因此不支持事件冒泡的事件就不適合使用事件委托。
          • 不是所有的事件綁定都適合使用事件委托,不恰當(dāng)使用反而可能導(dǎo)致不需要綁定事件的元素也被綁定上了事件。

          告誡自己,即使再累也不要忘記學(xué)習(xí),成功沒(méi)有捷徑可走,只有一步接著一步走下去。共勉!文章中如有不對(duì)的地方,歡迎小伙伴們多多指正。謝謝大家~ ??

          神評(píng):


          瀏覽 76
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  超碰国产青娱乐 | 91十八禁| 国产三级A片 | 国产麻豆精品成人免费视频 | 操逼逼啊啊啊 |