DOM事件的傳播機制

DOM事件的傳播機制是指當一個事件在DOM樹中觸發時,它是如何在各個元素之間傳播的。DOM事件傳播機制分為三個階段:捕獲階段、目標階段和冒泡階段。此外,還有一種常用的技術稱為事件委托,它能夠簡化事件處理程序的綁定和管理。本文將詳細介紹這些概念,并提供相應的代碼示例。

事件與事件流

在介紹事件傳播機制之前,我們先來了解一下什么是事件和事件流。在DOM中,事件是指用戶與頁面交互時發生的動作,比如點擊、鼠標移動等。而事件流則是指這些事件在DOM樹中傳播的路徑。

每次用戶與一個網頁進行交互,例如點擊鏈接,按下一個按鍵或者移動鼠標時,就會觸發一個事件。我們的程序可以檢測這些事件,然后對此作出響應。從而形成一種交互。

這樣可以使我們的頁面變得更加的有意思,而不僅僅像以前一樣只能進行瀏覽。

JavaScript 中采用一個叫做事件監聽器的東西來監聽事件是否發生。這個事件監聽器類似于一個通知,當事件發生時,事件監聽器會讓我們知道,然后程序就可以做出相應的響應。

通過這種方式,就可以避免讓程序不斷地去檢查事件是否發生,讓程序在等待事件發生的同時,可以繼續做其他的任務。

標準 DOM 事件流

DOM事件流是指在DOM樹中,事件從最外層的節點開始傳播,逐級向下,直到達到目標節點,然后再從目標節點向上傳播到最外層的節點。

DOM事件流分為三個階段:捕獲階段、目標階段和冒泡階段。

  1. 捕獲階段:事件從最外層的節點開始傳播,逐級向下,直到達到目標節點。在捕獲階段中,事件會依次觸發每個經過的節點上綁定的捕獲型事件處理函數。
  2. 目標階段:事件達到目標節點后,在目標節點上觸發綁定的事件處理函數。在這個階段中,只會觸發目標節點上綁定的事件處理函數。
  3. 冒泡階段:事件從目標節點開始向上傳播,逐級向上,直到達到最外層的節點。在冒泡階段中,事件會依次觸發每個經過的節點上綁定的冒泡型事件處理函數。

在實際應用中,默認情況下大部分DOM事件都是按照冒泡方式進行傳播。但是也可以通過調用addEventListener方法時傳入第三個參數為true來將其設置為捕獲方式進行傳播。

總結起來,DOM事件流就是指從最外層的節點開始傳播,逐級向下到達目標節點,然后再從目標節點向上傳播到最外層的節點的過程。這個過程分為捕獲階段、目標階段和冒泡階段。

下面是一個示例,演示了標準 DOM 事件流的傳播順序:

 
<div id="outer"><div id="inner"><button id="btn">點擊我</button></div>
</div>

 
const outer = document.getElementById('outer');
const inner = document.getElementById('inner');
const btn = document.getElementById('btn');outer.addEventListener('click', function() {console.log('外層元素被點擊');
}, true);inner.addEventListener('click', function() {console.log('內層元素被點擊');
}, true);btn.addEventListener('click', function() {console.log('按鈕被點擊');
});

當我們點擊按鈕時,控制臺會輸出以下內容:

外層元素被點擊 內層元素被點擊 按鈕被點擊

可以看到,事件首先在捕獲階段從外層元素開始傳播,然后到達目標元素,最后在冒泡階段從目標元素向上冒泡。

事件冒泡流

事件冒泡是指在DOM樹中,事件從目標元素開始向上冒泡傳播的過程。也就是說,在冒泡階段,事件會依次觸發父級元素的相同類型事件處理程序。

下面是一個示例,演示了事件冒泡的過程:

 
<div id="outer"><div id="inner"><button id="btn">點擊我</button></div>
</div>

const outer = document.getElementById('outer');
const inner = document.getElementById('inner');
const btn = document.getElementById('btn');outer.addEventListener('click', function() {console.log('外層元素被點擊');
});inner.addEventListener('click', function() {console.log('內層元素被點擊');
});btn.addEventListener('click', function() {console.log('按鈕被點擊');
});

當我們點擊按鈕時,控制臺會輸出以下內容:

按鈕被點擊 內層元素被點擊 外層元素被點擊

可以看到,事件首先在目標元素上觸發,然后在冒泡階段依次觸發父級元素的相同類型事件處理程序。

事件捕獲流

事件捕獲是指在DOM樹中,事件從最外層的父級元素開始向下捕獲傳播的過程。也就是說,在捕獲階段,事件會依次觸發父級元素的相同類型事件處理程序。

