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