iT邦幫忙

0

JS30 Day 25:Event Capture, Propagation, Bubbling and Once學習筆記

今天這章節主要是在練習事件綁定相關的知識。

https://ithelp.ithome.com.tw/upload/images/20201123/201261824mAN2Kt9ta.png

主要以上面的畫面來做事件的操作。

  <button>BTN</button>
  <div class="one">
    <div class="two">
      <div class="three">
      </div>
    </div>

    <ul>
      <li><a href="javascript:;">Button1</a></li>
      <li><a href="javascript:;">Button2</a></li>
      <li><a href="javascript:;">Button3</a></li>
    </ul>
  </div>

addEventListener

有分為三個參數。
1.事件類型(event)。
2.回呼函數(callback)。
3.設定(options) (替換掉原本的捕獲(capture))。

事件分為兩種模式。
1.捕獲(capture):由外至內。
2.冒泡(bubbling)):由內至外。

此為最基本事件綁定的操作。

      let btn = document.querySelector("button");
      btn.addEventListener("click", btnHandler, {
        // options常用的參數,並以物件型式呈現,預設都為false
        // capture(boolean):true為捕獲模式,反之冒泡 , once(boolean):只執行一次
        capture: true,
        once: true
      });

      function btnHandler() {
        console.log("click");
      }

利用one,two,three(外至內)的區域來做操作。

使用預設的options,事件模式為冒泡。

 let divs = document.querySelectorAll('div');
      divs.forEach(div => {
        div.addEventListener('click', divHandler, {
          capture: false,
          once: false
        })
      })

當我們阻止事件進行傳遞。
為捕捉模式時,只會獲取最外層(one),因為無法進行事件傳遞。
為冒泡模式時,只會獲取當前層(one,two,three),因為無法進行事件傳遞。

      function divHandler(e) {
        e.stopPropagation(); // 可阻止當前事件繼續進行捕捉(capturing)及冒泡(bubbling)傳遞。
        console.log(this.className); // capture: false => three two one / true => one
        console.log(e.path, e.composedPath()); // [div.three, div.two, div.one, body.bod, html, document, Window] , [//]
      }

綁定事件:各別將事件綁到指定的dom上,而如果動態增加dom元素的話,新增的dom就不會被綁到事件。

      let as = document.querySelectorAll('a');
      as.forEach(a => {
        a.addEventListener('click', aHandler, {
          capture: false,
          once: false
        })
      })

target就是我們最深層的目標currentTarget就是綁定事件的目標
點擊Button1,2,3後,會顯示對應的訊息,委派的訊息(ul部分)也會顯示出來,但當我們動態新增li之後再點擊,發現綁定事件的訊息已經不見了

      function aHandler(e) {
        console.log("Bind : a click", "target", e.target, "currentTarget", e.currentTarget);
        // target <a href="javascript:;">Button3</a> , currentTarget <a href="javascript:;">Button3</a>
      }

委派事件:也就是將事件監聽做在外層,控制其委派範圍內的dom,動態新增進來的dom也能獲取事件。

https://ithelp.ithome.com.tw/upload/images/20201123/20126182teU4fEJXdj.png

      let ul = document.querySelector('ul');
      ul.addEventListener('click', ulHandler)

當Button1,2,3後,會顯示對應的訊息,當我們動態新增li之後再點擊,發現委派事件的訊息依然會顯示
而我們在委派時,可以利用判斷if去篩選我們所需的dom。

      function ulHandler(e) {
        // 加以判斷是否為a標籤(nodeName會將標籤轉為大寫)
        if (e.target.nodeName === "A") {
          console.log("delegate : a click", "target", e.target, "currentTarget", e.currentTarget);
          // target <a href="javascript:;">Button3</a>  , currentTarget <ul>…</ul> 
        }
      }

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言