iT邦幫忙

2021 iThome 鐵人賽

DAY 13
0
自我挑戰組

追憶JS年華系列 第 25

Day-25 事件機制(1)

  • 分享至 

  • xImage
  •  

在網頁中的JavaScript程式碼,必須經由事件觸發(如:按下按鈕,又稱事件驅動event-driven)才會執行。其觸發則根據網頁元素接收事件的順序(事件流程event flow)而定。

具體上,事件流程可分為事件冒泡、事件捕獲兩大機制。而事件觸發時,兩機制都會執行。

事件冒泡 Event Bubbling

所謂事件冒泡,可理解為「由外向內」的,從「事件觸發的節點」向根部(document)往上傳遞的過程。以前文網頁原始碼為基礎,舉例來說:

<html>
    <head>冒泡一下</head>
        <body>
            <div>Hello</div>
            <div>Hi</div>
            <div>There
                <button>CLICK</button>
            </div>
        </body>
</html>

此例中,若點下CLICK按鈕,經由事件冒泡,觸發順序會是:

  1. button標籤
  2. div標籤
  3. body標籤
  4. html標籤
  5. document

事件捕獲 Event Capturing

與之相對,事件捕獲則相反,可理解為「由內向外」的,從根部(document)向下捕獲「事件觸發的節點」的過程。以前文網頁原始碼為基礎,舉例來說:

<html>
    <head>捕獲一下</head>
        <body>
            <div>Hello</div>
            <div>Hi</div>
            <div>There
                <button>CLICK</button>
            </div>
        </body>
</html>

此例中,若點下CLICK按鈕,經由事件捕獲,觸發順序會是:

  1. document
  2. html標籤
  3. body標籤
  4. div標籤
  5. button標籤

事件的綁定與監聽

除了前文介紹的 window.addEventListener() 方法外,尚有其他常見方式。在HTML中觸發支援的事件,可以用on+事件名進行,比如「onclick」。

<button id="btn" onclick="console.log('你按下去了');">CLICK</button>

此例中,若點下CLICK按鈕,會印出「你按下去了」,也就是在button上面註冊click事件。惟基於安全性,此類作法已日漸少用。

然而,若遇到沒有實體元素的情況,以使用DOM API提供的 on-event處理器(event handler)處理。網頁原始碼一樣:

<button id="btn">CLICK</button>

而JavaScript則如此綁定:

let btn = document.getElementById('btn');

btn.onclick = function() {
    console.log('你按下去了');
}

與事件處理器不同,事件監聽器寫為 addEventListener() ,共涵蓋三個函數:

  • 事件名稱
  • 事件處理器(函式)
  • 事件捕獲/事件冒泡

同上,針對同一預期事件:

<button id="btn">CLICK</button>

監聽事件啟動時,會執行其中的函式。監聽器會產生生一個事件物件(Event Object),生成包括有關屬性(視事件而有不同)的參數(本例為a),再丟給函式處理。在JavaScript中給出一個參數a:

let btn = document.getElementById('btn');

  btn.addEventListener('你按下去了', function(e){
  console.log(e);
}, false);
}

其他

其他尚有「阻擋預設行為」的 event.preventDefault() 、「阻擋事件冒泡傳遞」的 event.stopPropagation() 可資使用,意者可再持續深造。


上一篇
Day-24 DOM Node
下一篇
Day-26 事件機制(2)
系列文
追憶JS年華30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言