更新時間:2022-10-31 09:30:57 來源:動力節(jié)點 瀏覽1226次
一個事件的生命周期分為三個階段:捕獲、目標(biāo)和冒泡。
當(dāng)一個事件被觸發(fā)時,瀏覽器會識別出與該事件相關(guān)的元素,該元素被稱為事件的目標(biāo)。
瀏覽器識別 body 元素和 target 之間的所有元素,并檢查每個元素以查看它們是否有任何事件處理程序要求通知其后代的事件。
瀏覽器在觸發(fā)目標(biāo)本身的處理程序之前觸發(fā)任何此類處理程序。
下面是代碼。
讓香蕉=文檔.getElementById(“香蕉”);
讓textblock = document .getElementById( "block1" );
香蕉.addEventListener(“鼠標(biāo)懸停”,handleMouseEvent);
香蕉.addEventListener( "mouseout" ,handleMouseEvent);
textblock.addEventListener( "mouseover" , handleDescendantEvent, true);
textblock.addEventListener( "mouseout" , handleDescendantEvent, true);
函數(shù)handleDescendantEvent(e) {
if (e.type == "mouseover" && e.eventPhase == Event.CAPTURING_PHASE) {
e.target.style.border = "厚實紅色" ;
e.currentTarget.style.border = "厚雙黑" ;
} else if (e.type == "mouseout" && e.eventPhase == Event.CAPTURING_PHASE) {
e.target.style.removeProperty( "border" );
e.currentTarget.style.removeProperty( "border" );
} / * w w w 。d e m o 2秒。厘米* / _ _
}
函數(shù)handleMouseEvent(e) {
if (e.type == "mouseover" ) {
e.target.style.background= '白色' ;
e.target.style.color= '黑色' ;
} 別的 {
e.target.style.removeProperty( 'color' );
e.target.style.removeProperty( '背景' );
}
}
< ! DOCTYPE HTML > < html > < head > < style type= "text/css" > p { < ! - - w w w 。d e m o 2秒。c o m - - >背景:灰色;
顏色:白色;
填充:10px;
邊距:5px;
邊框:細(xì)實黑色
}
跨度{
背景:白色;
顏色:黑色;
填充:2px;
光標(biāo):默認(rèn);
}
</style>
</head>
< body >
< p id = "block1" >
test < span id = "banana" >香蕉</span> test
</p>
<腳本類型= “文本/javascript” >
讓香蕉=文檔.getElementById(“香蕉”);
讓 textblock = document .getElementById( "block1" );
香蕉.addEventListener(“鼠標(biāo)懸停”,handleMouseEvent);
香蕉.addEventListener( "mouseout" ,handleMouseEvent);
textblock.addEventListener( "鼠標(biāo)懸停" ,
處理后代事件,真);
textblock.addEventListener( "mouseout" ,
處理后代事件,真);
函數(shù)句柄后代事件(e){
if (e.type == "鼠標(biāo)懸停" &&
e.eventPhase == Event.CAPTURING_PHASE) {
e.目標(biāo)。風(fēng)格。邊框= “厚實的紅色”;
e.當(dāng)前目標(biāo)。風(fēng)格。邊框= “厚雙黑”;
} else if (e.type == "mouseout" &&
e.eventPhase == Event.CAPTURING_PHASE) {
e.目標(biāo)。樣式.removeProperty( "邊框" );
e.當(dāng)前目標(biāo)。樣式.removeProperty( "邊框" );
}
}
函數(shù)句柄鼠標(biāo)事件(e){
如果(e.type == “鼠標(biāo)懸停”){
e.目標(biāo)。風(fēng)格。背景= '白色' ;
e.目標(biāo)。風(fēng)格。顏色= '黑色' ;
} 別的 {
e.目標(biāo)。樣式.removeProperty( 'color' );
e.目標(biāo)。樣式.removeProperty( '背景' );
}
}
</script>
</body>
</html>
在這個例子中,我們定義了一個<span>元素作為 p 元素的子元素,并為mouseover和mouseout事件注冊了處理程序。
請注意,當(dāng)我們向父元素(p 元素)注冊時,我們向addEventListener () 方法添加了第三個參數(shù),如下所示:
textblock.addEventListener( "mouseover" , handleDescendantEvent, true);
這個附加參數(shù)告訴瀏覽器我們希望<p>元素在捕獲階段接收其后代元素的事件。
當(dāng) mouseover 事件被觸發(fā)時,瀏覽器從 HTML 文檔的根開始,并開始沿著 DOM 向下移動到目標(biāo),即觸發(fā)事件的元素。
對于層次結(jié)構(gòu)中的每個元素,瀏覽器都會檢查它是否已經(jīng)注冊了對捕獲事件的興趣。
在每個元素處,瀏覽器都會調(diào)用任何啟用了捕獲的偵聽器。
在這種情況下,瀏覽器會找到并調(diào)用我們在<p>元素中注冊 的handleDescendantEvent () 函數(shù)。
當(dāng)調(diào)用handleDescendantEvent () 函數(shù)時,Event對象通過target 屬性包含有關(guān)目標(biāo)元素的信息,以及通過 currentTarget屬性導(dǎo)致調(diào)用該函數(shù)的元素的信息。
我們使用這兩個屬性,以便我們可以更改 p 元素和 span 子元素的樣式。
事件捕獲使每個元素的祖先有機(jī)會在將事件傳遞給元素本身之前對其做出反應(yīng)。
父元素事件處理程序可以通過在 Event 對象上調(diào)用stopPropagation () 或stopImmediatePropagation () 函數(shù)來停止事件向下流向目標(biāo)。
stopPropagation () 將確保為當(dāng)前元素注冊的所有事件偵聽器都將被調(diào)用,而stopImmediatePropagation () 將忽略任何未觸發(fā)的偵聽器。
以下代碼顯示了將 stopPropagation 函數(shù)添加到 handleDescendantEvent () 事件處理程序。
防止進(jìn)一步的事件流。
...
函數(shù)handleDescendantEvent(e) {
if (e.type == "mouseover" && e.eventPhase == Event.CAPTURING_PHASE) {
e.target.style.border = "厚實紅色" ;
e.currentTarget.style.border = "厚雙黑" ;
} else if (e.type == "mouseout" && e.eventPhase == Event.CAPTURING_PHASE) {
e.target.style.removeProperty( "border" );
e.currentTarget.style.removeProperty( "border" );
}
e.stopPropagation();
}
...
< ! DOCTYPE HTML > < html > < head > < style type= "text/css" > p { < ! - - w w w 。d e m o 2秒。c o m - - >背景:灰色;
顏色:白色;
填充:10px;
邊距:5px;
邊框:細(xì)實黑色
}
跨度{
背景:白色;
顏色:黑色;
填充:2px;
光標(biāo):默認(rèn);
}
</style>
</head>
< body >
< p id = "block1" >
test < span id = "banana" >香蕉</span> test
</p>
<腳本類型= “文本/javascript” >
讓香蕉=文檔.getElementById(“香蕉”);
讓 textblock = document .getElementById( "block1" );
香蕉.addEventListener(“鼠標(biāo)懸停”,handleMouseEvent);
香蕉.addEventListener( "mouseout" ,handleMouseEvent);
textblock.addEventListener( "鼠標(biāo)懸停" ,
處理后代事件,真);
textblock.addEventListener( "mouseout" ,
處理后代事件,真);
函數(shù)句柄后代事件(e){
if (e.type == "鼠標(biāo)懸停" &&
e.eventPhase == Event.CAPTURING_PHASE) {
e.目標(biāo)。風(fēng)格。邊框= “厚實的紅色”;
e.當(dāng)前目標(biāo)。風(fēng)格。邊框= “厚雙黑”;
} else if (e.type == "mouseout" &&
e.eventPhase == Event.CAPTURING_PHASE) {
e.目標(biāo)。樣式.removeProperty( "邊框" );
e.當(dāng)前目標(biāo)。樣式.removeProperty( "邊框" );
}
e.stopPropagation();
}
函數(shù)句柄鼠標(biāo)事件(e){
如果(e.type == “鼠標(biāo)懸停”){
e.目標(biāo)。風(fēng)格。背景= '白色' ;
e.目標(biāo)。風(fēng)格。顏色= '黑色' ;
} 別的 {
e.目標(biāo)。樣式.removeProperty( 'color' );
e.目標(biāo)。樣式.removeProperty( '背景' );
}
}
</script>
</body>
</html>
通過此更改,瀏覽器捕獲階段在調(diào)用 p 元素上的處理程序時結(jié)束。
不會檢查其他元素,并且將跳過目標(biāo)和冒泡階段。
就示例而言,這意味著將不會應(yīng)用 handleMouseEvent () 函數(shù)中的樣式更改以響應(yīng)鼠標(biāo)懸停事件。
請注意,在處理程序中,我們檢查事件類型并使用 eventPhase 屬性確定事件處于哪個階段,如下所示:
...
if (e.type == "mouseover" && e.eventPhase == Event.CAPTURING_PHASE) {
...
在注冊事件偵聽器時啟用捕獲事件不會停止針對元素本身的事件。
在這種情況下,p 元素會占用瀏覽器屏幕上的空間,并且也會響應(yīng) mouseover 事件。
為避免這種情況,我們檢查以確保僅在處理處于捕獲階段的事件時應(yīng)用樣式更改。
以后代元素為目標(biāo)的事件,我們只處理這些事件,因為我們已經(jīng)注冊了一個啟用捕獲的偵聽器。
初級 202925
初級 203221
初級 202629
初級 203743