下面是一個示例,演示了事件捕獲的過程:

 
<div id="outer"><div id="inner"><button id="btn">點擊我</button></div>
</div>
const outer = document.getElementById('outer');
const inner = document.getElementById('inner');
const btn = document.getElementById('btn');outer.addEventListener('click', function() {console.log('外層元素被點擊');
}, true);inner.addEventListener('click', function() {console.log('內層元素被點擊');
}, true);btn.addEventListener('click', function() {console.log('按鈕被點擊');
});

當我們點擊按鈕時,控制臺會輸出以下內容:

外層元素被點擊 內層元素被點擊 按鈕被點擊

可以看到,事件首先在捕獲階段依次觸發父級元素的相同類型事件處理程序,然后到達目標元素。

事件委托流

事件委托是一種常用的技術,它利用了事件冒泡的特性。通過在父級元素上綁定一個事件處理程序,可以監聽子級元素觸發的事件。這樣一來,無論子級元素是已經存在的還是動態生成的,都可以通過父級元素來管理它們的事件。

下面是一個示例,演示了事件委托的過程:

 
<ul id="list"><li>列表項1</li><li>列表項2</li><li>列表項3</li>
</ul>

 
const list = document.getElementById('list');list.addEventListener('click', function(event) {if (event.target.tagName === 'LI') {console.log('列表項被點擊');console.log('觸發事件的目標元素是:', event.target);}
});

當我們點擊任意一個列表項時,控制臺會輸出以下內容:

列表項被點擊 觸發事件的目標元素是: <li>列表項1</li>

可以看到,通過在父級元素上綁定點擊事件處理程序,我們可以捕獲到子級元素觸發的點擊事件,并且可以獲取到觸發事件的目標元素。這樣一來,無論我們添加或刪除列表項,只需要在父級元素上綁定一個事件處理程序即可。

總結

通過以上介紹,我們了解了DOM事件傳播機制的三個階段:捕獲階段、目標階段和冒泡階段。此外,我們還學習了如何利用事件委托來簡化事件處理程序的綁定和管理。掌握這些概念和技巧,能夠幫助我們更好地處理和管理DOM中的各種交互事件。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/162944.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/162944.shtml
英文地址,請注明出處:http://en.pswp.cn/news/162944.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

入選《數據結構與算法領域內容幫榜》第44名

入選《數據結構與算法領域內容幫榜》第44名

注冊并實名認證華為開發者賬號

首先 我們訪問 https://www.harmonyos.com/ 訪問鴻蒙官方網站 右上角 我們點擊 登錄 然后 我們選擇注冊 然后 注冊方式 有郵箱和手機號的注冊 這邊 看大家需要 如果像我不怎么登郵箱這種 建議還是選擇手機號注冊 這里 居住地區 應該就是默認中國吧 然后 手機號 驗證碼 密碼…

[springboot bug] mac 文件讀取靈異事件

一開始是想嘗試一下spring在過去的xml文件配置bean 的感覺&#xff0c;但是在測試 FileSystemXmlApplicationContext 的時候&#xff0c;反復確認文件路徑沒有問題&#xff0c;將 / -> \\ 也不起作用&#xff0c;后決定debug一下&#xff0c;發現根因。記錄一下&#xff0c…

C#線程 ConcurrentQueue安全隊列介紹

https://blog.csdn.net/qq_41230604/article/details/126305068 C#線程安全隊列ConcurrentQueue ConcurrentQueue隊列是一個高效的線程安全的隊列&#xff0c;是Net Framework 4.0&#xff0c;System.Collections.Concurrent命名空間下的一個數據結構。 ConcurrentQueue內部結…

el-select 組件 懶加載 可遠程搜索

用于分頁數據的懶加載 vueelment 新建elSelct.vue 組件 <template><div><el-select v-el-select-loadmore"loadMore" :value"defaultValue" :loading"loading" :multiple"multiple":placeholder"placeholder&quo…

LeetCode算法心得——使用最小花費爬樓梯(記憶化搜索+dp)

大家好&#xff0c;我是晴天學長&#xff0c;很重要的思想動規思想&#xff0c;需要的小伙伴可以關注支持一下哦&#xff01;后續會繼續更新的。&#x1f4aa;&#x1f4aa;&#x1f4aa; 1&#xff09;使用最小花費爬樓梯 給你一個整數數組 cost &#xff0c;其中 cost[i] 是從…

PTA-使用函數求最大公約數

本題要求實現一個計算兩個數的最大公約數的簡單函數。 函數接口定義&#xff1a; int gcd( int x, int y ); 其中x和y是兩個正整數&#xff0c;函數gcd應返回這兩個數的最大公約數。 裁判測試程序樣例&#xff1a; #include <stdio.h> int gcd( int x, int y ); i…

【數據結構】深入淺出理解鏈表中二級指針的應用

&#x1f984;個人主頁:修修修也 &#x1f38f;所屬專欄:數據結構 ??操作環境:Visual Studio 2022 (注:為方便演示本篇使用的x86系統,因此指針的大小為4個字節) 目錄 &#x1f4cc;形參的改變不影響實參! 1.調用函數更改整型時傳值調用與傳址調用的區別 &#x1f38f;傳值…

