JS30 Day 25 筆記


Posted by GL on 2023-05-23

目標

EventTarget.addEventListener中事件的 capturebubbleonce 方法,以及事件代理(propagation)

Demo

step 1 : 了解 HTML 的架構與建立 click 監聽事件

<div class="one">
  <div class="two">
    <div class="three">
    </div>
  </div>
</div>
// 取得頁面的所有 div 元素
const divs = document.querySelectorAll('div');

function logText(e){
// console 印出當前 click 的 class name
  console.log(this.classList.value);
}

// 監聽所有 div 元素的 click 事件 
divs.forEach(div => div.addEventListener('click',logText));

step 2 : 點擊最裡面的 class name 為 three 的區塊,並查看 console.log 的結果

發現印出從最内層到最外層(three -> two -> one)

three
two
one

step 3 : 分析 addEventListener 的參數

// 第一個參數: 監聽的事件類型(event type)
// 第二個參數: 事件被觸發時,要執行的 callback function
// 第三個參數: options 是一個物件,可控制的屬性有 capture、once...等
addEventListener(type, listener, options)
divs.forEach(div => div.addEventListener('click', logText, {
  // 預設為false,表示事件的觸發順序為冒泡階段(由下往上的層級)
  // 若爲 true,則表示設定為捕獲階段(由上往下的層級。印出:one,two,three)
  capture: false, 
  //預設為 false,若設爲 true,則表示事件只監聽一次
  //執行後 removeEventListener
  once: false 
  //預設為 false,若設爲 true,則表示將無法在函式中使用 event.preventDefault() 方法。
  passive: false
}));

step 4 : stopPropagation()

e.stopPropagation:表示此處監聽到事件後,停止事件以捕獲或者冒泡的方式往下個層級傳遞,

function logText(e) {
  console.log(this.classList.value);
  e.stopPropagation(); // stop bubbling or capture 
}

補充: Event delegation

如果有很多類似的監聽事件,與其在每個元素中挂上監聽,較好的做法是統一監聽在這些元素的父元素


參考資料:


#JS 30







Related Posts

5. 隊列(Queue)

5. 隊列(Queue)

Laravel view component cache

Laravel view component cache

[TensorFlow Certification Day1] 環境安裝

[TensorFlow Certification Day1] 環境安裝


Comments