nodeName 是 DOM 元素的一個唯讀屬性,可以告訴你「這個節點是什麼類型」
//HTML
<input type = "button" value = "點擊" class = "btn">
const btn = document.querySelector("button");
console.log(btn.nodeName); // "INPUT"
console.log(btn.getAttribute("type")); // "button"
console.log(btn.getAttribute("value")); // "點擊"
e.target 是事件物件(event object)裡的一個屬性,它會告訴你:「使用者實際點到(或觸發事件)的那個元素是誰」
//HTML
<input type = "button" value = "點擊" class = "btn">
const btn = document.querySelector(".btn");
btn.addEventListener("click", function (e) {
console.log(e.target); //輸出 <input type="button" value="點擊" class="btn">
});
什麼時候會用到e.target呢?
只要是「同一個監聽器要處理很多個子元素」,或是「元素是之後才動態產生的」,就一定會用到 e.target。
常見使用時機
1.一群按鈕,想知道按到哪一個
//HTML
<div class="menu">
<button>蛋餅</button>
<button>飯糰</button>
<button>豆漿</button>
</div>
document.querySelector(".menu").addEventListener("click", function (e) {
console.log(e.target.textContent + " 被點了");
});
//豆漿 被點了
//飯糰 被點了
//蛋餅 被點了
不用幫每顆按鈕分別寫監聽器,一個父層監聽器搞定全部。
2.點擊清單裡的「刪除」按鈕
//HTML
<ul class="list">
<li>買雞蛋 <button class="del">刪除</button></li>
<li>買牛奶 <button class="del">刪除</button></li>
</ul>
document.querySelector(".list").addEventListener("click", function (e) {
if (e.target.classList.contains("del")) {
e.target.parentElement.remove(); // 刪掉這一整條 <li>
}
});
列表項目是動態產生的(例如待辦清單、購物車),你不知道未來會有幾個,用 e.target 才能知道使用者按的是哪一個
3.點擊輸入框,取得使用者輸入的值
//HTML
<input type="text" id="search" placeholder="請輸入代辦事項">
<button id="add">新增</button>
document.querySelector("#search").addEventListener("input", function (e) {
console.log("目前輸入:" + e.target.value);
});
4.點擊空白處要關閉彈跳視窗(判斷點到的是不是背景)
//HTML
<div id="modalBackground">
</div>
<style>
#modalBackground {
width: 100px;
height:100px;
background-color: rgba(0, 0, 0, 0.5);
}
</style>
document.querySelector("body").addEventListener("click", function (e) {
if (e.target.id !== "modalBackground") {
// 只有點到背景本身才關閉,點到裡面的內容不會關
console.log("關閉視窗");
alert("關閉視窗");
}
});
利用nodeNmae去判斷有沒有點到該節點
//HTML:<ul class="list">
<li>標題<input type="button" class="btn1" value="按鈕"></li>
</ul>
const list=document.querySelector('.list');
list.addEventListener('click',function(e){
if(e.target.nodeName=="INPUT"){
alert('按到了');
}
})
e.target和nodeName是很常見的搭配
e.target 是「找到使用者點到誰」,nodeName 是「確認那個誰是什麼類型」
兩個合起來就是:先抓到目標,再檢查它是不是我要的類型
範例:點早餐
//HTML
<div id="counter">
<span>今日菜單:</span>
<button data-item="蛋餅">蛋餅</button>
<button data-item="豆漿">豆漿</button>
</div>
document.querySelector("#counter").addEventListener("click", function (e) {
if (e.target.nodeName === "BUTTON") {
console.log(e.target.dataset.item + " 加入訂單!");
} else {
console.log("你點到的不是按鈕,不處理");
}
});
客人在櫃檯範圍內隨便點,但我只在乎他點到的是不是『按鈕』,如果不是就忽略。
因為事件代理(把監聽器放在父層)常常會有「誤觸」的狀況——父層底下可能包了好幾種元素(文字、圖片、按鈕...),你不檢查的話,點到任何地方都會誤發動作。
一句話總結:e.target 負責「抓到是誰」,nodeName(或 class、matches)負責「篩選出我要的那種」——這是事件代理最常見的黃金組合