昨天終於成功把哈納從 Console 抓到網頁上。
今天想說既然都會 addEventListener() 了,
那就再玩一下點擊事件。
結果一點下去才發現——
蛤?我明明只點裡面那個,怎麼外面也一起有反應???
你們消息是傳多快啦 ==
所以今天來看看一個名字很可愛,但第一次看到有點問號的東西:
Event Bubbling(事件冒泡)
HTML:
<div class="outer">
外層
<button class="btn">
點哈納
</button>
</div>
JavaScript:
const outer = document.querySelector(".outer");
const btn = document.querySelector(".btn");
outer.addEventListener("click", function () {
console.log("外層也被點到了!");
});
btn.addEventListener("click", function () {
console.log("哈納被點到了!");
});
現在按一下按鈕。
原本以為只會看到:
哈納被點到了!
結果 Console:
哈納被點到了!
外層也被點到了!
我:
?????
我明明點的是哈納,
外層你是在湊什麼熱鬧啦 XD
當我點下按鈕時,
事件會先發生在被點擊的元素上,
接著再一路往外層傳。
大概像這樣:
button
↓
div
↓
body
↓
document
所以才叫「冒泡」。
有點像一顆泡泡從裡面慢慢浮出去。
又或者可以理解成:
哈納一被點,整棟樓都知道了。
消息真的傳超快 XD
如果今天只想讓按鈕自己處理,
不想讓外層也一起收到事件,
可以使用:
event.stopPropagation();
改成:
btn.addEventListener("click", function (event) {
event.stopPropagation();
console.log("哈納被點到了!");
});
再點一次。
這次就只會出現:
哈納被點到了!
外層終於安靜了。
很好,不要什麼事情都到處廣播。
一開始看到事件冒泡,
第一反應很容易是:
怎麼把它關掉???
但其實它也滿有用的。
例如今天有很多按鈕:
<div class="cats">
<button>哈納</button>
<button>小橘</button>
<button>布丁</button>
</div>
如果每個按鈕都分別加:
addEventListener()
三個還好。
如果有 100 個呢?
……
又來了。
JavaScript 怎麼一天到晚想逼我複製貼上 ==
可以把事件監聽放在外層:
const cats = document.querySelector(".cats");
cats.addEventListener("click", function (event) {
console.log(event.target.textContent);
});
現在不管點:
哈納、
小橘、
還是布丁,
都可以由 .cats 統一接到事件。
其中:
event.target
就是實際被點到的那個元素。
所以點哈納:
哈納
點布丁:
布丁
這種做法就是很常聽到的:
Event Delegation(事件代理)
簡單來說:
小孩很多,不要每個都自己請人顧,直接交給家長統一處理 XD
事件會從被操作的元素一路往外層傳。
裡面 → 外面
利用事件冒泡,
把事件監聽放在共同的父元素上,
再透過:
event.target
確認到底是誰被點到。
昨天才剛覺得:
addEventListener 好像沒那麼難嘛。
今天就馬上發現,
原來「點一下」後面還藏著一堆事情。
一開始還很嫌棄事件冒泡:
誰叫你把事情講出去的???
結果後來才發現,
它居然還可以拿來做事件代理。
好啦。
今天先不怪你。
原來你只是比較愛傳話而已 XD
Day 20,完成!