DOM 事件與事件委托
本文寫于 2020 年 5 月 28 日
先思考一個問題:我們如何給一百個 button 添加點擊事件?
遍歷?
那豈不是要添加一百個監聽器?
這就需要事件委托了,
其實這根本不是一個很難的概念,看下去,本文并不長,
1. 點擊事件
現在我們擁有三個元素,他們嵌套成為爺爺、爸爸、兒子:
<div class='grandpa'>
<div class='father'>
<div class='son'></div>
</div>
</div>
然后分別給他們仨添加不同的三個事件監聽,
因為事件冒泡,我們能知道他們都會執行,并且會按照一定順序執行,
但是不同瀏覽器的順序是不一樣的,
IE 認為應該呼叫 .son 的事件,網景認為應該呼叫 .grandpa,
后來 2002 年,W3C 發布了標準:
- 先按照從外向內——事件捕獲;
- 在按照從內向外——事件冒泡,
整個程序就是——有監聽函式就呼叫,沒有就跳過,
開發者可以自己選擇把最外層的事件,放在捕獲階段還是冒泡階段,
如何選擇呢?其實就是我們最熟悉的addEventListener,
我們經常會用它去系結事件,我們一般都只會傳入兩個引數,
可實際上這個函式有 3 個引數,
我們可以在第三個引數,放置一個布林值,例如:xxx.addEventListener('click', fn, bool)
如果是true,則是捕獲方式(從外向內);如果不寫,或者是falsy值,則是冒泡(從內向外),
順序問題
上面說了,先捕獲后冒泡,
那我同時給一個元素,先掛一個冒泡,再掛一個捕獲——誰先觸發?
誰先寫,誰先觸發,因為他們是同級的!
可以取消嗎?
捕獲不可以取消,但是冒泡可以取消,(有些事件不能取消,比如滾動事件)
e.stopPropagation()中斷冒泡,
2. 事件委托
回到我們剛開始的問題:我們如何給一百個 button 添加點擊事件?
肯定不是遍歷,
我們可以直接給父元素添加事件,例如:
father.addEventListener('click', e => {
console.log(e.target)
console.log(e.currentTarget)
})
這里看到,我們傳入了一個 e,這個 e 可以嘗試列印出來,就會發現其實是MouseEvent,
這是一個物件,里面有各種各樣的資料,比如我們需要的target,
target就是用戶所點擊的元素!
也就是說如果 father 有 10 個孩子,從 child1 一直到 child10,我們點誰,這個 target 就是誰,
而e.currentTarget呢,和e.target是有區別的!
簡單來說呢 target 是被操作的元素,currentTarget 是被監聽的元素,
在這個例子中,currentTarget 恒為 father,target 則會隨著點擊發生改變,
最后說一下,JS 其實是不支持事件的!支持事件的是瀏覽器,addEventListener 是瀏覽器的 DOM 提供的,
(完)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/79789.html
標籤:JavaScript
下一篇:JavaScript 的 物件
