關於DOM事件流、DOM0級事件與DOM2級事件

来源:https://www.cnblogs.com/Leophen/archive/2019/08/24/11405579.html
-Advertisement-
Play Games

一、DOM 事件模型 DOM 事件模型包括捕獲和冒泡,捕獲是從上往下到達目標元素,冒泡是從當前元素,也就是目標元素往上到 window 二、流 流的概念,在現今的 JavaScript 中隨處可見。比如說 React 中的單向數據流,Node 中的流,還有 DOM 事件流,都是流的一種生動體現。至於 ...


一、DOM 事件模型

DOM 事件模型包括捕獲和冒泡,捕獲是從上往下到達目標元素,冒泡是從當前元素,也就是目標元素往上到 window

 

 

二、流

流的概念,在現今的 JavaScript 中隨處可見。比如說 React 中的單向數據流,Node 中的流,還有 DOM 事件流,都是流的一種生動體現。
至於流的具體概念,用術語說流是對輸入輸出設備的抽象。以程式的角度說,流是具有方向的數據。

 

 

三、事件流

瀏覽器在為當前頁面與用戶做交互的過程中,比如點擊滑鼠左鍵,會出現這個左鍵是怎麼傳到頁面上,還有怎麼響應的問題。

事件流所描述的就是從頁面中接受事件的順序,事件流分為兩種:事件冒泡(主流)和事件捕獲

 

1、事件冒泡

事件開始時由具體元素接收,然後逐級向上傳播到父元素

舉個例子:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Event Bubbling</title>
</head>
<body>
  <button id="clickMe">Click Me</button>
</body>
</html>

我們給 button 和它的父元素,加入點擊事件

var button = document.getElementById('clickMe');
 
button.onclick = function() {
  console.log('1. You click Button');
};
document.body.onclick = function() {
  console.log('2. You click body');
};
document.onclick = function() {
  console.log('3. You click document');
};
window.onclick = function() {
  console.log('4. You click window');
};

點擊按鈕運行效果:

也就是說,click 事件首先在 <button> 元素上發生,然後逐級向上傳播,這就是事件冒泡

 

2、事件捕獲

 

父元素的節點更早接收事件,而具體元素最後接收事件,與事件冒泡相反

 

 

三、DOM 事件流

DOM事件流包括三個階段:

  1. 事件捕獲階段

  2. 處於目標階段

  3. 事件冒泡階段

 

1、事件捕獲階段

當事件發生時,首先發生的是事件捕獲,為父元素截獲事件提供了機會

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Event Bubbling</title>
</head>
<body>
  <button id="clickMe">Click Me</button>
</body>
</html>

上面事件冒泡的 Demo 中,window 點擊事件更改為使用事件捕獲模式

var button = document.getElementById('clickMe');
 
button.onclick = function() {
  console.log('1. You click Button');
};
document.body.onclick = function() {
  console.log('2. You click body');
};
document.onclick = function() {
  console.log('3. You click document');
};
// window.onclick = function() {
//   console.log('4. You click window');
// };
window.addEventListener('click', function() {
  console.log('4. You click window');
}, true);

此時,點擊 button 的效果是這樣的:

可以看到,點擊事件先被父元素截獲了,且該函數只在事件捕獲階段起作用

 

2、處於目標階段

事件到了具體元素時,在具體元素上發生,並且被看成冒泡階段的一部分

 

3、事件冒泡階段

最後,冒泡階段發生,事件開始冒泡

 

 

四、阻止事件冒泡

事件冒泡過程,是可以被阻止的。防止事件冒泡而帶來不必要的錯誤和困擾。

阻止方法是使用 stopPropagation(),舉個例子:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Event Bubbling</title>
</head>
<body>
  <button id="clickMe">Click Me</button>
</body>
</html>

還是上面的 demo,這裡對 button 的 click 事件做了一些改造:

var button = document.getElementById('clickMe');
 
// button.onclick = function() {
//   console.log('1. You click Button');
// };
button.addEventListener('click', function(event) {
  // 這裡event為事件對象
  console.log('1. You click Button');
  event.stopPropagation();
  console.log('Stop Propagation!');
}, false);
document.body.onclick = function() {
  console.log('2. You click body');
};
document.onclick = function() {
  console.log('3. You click document');
};
window.addEventListener('click', function() {
  console.log('4. You click window');
}, true);

點擊後,效果如下圖:

