冒泡事件(Bubbling Event)是指在DOM樹中從子元素向父元素逐級(jí)觸發(fā)的一種事件傳遞方式。大多數(shù)情況下,冒泡事件具有很好的靈活性和可擴(kuò)展性,但是也存在一些特殊情況,這些情況下事件不支持冒泡。
一、哪些事件不支持冒泡?
雖然大部分的事件都支持冒泡,但存在一些事件是不支持冒泡的。以下是一些常見的不支持冒泡的事件:
-
focus和blur事件
load和unload事件
input、select和change事件
submit和reset事件
scroll事件
mouseenter和mouseleave事件
contextmenu事件
二、事件示例
為了更好地理解冒泡事件的局限性,下面針對(duì)每個(gè)不支持冒泡的事件給出具體的代碼示例,以便更好地理解:
- focus和blur事件
focus和blur事件是用于處理元素獲取或失去焦點(diǎn)的事件。這些事件不支持冒泡,意味著當(dāng)你在子元素上觸發(fā)focus或blur事件時(shí),不會(huì)觸發(fā)父元素上的相應(yīng)事件。
HTML代碼:
<div> <input type="text" id="myInput"> </div>
登錄后復(fù)制
JavaScript代碼:
const myInput = document.getElementById('myInput'); myInput.addEventListener('focus', function() { console.log('Input獲得焦點(diǎn)'); }); const myDiv = document.querySelector('div'); myDiv.addEventListener('focus', function() { console.log('Div獲得焦點(diǎn)'); });
登錄后復(fù)制
結(jié)果:
當(dāng)文本框獲得焦點(diǎn)時(shí),只會(huì)在控制臺(tái)輸出”Input獲得焦點(diǎn)”,而不會(huì)輸出”Div獲得焦點(diǎn)”。因?yàn)閒ocus事件沒有冒泡到父元素div。
- load和unload事件
load和unload事件是在頁面或資源加載完成后觸發(fā)的事件。這些事件不支持冒泡,也就是說當(dāng)子元素上觸發(fā)load或unload事件時(shí),不會(huì)觸發(fā)父元素上的相應(yīng)事件。
HTML代碼:
<div> <img src="image.png" id="myImage"> </div>
登錄后復(fù)制
JavaScript代碼:
const myImage = document.getElementById('myImage'); myImage.addEventListener('load', function() { console.log('圖片加載完成'); }); const myDiv = document.querySelector('div'); myDiv.addEventListener('load', function() { console.log('Div加載完成'); });
登錄后復(fù)制
結(jié)果:
當(dāng)圖片加載完成時(shí),只會(huì)在控制臺(tái)輸出”圖片加載完成”,而不會(huì)輸出”Div加載完成”。因?yàn)閘oad事件沒有冒泡到父元素div。
- input、select和change事件
input、select和change事件是用于處理表單元素值改變的事件。這些事件只作用于實(shí)際發(fā)生值改變的元素,不會(huì)冒泡到父元素。
HTML代碼:
<input type="text" id="myInput">
登錄后復(fù)制
JavaScript代碼:
const myInput = document.getElementById('myInput'); myInput.addEventListener('input', function() { console.log('輸入框值改變'); }); const myForm = document.querySelector('form'); myForm.addEventListener('input', function() { console.log('表單值改變'); });
登錄后復(fù)制
結(jié)果:
當(dāng)輸入框的值改變時(shí),只會(huì)在控制臺(tái)輸出”輸入框值改變”,而不會(huì)輸出”表單值改變”。因?yàn)閕nput事件沒有冒泡到父元素form。
- submit和reset事件
submit和reset事件是在提交和重置表單時(shí)觸發(fā)的事件。這些事件只能應(yīng)用于form元素本身,不會(huì)冒泡到父元素。
HTML代碼:
<form id="myForm"> <input type="submit" value="提交"> </form>
登錄后復(fù)制
JavaScript代碼:
const myForm = document.getElementById('myForm'); myForm.addEventListener('submit', function(event) { event.preventDefault(); console.log('表單已提交'); }); const myDiv = document.querySelector('div'); myDiv.addEventListener('submit', function() { console.log('Div提交'); });
登錄后復(fù)制
結(jié)果:
當(dāng)點(diǎn)擊提交按鈕時(shí),只會(huì)在控制臺(tái)輸出”表單已提交”,而不會(huì)輸出”Div提交”。因?yàn)閟ubmit事件沒有冒泡到父元素div。注意到例子中我們通過event.preventDefault()方法阻止了表單的默認(rèn)提交行為。
- scroll事件
scroll事件是在發(fā)生滾動(dòng)時(shí)觸發(fā)的事件。這個(gè)事件不支持冒泡,也就是說當(dāng)滾動(dòng)一個(gè)元素時(shí),不會(huì)觸發(fā)父元素上的scroll事件。
HTML代碼:
<div style="height: 100px; width: 100px; overflow: auto;"> <p>這是一段很長(zhǎng)的文本</p> </div>
登錄后復(fù)制
JavaScript代碼:
const myDiv = document.querySelector('div'); myDiv.addEventListener('scroll', function() { console.log('滾動(dòng)'); });
登錄后復(fù)制
結(jié)果:
當(dāng)滾動(dòng)div時(shí),只會(huì)在控制臺(tái)輸出”滾動(dòng)”,而不會(huì)冒泡到上層元素。
- mouseenter和mouseleave事件
mouseenter和mouseleave事件是在鼠標(biāo)進(jìn)入和離開元素時(shí)觸發(fā)的事件。這些事件不支持冒泡,也就是說當(dāng)鼠標(biāo)進(jìn)入或離開一個(gè)元素時(shí),不會(huì)觸發(fā)父元素上的相應(yīng)事件。
HTML代碼:
<div id="myDiv" style="background-color: yellow; width: 100px; height: 100px;"> <p>鼠標(biāo)進(jìn)入這個(gè)div</p> </div>
登錄后復(fù)制
JavaScript代碼:
const myDiv = document.getElementById('myDiv'); myDiv.addEventListener('mouseenter', function() { console.log('鼠標(biāo)進(jìn)入div'); }); const myBody = document.querySelector('body'); myBody.addEventListener('mouseenter', function() { console.log('鼠標(biāo)進(jìn)入body'); });
登錄后復(fù)制
結(jié)果:
當(dāng)鼠標(biāo)進(jìn)入div時(shí),只會(huì)在控制臺(tái)輸出”鼠標(biāo)進(jìn)入div”,而不會(huì)輸出”鼠標(biāo)進(jìn)入body”。
- contextmenu事件
contextmenu事件是在鼠標(biāo)右鍵點(diǎn)擊時(shí)觸發(fā)的事件。這個(gè)事件并不支持冒泡,也就是說當(dāng)右鍵點(diǎn)擊一個(gè)元素時(shí),不會(huì)觸發(fā)父元素上的contextmenu事件。
HTML代碼:
<div id="myDiv" style="background-color: yellow; width: 100px; height: 100px;"></div>
登錄后復(fù)制
JavaScript代碼:
const myDiv = document.getElementById('myDiv'); myDiv.addEventListener('contextmenu', function(event) { event.preventDefault(); console.log('右鍵點(diǎn)擊'); }); const myBody = document.querySelector('body'); myBody.addEventListener('contextmenu', function() { console.log('右鍵點(diǎn)擊body'); });
登錄后復(fù)制
結(jié)果:
當(dāng)右鍵點(diǎn)擊div時(shí),只會(huì)在控制臺(tái)輸出”右鍵點(diǎn)擊”,而不會(huì)輸出”右鍵點(diǎn)擊body”。注意到例子中我們通過event.preventDefault()方法阻止了默認(rèn)的上下文菜單顯示。
三、總結(jié)
冒泡事件是DOM樹中子元素向父元素逐級(jí)觸發(fā)的一種事件傳遞方式,大部分的事件都支持冒泡,但也存在一些不支持冒泡的特殊事件。本文通過具體的代碼示例分析了不支持冒泡的事件,希望能對(duì)讀者理解冒泡事件的局限性有所幫助。