render函數舉例

在這段代碼中&#xff0c;renderButton是一個對象嗎 還有render為什么不能寫成render() {} 代碼原文鏈接 <template><div><renderButton /></div> </template><script setup> import { h, ref } from "vue"; const renderButt…

C#,簡單修改Visual Studio 2022設置以支持C#最新版本的編譯器,尊享編程之趣

1 PLS README & CHAPTER 5 用一個超簡單的例子說明各版本 C# 的差異。 使用新版本&#xff08;比如C#.11&#xff09;&#xff0c;當然有一定的好處。我們在寫程序的時候一般這樣&#xff1a; Visual Studio 2022 默認只能這樣寫&#xff1a; string imageFile Path.C…

若依框架參數驗證

文章目錄 一、前端觸發參數校驗異常1.前端頁面2.前端代碼 二、后端觸發參數校驗異常1.前端頁面2.后端報錯 三、后端自定義參數驗證1.添加注解2.觸發后端校驗 一、前端觸發參數校驗異常 1.前端頁面 輸入不符合校驗規則的值來觸發 2.前端代碼 校驗規則數組 表單的元素 修…

SQL Server數據庫備份與還原

目錄 SQL Server DataBase備份 SQL Server DataBase還原 SQL Server DataBase備份 在 SQL Server 中&#xff0c;你可以使用 SQL Server Management Studio (SSMS) 或 Transact-SQL 語句來手動備份數據庫。以下是兩種方法&#xff1a; 使用 SQL Server Management Studio (SS…

JAVA小游戲“飛翔的小鳥”

第一步是創建項目 項目名自擬 第二步創建個包名 來規范class 再創建一個包 來存儲照片 如下&#xff1a; 代碼如下&#xff1a; package game; import java.awt.*; import javax.swing.*; import javax.imageio.ImageIO;public class Bird {Image image;int x,y;int width…

Windows下安裝Anaconda3并使用JupyterNoteBook

下載安裝包 Anaconda官網 進官網&#xff0c;點擊下載 自動根據當前系統下載對應的包了&#xff0c;安裝包大約1G&#xff0c;喝杯Java耐心等待。 安裝 很多人安裝C盤&#xff0c;我這里放D盤。 注意&#xff1a;你的文件夾目錄一定要不能有空格 然后其他的直接默認install即…

不同路徑 遞歸

int dfs(int i, int j, int m, int n) { if (i > m || j > n) return 0; // 越界了 if (i m && j n) return 1; // 找到一種方法&#xff0c;相當于找到了葉子節點 return dfs(i 1, j, m, n) dfs(i, j 1, m, n); } int u…

在線視頻課程教育系統源碼/網課網校/知識付費/在線教育系統/在線課程培訓系統源碼

源碼簡介&#xff1a; 在線視頻課程教育系統源碼&#xff0c;作為網課/網校/知識付費/在線教育系統&#xff0c;它有文章付費閱讀在線點播自動發貨付費閱讀VIP會員系統等功能。它是實用的在線課程培訓系統源碼。 發貨100-在線視頻課程教育系統&#xff0c;它是一款功能實用的…

優思學院|2024年質量管理的大趨勢

2023年我們已經順利度過了整年的大部分時間&#xff0c;2024年質量管理的趨勢和問題在全球范圍內都已經引起了關注&#xff0c;或者仍然是企業導航的首要任務。 1. 通貨膨脹與質量管理 2023年&#xff0c;全球范圍內通貨膨脹和嚴峻的經濟狀況成為企業最關心的問題之一。盡管物…

Flash可更換聲音語音芯片WT588F02系列:優勢盡顯,應用廣泛

在語音技術日益普及的今天&#xff0c;唯創知音推出的Flash可更換聲音語音芯片WT588F02系列備受關注。該系列芯片憑借其強大的性能與廣泛的應用領域&#xff0c;成為市場上的一顆璀璨明星。本文將分析WT588F02系列的優勢&#xff0c;并探討其應用場景&#xff0c;以展現其在語音…

typedef 的使用

typedef 的定義 typedef 是 C 和 C 中的一個關鍵字&#xff0c;用于給已有類型定義一個新的名字&#xff0c;與 class、struct、union 和 enum 聲明不同&#xff0c;typedef 聲明不引入新類型&#xff1b;它們引入現有類型的新名稱 typedef 的語法格式 typedef existing_typ…

gitlab 12升級14(解決各種報錯問題)

1.這里是從自己公司的源下載的rpm包&#xff0c;需要換成自己的 2.從12的最后一個版本升級到14的最后一個版本 # 停服務 [rootdocker test]# gitlab-ctl stop puma && gitlab-ctl stop sidekiq && gitlab-ctl stop nginx && gitlab-ctl status# 進入…