前兩篇關於 DOM 的文章,我們大略知道如何新增、刪除或修改 DOM 中的節點了。這篇來了解如何監控 DOM 產生的事件們。
具體的事件類別(type)有:
- 使用者介面事件(User interface events,UI events):使用者以外部裝置觸發的事件;例如滑鼠、鍵盤、滾輪、文字輸入、……等。
- 滑鼠:click、mousedown、dblclick、drag、…
- 鍵盤:input、keydown、keyup、…
- 使用者邏輯事件(UI Logical events):與外部裝置無關的事件;例如焦點的變更、觸發元素通知。
- 捕捉(Capturing):事件在被事件目標處理前,可先由事件目標的祖先處理的過程。
- 冒泡(Bubbling):事件在被事件目標處理後,藉其祖先向上傳播的過程
- 可取消(Cancelable):特定事件被處理時,瀏覽器(client)可選擇藉執行任何與此事件有關的預設行為來阻止 DOM 的實現。
- 突變事件(Mutation events):修改文件結構引起的事件。
-
注意:已廢棄,可能隨時停止運作。但仍有部分瀏覽器為了相容性而支援。
太多惹,以上僅列出部分
DOM 事件分成許多類,目前的主題聚焦在網頁上,所以我們討論的是使用者與瀏覽器互動所造成的 DOM 事件。
以下介紹關於 event 與他的好伙伴們(<ゝω・)☆
Event 介面(event interface)
- 表示在 DOM 物件上發生的事情。
- Event 本身包含了所有事件的共同屬性與方法。
- 使用
addEventListener()
監聽元素的事件,當目標元素的指定事件發生時,執行指定程式碼。
- 使用
removeEventListener()
將元素與事件斷開
event 的 property
以下僅列出部分
只可讀:
- Event.bubbles:布林值;表示事件可否藉冒泡向上傳遞
- Event.cancelable:布林值;事件可否取消
- Event.type:事件的類型
- Event.currentTarget:指向目前事件監聽器所監聽的 DOM 物件;在冒泡與捕捉時的值會不同
- Event.target:指向最初觸發事件的 DOM 物件
event 的方法
- Event.stopPropagation():阻止事件流(往下捕捉或往上冒泡)
- Event.preventDefault():事件的
cancelable="true"
時,取消事件的行為,但不影響事件的傳遞
addEventListener()
設定一個函式或物件,當指定的事件被呼叫時就會執行函式/加入物件。
addEventListener(type, listener)
addEventListener(type, listener, options)
addEventListener(type, listener, useCapture)
參數說明:
- type:要監聽的事件類型,需區分大小寫的字串。
- listener:當監聽的事件類型發生時,接收提醒的 event 物件或 JavaScript 函式。(會被執行或呼叫)
- options:是一個物件,用於指定關於事件監聽器的特性,以更細緻的操控事件監聽器的行為。可用選項如下:
- capture:布林值
- false:預設值;事件會在冒泡階段傳給事件監聽器。
- true:設為 true 時,指的是在註冊了一堆事件監聽器後,設定
{capture: true}
的事件監聽器 type 會優先被捕捉;若有多個同樣為 true 的事件監聽器,則會依註冊順序捕捉。
- once:布林值
- false:預設值
- true:設為 true 時,代表這個事件監聽器被觸發時只會執行一次,執行後會自動移除。
- passive:布林值,
- false:預設值;代表指定元素的預設行為若能取消便取消,但不影響事件流向(冒泡/捕捉)。
- true:設為 true 時,代表這個事件監聽器永遠不會呼叫 preventDefault(),即被指定元素的預設行為(事件)不會被取消;也就是說,瀏覽器已經知道 preventDefault() 永遠不會被呼叫,不會浪費效能在確認目標元素是否有 preventDefault() 這件事。
- 某些瀏覽器對這些事件預設為 true:wheel、mousewheel、touchstart、touchmove events
- signal:AbortSignal 物件適用的功能。
- abort():設定為 abort() 時,會呼叫 AbortSignal 物件的 abort() 方法來移除自己、中斷對目標的監聽。
- useCapture:布林值,表示指定類型的事件流向是冒泡或是捕捉。
- true:事件監聽器會在捕捉階段觸發
- false:預設值;事件監聽器會在冒泡階段觸發
- 回傳值:undefined
this
- 在 addEventListener 的 function 使用 this 時,this 指的就是目標元素。
- 箭頭函式則沒有自己的 this
來個練習吧!例子來自 GPT,略為修改
<div class="box">
<h3>addEventListener 的練習</h3>
<p>嗨你好</p>
<p>我是</p>
<button id="btn">click</button>
<p>海獺</p>
</div>
// 基本使用
// Q. 按下按鈕在控制台出現一段話
const btn = document.querySelector("#btn");
btn.addEventListener("click", function () {
console.log("被點惹>///<");
});
event.target
- 指向永遠是最初觸發事件的 DOM 物件
- 僅可讀取
- 變數 event 常見以 e、evt 代替
- 抓到 DOM 後,可以存取 DOM 的 properties 和屬性、也可修改 DOM 的樣式與 properties。
蒸蚌
// 語法
theTarget = event.target
直接上例子吧 :D
<button id="btn">click</button>
// 取得 e.target
const btn = document.querySelector("#btn");
btn.addEventListener("click", function (e) {
console.log(e.target); // <button id="btn">click</button>
});
例子二
<button id="button1">Button 1</button>
<button id="button2">Button 2</button>
<button id="button3">Button 3</button>
<p id="output"></p>
// Q. 按下 btn 可改變 p 的內容
const buttons = document.querySelectorAll("button");
const output = document.getElementById("output");
function handleButtonClick(event) {
let content = event.target.textContent;
output.textContent = `"${content}" is clicked!`;
}
buttons.forEach((button) => {
button.addEventListener("click", handleButtonClick);
});
event.target.value
- 可以得到 event.target 的值
- 常於 input 的取值
直接上例子吧:D
例子來自 GPT,略為修改
<input type="text" id="input" placeholder="輸入一些字">
// 取得 input 的輸入內容
const input = document.getElementById("input");
input.addEventListener("input", function (e) {
const content = e.target.value; // 取得 input 的輸入值
console.log("Input value:", content);
});
event.target.style
直接上例子吧:D
例子來自 GPT,略為修改
<div class="color-box">點我隨機換色</div>
.color-box {
width: 100px;
height: 100px;
border: 1px solid black;
padding: 3% 4.5%;
}
// Q. event.target.style 更改 css style
const colorBox = document.querySelector(".color-box");
function changeColor(event) {
const randomColor = `#${Math.floor(Math.random() * 16777215).toString(16)}`;
event.target.style.backgroundColor = randomColor;
}
colorBox.addEventListener("click", changeColor);
event.target.files
- 取得選取的檔案物件清單(陣列)
- 預設最多只能選取一筆資料
- 在 HTML 元素部分加上
multiple="multiple"
屬性可以選取多個檔案
直接上例子吧:D 一樣來自 GPT,略加修改
Q:請寫一個 HTML 表單,包含一個文件上傳的 <input>
元素。當使用者選擇文件後,請使用 JavaScript 來顯示所選文件的名稱和大小。
<input type="file" id="fileInput">
<div id="output"></div>
const input = document.getElementById("fileInput");
const output = document.getElementById("output");
input.addEventListener("change", function (e) {
const files = e.target.files;
if (files.length > 0) {
const file = files[0];
output.textContent = `檔案名稱:${file.name}, 檔案大小:${file.size} 位元組`;
} else {
output.textContent = "沒有選擇文件。";
}
});
自己覺得這篇很精實XD
要在一篇裡塞那麼多東西,獺腦袋瓜差點燒惹ˊ_>ˋ
參考資料
- 事件 - 術語表 | MDN,https://developer.mozilla.org/zh-TW/docs/Glossary/Event
- Event - Web APIs | MDN,https://developer.mozilla.org/zh-TW/docs/Web/API/Event
- Event reference | MDN,https://developer.mozilla.org/en-US/docs/Web/Events
- 事件處理 · 從ES6開始的JavaScript學習生活,https://eyesofkids.gitbooks.io/javascript-start-from-es6/content/part4/event.html
- DOM event - Wikipedia,https://en.wikipedia.org/wiki/DOM_event
- JavaScript Event Types - 8 Essential Types to shape your JS Concepts! - DataFlair,https://data-flair.training/blogs/javascript-event-types/
- EventTarget: addEventListener() method - Web APIs | MDN,https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
- Event.preventDefault() - Web APIs | MDN,https://developer.mozilla.org/zh-TW/docs/Web/API/Event/preventDefault
- EventTarget - Web APIs | MDN,https://developer.mozilla.org/en-US/docs/Web/API/EventTarget
- Event: target property - Web APIs | MDN,https://developer.mozilla.org/en-US/docs/Web/API/Event/target
- Event.target - Web APIs | MDN,https://developer.mozilla.org/zh-TW/docs/Web/API/Event/target
- What is the Event Target in Javascript? - Scaler Topics,https://www.scaler.com/topics/event-target-javascript/
- [WebAPIs] 檔案上傳 Input File, File Upload, and FileList | PJCHENder 未整理筆記,https://pjchender.dev/webapis/webapis-file-input/