上一篇講到event傳遞時的三種phase,形成事件capturing和bubbling

再來整理相關的應用,加深印象


Event Delegation(事件代理)

由父元素取代子元素註冊事件

範例: (取自JavaScript Event Delegation)

<ul id="menu">
    <li><a id="home">home</a></li>
    <li><a id="dashboard">Dashboard</a></li>
    <li><a id="report">report</a></li>
</ul>


當每個選單項目都想綁定click事件,可能會這樣寫

let home = document.querySelector('#home');
home.addEventListener('home',(event) => {
    console.log('Home menu item was clicked');
});

let dashboard = document.querySelector('#dashboard');
dashboard.addEventListener('dashboard',(event) => {
    console.log('Dashboard menu item was clicked');
});

let report = document.querySelector('#report');
report.addEventListener('report',(event) => {
    console.log('Report menu item was clicked');
});

當項目越來越多 or 頁面越來越複雜,可能就會註冊很多個event handler,效能不好


利用event傳播的機制,可以改寫成:

let menu = document.querySelector('#menu');

menu.addEventListener('click', (event) => {
    let target = event.target;

    switch(target.id) {
        case 'home':
            console.log('Home menu item was clicked');
            break;
        case 'dashboard':
            console.log('Dashboard menu item was clicked');
            break;
        case 'report':
            console.log('Report menu item was clicked');
            break;
    }
});

當點擊ul中的a連結時,因為event bubbling最後會傳遞給ul元素,所以由父元素代為綁定event

而透過target id 可以區分是哪個目標被點擊


小結event delegation的優點:

  • 減少記憶體的消耗, 增加效能

  • 減少在頁面中註冊多個event handler


Event Stop Propagation

這篇Event Capturing and Bubbling in JavaScript有提到,知道event的傳播機制,Who care?? (都用預設bubbling就好??)

看起來不重要,踩到雷就知道

除了event delegation,最常遇到的應該是彈跳視窗(for 手刻)

彈跳視窗出現後,通常有兩種方式可以關閉

  1. 點擊彈跳視窗的x
  2. 點擊彈跳視窗以外的區域

範例 (取自 JavaScript Capture Bubble DOM事件獲取&冒泡)

See the Pen popup sample by pengyushan (@pengpon77) on CodePen.


小結:

  1. 選定capturing or bubbling傳遞方式
  2. target到達後,不再往上或往下傳,使用e.stopPropagation()中斷
  3. 彈出視窗事件僅綁定在button上,click不再往下傳!!
  4. 關閉視窗事件除綁在x span上,也要綁定在整個document上
  5. 跳窗本身被點擊後,要阻止事件繼續傳給document!


或是利用event target來控制跳窗的開啟或關閉

CodePen範例參考

See the Pen Simple Confirmation Popup by Adventures in Missions (@adventuresinmissions) on CodePen.


延伸閱讀&參考圖文

JavaScript Capture Bubble DOM事件獲取&冒泡

Event Delegation

JavaScript Event Delegation