不難看出,事件在到達具體元素後,停止了冒泡,但不影響父元素的事件捕獲

 

 

五、DOM0級事件

DOM0級事件,就是直接通過 onclick 等方式實現相應的事件

 

1、標簽內寫 onclick 事件

<input id="myButton" type="button" value="Click Me" onclick="alert('Hello1');" >

 

2、在 JS 中 使用onclick = function(){}

document.getElementById("myButton").onclick = function () {
    alert('Hello2');
}

運行結果 - 點擊彈出:

這說明 DOM0 級添加事件時,後面的事件會覆蓋前面的事件,而 DOM2級則不會,多個事件都會執行;

另外,DOM0級事件具有很好的跨瀏覽器優勢,會以最快的速度綁定,但由於綁定速度太快,可能頁面還未完全載入出來,以至於事件可能無法正常運行

 

 

六、DOM2級事件

 

1、DOM2級事件的方法

主流瀏覽器 DOM2 級事件是通過以下兩個方法用於處理指定和刪除事件處理程式的操作:

  • addEvenetListener
  • removeEventListener

 

2、DOM2級事件的使用

所有的 DOM 節點都包含這兩個方法,使用方法如下:

  • target.addEventListener(type, listener[, useCapture]);
  • target.removeEventListener(type, listener[, useCapture]);

並且它們都接受三個參數:

  • type:事件類型,如'click'、'mouseover'、'mouseout',在事件名前不加'on'
  • listener:事件處理方法
  • useCapture:布爾參數,不傳該參數時預設是 false,表示在事件冒泡階段處理,如果是 true,則表示在捕獲階段調用事件處理程式

舉個例子:

<input id="myButton" type="button" value="Click Me" onclick="alert('Hello1');" >
document.getElementById("myButton").onclick = function () {
    alert('Hello2');
}
document.getElementById('myButton').addEventListener('click', function() {
  alert('Hello3');
}, true)
document.getElementById('myButton').addEventListener('click', function() {
  alert('Hello4');
}, true)
document.getElementById('myButton').addEventListener('click', function() {
  alert('Hello5');
}, false)

運行結果:

註意:只有 DOM2級事件包含以下三個階段

  1. 事件捕獲階段

  2. 處於目標階段

  3. 事件冒泡階段

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Mongodb最基礎入門教程 如果想瞭解一下redis的入門教程,可以去看一下我的上一篇博客 Mongodb的安裝大家可以參考一下其他博主的博客,這裡我就不做介紹了。不過值得註意的是,在Linux版本中如果啟動mongodb的時候出現下麵這個錯誤(在windows版本中不會出現下麵的問題): mon ...
  • 一、基本概念 一個典型的 Hbase Table 表如下: 1.1 Row Key (行鍵) 是用來檢索記錄的主鍵。想要訪問 HBase Table 中的數據,只有以下三種方式: + 通過指定的 進行訪問; + 通過 Row Key 的 range 進行訪問,即訪問指定範圍內的行; + 進行全表掃描 ...
  • 坐標軸 平移 旋轉 縮放 重置坐標軸 矩陣操作 示例 1、坐標軸 OpenGL 使用的右手坐標系,從正面看原點,逆時針旋轉被認為是正旋轉。 x軸:從左到右 y軸:從底部向上 z軸:從屏幕背向朝向前方 2、平移 public abstract void glTranslatef(float x ,fl ...
  • 版權聲明:本文為xing_star原創文章,轉載請註明出處! 本文同步自http://javaexception.com/archives/201 Android Studio修改Apk打包生成名稱 Android studio預設生成的apk的名字實在是太沒有辨識度了,一般預設是app-debug ...
  • 本文是作者之前剛接觸移動端跨平臺開發,使用weex-eros開發項目平日里記下來的一些筆記,分享出來方便為新手解惑,weex-eros是weex的一套解決方法,使用vue語法糖,對於前端開發者來說可以輕鬆上手,文檔如下: weex:https://weex.apache.org/zh/ weex-e ...
  • 2019-08-2422:21:03 ...
  • 樣式的導入方式 link @import link @import 一、link 的使用 二、@import 的使用 三、link 和 @import 的區別 1、引入的內容不同 link 除了引用樣式文件,還可以引用圖片等資源文件,而 @import 只引用樣式文件 2、載入順序不同 link 引 ...
  • <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content=""> <meta name= ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...