前言
在當(dāng)今數(shù)字時代,前端技術(shù)正日益成為塑造用戶體驗(yàn)的關(guān)鍵。而其中一個不可或缺的核心概念就是
JavaScript的事件模型
?;蛟S你是剛踏入前端領(lǐng)域的小白,或者是希望深入了解事件模型的開發(fā)者,不論你的經(jīng)驗(yàn)如何,本篇博客都將帶你揭開事件模型的神秘面紗。
?? 作者簡介:程序員小豪,全棧工程師,熱愛編程,曾就職于蔚來、騰訊,現(xiàn)就職于某互聯(lián)網(wǎng)大廠,技術(shù)棧:Vue、React、Python、Java
?? 本文收錄于小豪的前端系列專欄,后續(xù)還會更新前端入門以及前端面試的一些相關(guān)文章,手把手帶你從零學(xué)習(xí)前端到面試找工作,并如果有想進(jìn)入前端領(lǐng)域工作的同學(xué),這個前端專欄會對你有所幫助,歡迎關(guān)注起來呀
?? 本人也會持續(xù)的去關(guān)注AIGC以及人工智能領(lǐng)域
的一些動向并總結(jié)到博客中,大家感興趣的可以關(guān)注一下我的人工智能專欄
?? 云原生的入門學(xué)習(xí)系列,大家有興趣的可以看一看
1.事件與事件流
javascript
中的事件,可以理解就是在HTML
文檔或者瀏覽器中發(fā)生的一種交互操作,使得網(wǎng)頁具備互動性, 常見的有加載事件、鼠標(biāo)事件、自定義事件等
由于DOM
是一個樹結(jié)構(gòu),如果在父子節(jié)點(diǎn)綁定事件時候,當(dāng)觸發(fā)子節(jié)點(diǎn)的時候,就存在一個順序問題,這就涉及到了事件流的概念
事件流都會經(jīng)歷三個階段:
- 事件捕獲階段(capture phase)
- 處于目標(biāo)階段(target phase)
- 事件冒泡階段(bubbling phase)
事件冒泡是一種從下往上的傳播方式,由最具體的元素(觸發(fā)節(jié)點(diǎn))然后逐漸向上傳播到最不具體的那個節(jié)點(diǎn),也就是DOM中最高層的父節(jié)點(diǎn)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件冒泡</title>
</head>
<body>
<button id="clickMe">按鈕</button>
</body>
</html>
然后,我們給button和它的父元素,加入點(diǎn)擊事件
var button = document.getElementById('clickMe');
button.onclick = function() {
console.log('1.Button');
};
document.body.onclick = function() {
console.log('2.body');
};
document.onclick = function() {
console.log('3.document');
};
window.onclick = function() {
console.log('4.window');
};
最后得到的輸出如下:
點(diǎn)擊事件首先在button元素上發(fā)生,然后逐級向上傳播
事件捕獲與事件冒泡相反,事件最開始由不太具體的節(jié)點(diǎn)最早接受事件, 而最具體的節(jié)點(diǎn)(觸發(fā)節(jié)點(diǎn))最后接受事件
2. 事件模型
事件模型可以分為三種:
- 原始事件模型(DOM0級)
- 標(biāo)準(zhǔn)事件模型(DOM2級)
- IE事件模型(基本不用)
原始事件模型
原始事件模型(DOM0級事件模型)是事件綁定的最簡單方式,適用于那些想要快速添加事件監(jiān)聽的場景。這種模型有兩種綁定方式:直接在HTML代碼中綁定和通過JS代碼綁定。讓我們來看看它們的特點(diǎn)和應(yīng)用。
HTML中直接綁定事件
<input type="button" onclick="fun()">
通過JS代碼綁定事件
var btn = document.getElementById('btn');
btn.onclick = fun;
原始事件模型的特點(diǎn):
- 綁定速度快: 原始事件模型綁定速度非??欤部赡芤?yàn)榻壎ㄟ^于迅速,導(dǎo)致事件無法在頁面完全加載時執(zhí)行。
- 僅支持冒泡: 原始事件模型只支持事件冒泡,不支持捕獲。
- 同類型事件只能綁定一次: 如果嘗試為同一個元素綁定多個同類型事件,后綁定的事件會覆蓋之前的事件。
<input type="button" id="btn" onclick="fun1()">
var btn = document.getElementById('btn');
btn.onclick = fun2;
對于上面的情況,嘗試為同一個按鈕綁定兩個點(diǎn)擊事件時,后綁定的事件會覆蓋之前的事件。
要刪除DOM0級事件處理程序,只需將對應(yīng)的事件屬性置為null
即可。
btn.onclick = null;
標(biāo)準(zhǔn)事件模型
標(biāo)準(zhǔn)事件模型(DOM2級事件模型)是更加強(qiáng)大和靈活的事件處理方式。在標(biāo)準(zhǔn)事件模型中,一個事件共有三個階段:捕獲階段、處理階段和冒泡階段。讓我們深入了解標(biāo)準(zhǔn)事件模型的特點(diǎn)和使用方法。
事件捕獲階段、處理階段和冒泡階段
-
事件捕獲階段: 事件從
document
向下傳播到目標(biāo)元素,檢查經(jīng)過的節(jié)點(diǎn)是否綁定了事件監(jiān)聽函數(shù),如果有則執(zhí)行。 - 事件處理階段: 事件到達(dá)目標(biāo)元素,觸發(fā)目標(biāo)元素的監(jiān)聽函數(shù)。
-
事件冒泡階段: 事件從目標(biāo)元素冒泡回
document
,依次檢查經(jīng)過的節(jié)點(diǎn)是否綁定了事件監(jiān)聽函數(shù),如果有則執(zhí)行。
在標(biāo)準(zhǔn)事件模型中,事件綁定和移除監(jiān)聽函數(shù)的方式如下:
addEventListener(eventType, handler, useCapture);
removeEventListener(eventType, handler, useCapture);
標(biāo)準(zhǔn)事件模型的特點(diǎn):
- 支持多個事件處理器: 在一個DOM元素上可以綁定多個事件處理器,它們不會相互沖突。
btn.addEventListener('click', showMessage1, false);
btn.addEventListener('click', showMessage2, false);
btn.addEventListener('click', showMessage3, false);
-
執(zhí)行時機(jī):
useCapture
參數(shù)設(shè)置為true
時,在捕獲階段執(zhí)行監(jiān)聽函數(shù);設(shè)置為false
時,在冒泡階段執(zhí)行監(jiān)聽函數(shù)。
通過以下例子,我們可以更好地理解事件處理階段的執(zhí)行時機(jī):
<div id='div'>
<p id='p'>
<span id='span'>點(diǎn)擊我!</span>
</p >
</div>
設(shè)置點(diǎn)擊事件:
var div = document.getElementById('div');
var p = document.getElementById('p');
function onClickFn (event) {
var tagName = event.currentTarget.tagName;
var phase = event.eventPhase;
console.log(tagName, phase);
}
div.addEventListener('click', onClickFn, false);
p.addEventListener('click', onClickFn, false);
點(diǎn)擊"點(diǎn)擊我!"后,輸出如下:
P 3
DIV 3
我們可以看到,p
和div
都在冒泡階段響應(yīng)了事件,由于冒泡的特性,內(nèi)部的p
先于外層的div
作出了響應(yīng)。
如果我們將useCapture
參數(shù)改為true
:
div.addEventListener('click', onClickFn, true);
p.addEventListener('click', onClickFn, true);
輸出如下:
DIV 1
P 1
兩者在捕獲階段響應(yīng)事件,因此div
會先于p
作出響應(yīng)。
IE事件模型
IE事件模型共有兩個過程:
- 事件處理階段:事件到達(dá)目標(biāo)元素, 觸發(fā)目標(biāo)元素的監(jiān)聽函數(shù)。
- 事件冒泡階段:事件從目標(biāo)元素冒泡到
document
, 依次檢查經(jīng)過的節(jié)點(diǎn)是否綁定了事件監(jiān)聽函數(shù),如果有則執(zhí)行
事件綁定監(jiān)聽函數(shù)的方式如下:
attachEvent(eventType, handler)
事件移除監(jiān)聽函數(shù)的方式如下:
detachEvent(eventType, handler)
舉個例子:文章來源:http://www.zghlxwxcb.cn/news/detail-648336.html
var btn = document.getElementById('.btn');
btn.attachEvent(‘onclick’, showMessage);
btn.detachEvent(‘onclick’, showMessage);
總結(jié)
在本篇博客中,我們一起探索了JavaScript事件模型的四大概念:事件與事件流、原始事件模型、標(biāo)準(zhǔn)事件模型、IE事件模型。JavaScript是一門非常強(qiáng)大且廣泛應(yīng)用的編程語言。掌握了這些基本的語法和概念,你已經(jīng)具備了入門JavaScript編程的基礎(chǔ)。未來,你將能夠創(chuàng)建更加交互性的網(wǎng)頁,實(shí)現(xiàn)更多驚艷的動態(tài)效果,甚至搭建出屬于自己的Web應(yīng)用。但這只是一個開始,還有許多更深入的主題等待你去探索。
后續(xù)我們這個前端專欄還會講述作用域、事件模型、內(nèi)置對象、垃圾回收、js算法技巧、Vue入門實(shí)戰(zhàn)、React實(shí)戰(zhàn)、前端面試題等等文章,如果您感興趣的話,歡迎點(diǎn)贊三連并關(guān)注我以及我的前端專欄,我們下期文章再見。文章來源地址http://www.zghlxwxcb.cn/news/detail-648336.html
到了這里,關(guān)于【前端|Javascript第4篇】詳解Javascript的事件模型:小白也能輕松搞懂!的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!