本意是講 react 事件機(jī)制的,但仔細(xì)想想..我連瀏覽器本身的事件機(jī)制也不是十分清晰
事件傳播
事件傳播的三個(gè)階段:捕獲囱皿,目標(biāo)對(duì)象,冒泡耕渴。
1.其中捕獲(Capture)是 事件對(duì)象(event object) 從 window 派發(fā)到 目標(biāo)對(duì)象父級(jí)的過(guò)程齿兔。
2.目標(biāo)(Target)階段是 事件對(duì)象派發(fā)到目標(biāo)元素時(shí)的階段,如果事件類(lèi)型指示其不冒泡添诉,那事件傳播將在此階段終止医寿。
3.冒泡(Bubbling)階段 和捕獲相反栏赴,是以目標(biāo)對(duì)象父級(jí)到 window 的過(guò)程靖秩。
在任一階段調(diào)用 stopPropagation 都將終止本次事件的傳播竖瘾。
window.addEventListener('click',function (event) {
console.log(event)
},true)
note:
addEventListener
形式注冊(cè)的監(jiān)聽(tīng)事件接受參數(shù)以指定是否在捕獲階段觸發(fā)本次事件花颗,默認(rèn)值為否(既冒泡階段)。以事件處理器注冊(cè)的事件在非捕獲階段觸發(fā)庸论。
點(diǎn)擊視窗的內(nèi)任一元素棒呛,輸出 MouseEvent 對(duì)象。查看對(duì)象的 path 屬性条霜,既該對(duì)象的傳播路徑涵亏。
阻止冒泡和默認(rèn)事件
-
調(diào)用
stopPropagation
嚴(yán)格來(lái)說(shuō)不是阻止冒泡气筋,是阻止事件傳播,捕獲階段也可以直接阻止宠默。
image.png 事件接口還有一個(gè)
cancelBubble
因歷史原因的 stopPropagation 的別名,給其賦值 true 可以達(dá)到調(diào)用 stopPropagation 同樣的效果抹沪。或者你在事件處理器(通過(guò)
on...
屬性注冊(cè))的回調(diào)返回 true瓤球,這個(gè)返回值決定了事件是否被取消,這里的取消的作用要根據(jù)事件的類(lèi)型而定卦羡。
element.onclick = function () { return true}
- 調(diào)用
preventDefault
則是阻止默認(rèn)事件。
注: jQuery 注冊(cè)事件時(shí)返回 false 是一種用于同時(shí)調(diào)用 e.preventDefault 和 e.stopPropagation 的快捷方式欠肾。
事件回調(diào)
addEventListener()
- on-event 事件處理器
這里主要提我自己平常沒(méi)重視的地方~ 例如:
1.回調(diào)函數(shù)的this
被設(shè)置為注冊(cè)該事件的 DOM 元素拟赊。
2.混用時(shí)的調(diào)用順序。
首次設(shè)定 事件處理器 為非 null 值時(shí)的順序虏肾,就是該事件處理器的值被調(diào)用的順序。
<button id="test" >Start Demo</button>
<script>
var button = document.getElementById('test');
button.addEventListener('click', function () { alert('ONE') }, false);
button.setAttribute('onclick', "alert('NOT CALLED')"); // event handler listener is registered here
button.addEventListener('click', function () { alert('THREE') }, false);
button.onclick = function () { alert('TWO'); };
button.addEventListener('click', function () { alert('FOUR') }, false);
</script>
//alert 順序 one 封豪、two 、three第步、 four
推薦閱讀:
從Chrome源碼看瀏覽器的事件機(jī)制