搜尋
首頁web前端js教程JavaScript事件之事件冒泡與時間捕獲(總結分享)

這篇文章為大家帶來了JavaScript中關於事件的基礎知識詳解,其中包括了事件冒泡和時間捕獲,希望對大家有幫助。

JavaScript事件之事件冒泡與時間捕獲(總結分享)

一、事件冒泡與事件捕獲

當我們在Web頁面點擊某一個元素的時候,例如某個p元素。仔細想想,我們點擊的不僅是這一個p元素,一同被點擊的還有以該p為圓心的同心圓元素,例如元素的父,外層body、body的父元素html還有外層的document。事件在這些嵌套的元素之間的傳播稱為事件流。

  • 1、事件冒泡
  • 2、事件擷取

#1、事件冒泡

IE的事件流稱為事件冒泡,事件從最具體的元素開始,逐級向上傳播。我們使用DOM0加入的事件處理程序就是在事件冒泡階段處理的。例如:

<html>
  <head>
    <script type="text/javascript">

      window.onload = bubblingHandle;      function bubblingHandle() {
          //内层p处理程序
          document.getElementById("inner").onmousedown     = function() {
              alert("inner p");
          }          //外层p处理程序
          document.getElementById("outer").onmousedown = function() {
              alert("outerp");
          }

          document.onmousedown = function() {
              alert("document");
          }
      } 
      -->    </script>
  </head>
  <body>
    <p id="outer" style="background-color:black; padding: 15px;">
        <p id="inner" style="background-color:white; padding: 5px;"></p>
    </p>
  </body></html>

當點擊內層的白色p時,會依序顯示:

inner p
outer p
document

事件捕獲

網景提出的事件流稱為事件捕獲,其與IE幾乎相反。事件首先由最不具體的元素接收,然後逐級向具體節點傳播。

二、DOM0級事件處理

事件,由WEB頁面中發生的一些特定行為觸發。例如在某個頁面元素上按下滑鼠左鍵,按下鍵盤某個按鍵,某物件取得或遺失焦點時都會觸發對應的事件。 JavaScript和HTML的互動就是透過事件來實現的。我們使用事件偵聽器對事件進行“註冊”,並在事件發生時執行相應的程式碼。

DOM0級事件處理程序以其簡單、跨瀏覽器支援的特點,至今仍為所有瀏覽器支援。

  • 透過DOM0級方法指定事件處理程序
  • 事件處理程序中的this
  • 透過DOM0級方法刪除事件處理程序

透過DOM0級方法指定事件處理程序

透過DOM0級方法指定事件處理程序方法很簡單,先取得一個要操作元素的引用,然後接將一個函數賦值給該元素的對應事件處理程序屬性。 (每個元素包括window和document都擁有自己的事件處理程序屬性。)請注意,這種方法添加的事件處理程序將在事件流的冒泡階段被處理。

有關事件處理程序屬性,有以下幾點需要說明:

1、事件處理程序屬性全部小寫,以”on”開頭,後面跟著事件類型:

onclick  //单击鼠标
onload  //图像或页面载入完成
onmouseover  //将鼠标移动到某元素上面
onmousemove  //移动鼠标
onfocus  //对象获得焦点

2、每個元素如img、a、input、form包括window和document都擁有自己的事件處理程序屬性。如:

document.getElementById("btn1").onclick  //btn1上单击鼠标
document.getElementById("img1").onmouseover  //鼠标移动到img1
document.getElementById("img1").onmerror  //img1图像无法载入

接下來,將事件處理程序屬性賦值即可完成事件處理程序方法的指定。例如,當滑鼠移動到”img1”上時,彈出對話框”This is a nice pic!”:

var pic1 = document.getElementById("img1");
pic1.onmouseover = function() {
    alert("This is a nice pic!");
};

特別注意:如果以上代碼處於文檔的底部,在頁面剛剛加載時,我們將滑鼠移動到img1上面。有可能由於程式碼尚未執行,不會彈出我們設定的對話框!如今,這個延遲已經十分短暫。

事件處理程序中的this

透過DOM0級方法指定的事件處理程序,屬於元素方法。因此,我們在事件處理程序中的this引用的是該元素!透過以下範例來說明:

<input>
...//省略
<script>
  <!--
  var btn1 = document.getElementById("btn1");
  btn1.onclick = function() {
      alert(this.id + "\n" + this.type + "\n" + this.value);
  };
  -->
</script>

透過DOM0級方法刪除事件處理程序

要刪除事件處理程序,只需要將對應的事件處理程序屬性設為null:

pic1.onmouseover = null;

三、DOM2級事件處理

1、addEventListener與removeEventListener

目前,幾乎所有的瀏覽器都支援DOM0事件模型,但鼓勵開發人員使用新的DOM2模型。 DOM2模型與DOM0有兩個顯著差異:

  • 1、DOM2不依賴事件處理程序屬性
  • 2、可以同時對物件的相同事件註冊多個處理程序,它們依照註冊順序依序執行。

DOM2定義了2個方法:

addEventListener()  //指定事件处理程序
removeEventListener()  //删除事件处理程序

所有DOM節點都有包含這兩個方法,這兩個方法用法如下,它們都接收3個參數,第1個為要處理事件名(不含on),第2個事件處理函數,第3個布林變數:

例如我們為按鈕btn1的點擊事件新增2個事件處理程序,事件處理程序在事件冒泡階段被處理:

<input>
...
<script>
  <!--
  var btn1 = document.getElementById("btn1");
  var handle1 = function() {
      alert("handle1!");
  }
  var handle2 = function() {
      alert("handle2!");
  }
  btn1.addEventListener("click", handle1, false);
  btn1.addEventListener("click", handle2, false);
  -->
</script>

當點擊btn1按鈕時,會依序彈出對話框:

handle1!
handle2!

我們可以用removeEventListener()方法來刪除我們剛才指定的事件處理程序,注意參數要保持一致:

btn1.removeEventListener("click", handle2, false);

此時點選btn1按鈕,只會顯示handle1!。

要特別注意的是,如果我們使用匿名函數指定事件處理程序,便無法使用removeEventListener()方法刪除事件處理程序:

 btn1.addEventListener("click", function(){
     alert("click!");
 }, false);

 btn1.removeEventListener("click", function(){
     alert("click!");
 }, false);  //无法取消!

这样是无法取消以上指定的事件处理程序的!因为上面addEventListener和removeEventListener中的2个事件处理函数虽然代码相同,实质上是2个不同的函数引用。

另外,强调一点,以上两个函数的第一个参数(要处理的事件名)是没有on前缀的。这一点和IE不同,后面会说明。

tips: IE9, Firefox, Safari, Chrome以及Opera均支持DOM2级事件处理程序。

DOM2事件处理程序中的this

DOM2事件处理程序和DOM0相同,它们的this都在其依附的元素作用域中运行。this的指代参考DOM0的示例。这里之所以要特别指出DOM2的this,是为了和IE事件处理程序进行区分。IE中事件处理程序this与事件指定方式有关。

四、IE事件处理程序及跨浏览器支持

attachEvent()与detachEvent()

IE并没有提供对W3C事件模型的支持,其实现了2个和DOM2模型类似的方法:

attachEvent()
detachEvent()

这两个方法只接收2个参数:事件名称以及事件处理函数。由于IE8及更早版本只支持事件冒泡,这两个方法添加的事件处理程序会在事件冒泡阶段被执行。

和DOM2不同的是:

  • 1、IE事件处理方法运行作用域为全局作用域,this指代window;
  • 2、第一个参数事件名以on为前缀;
  • 3、当为同一对象的相同事件指定多个处理程序时,执行顺序和DOM2相反,IE中以添加它们的相反顺序执行。

例如:

<input>
...
<script>
  <!--
  var btn1 = document.getElementById("btn1");
  var handle1 = function() {
      alert("handle1!" + "\n" + (this === window));
  };
  var handle2 = function() {
      alert("handle2!"+ "\n" + (this === window));
  };
  btn1.attachEvent("onclick", handle1);
  btn1.attachEvent("onclick", handle2);
  -->
</script>

执行结果:

handle2!
true

handle1!
true

跨浏览器支持

虽然可以使用屏蔽浏览器差异的JS库,实际上,我们自己编写一个跨浏览器兼容的事件处理代码并不是一件困难的事情,同时更有利于我们对原生JavaScript的学习理解。我们使用一个习惯上称为EventUtil的对象来进行跨浏览器事件处理:

var EventUtil = {
    addEventHandler : function(element, eventType,        handler) {
        if(element.addEventListener){
            element.addEventListener(eventType, handler, flase);
        } else if(element.attachEvent) {
            element.attachEvent("on" + eventType, handler);
        } else {
            element["on" + eventType] = handler;
        }
    },

    removeEventHandler : function(element, eventType, handler) {
        if(element.aremoveEventListener){
            element.addEventListener(eventType, handler, flase);
        } else if(element.detachEvent) {
            element.attachEvent("on" + eventType, handler);
        } else {
            element["on" + eventType] = null;
        }
    }
}

为了保证事件处理代码能够在大多数浏览器中一致地运行,我们这里只关注冒泡阶段。以上代码使用浏览器能力检测,首先检测是否支持DOM2级方法addEventListener和removeEventListener,如果支持则使用该方法;如果不支持该方法,检测是否是IE8级更早版本的attachEvent或detachEvent方法,若支持则使用该方法;如果对以上2种方法都不支持,则使用DOM0级方法。要注意,DOM0级对每个事件只能指定一个事件处理程序。

以上对象使用示例如下:

var btn1 = document.getElementById("btn1");var handle1 = function() {
    alert("handle1!" + "\n" + (this === window));
};var handle2 = function() {
    alert("handle2!"+ "\n" + (this === window));
};
EventUtil.addEventHandler(btn1, "click", handler1);
EventUtil.addEventHandler(btn1, "click", handler2);

EventUtil.removeEventHandler(btn1, "click", handler2);

五、事件对象

在触发某个事件时,会产生一个event对象。该对象中包含与事件有关的信息。例如触发事件的元素、事件的类型、与特定事件相关的如鼠标位置信息等。

  • 1、DOM事件对象
  • 2、IE事件对象与跨浏览器事件对象

1、DOM事件对象

不论使用DOM0级还是DOM2级方法指定事件处理程序,事件触发时都会自动将一个event对象传入事件处理程序,例如:

var btn1 = document.getElementById("btn1");

btn1.onmouseover = function(evnt) {
    alert(evnt.type);
}var handle = function(evnt) {
    alert(evnt.type);
};
btn1.addEventListener("click", handle, false);

以上是一个简单的event对象的示例。event对象中的type属性是一个只读字符串属性,其中包含着事件的类型。例如我们上例中的click和onmouseover。event对象中包含有大量的有关事件的属性和方法(例如event.stopPropagation()方法可用于停止事件在捕获或者冒泡阶段的继续传播,preventDefault()方法会取消阻止事件的行)在此就不一一列举了。其中常用的如下:

属性/方法 值类型 读写 描述
currentTarget Element readonly 事件处理程序当前正在处理的元素
target Element readonly 事件的目标
type String readonly 触发事件的类型
preventDefault Function readonly 取消事件默认行为,如链接的默认行为就是被单击时跳转到href指定的url
stopPropagation Function readonly 取消事件进一步冒泡或捕获

2、IE事件对象与跨浏览器事件对象

IE事件对象

在IE中,当使用DOM0级指定事件处理程序时,event对象被认为是window的一个属性,例如获取鼠标点击坐标的代码:

var mouseLoc = function() {
    var loc = "x: " + window.event.screenX + "\n" +              "y: " + window.event.screenY;
    alert(loc);
};

当使用attachEvent()方法指定事件处理程序时,event对象会被作为参数传入事件处理程序,我们将以上的代码重写:

var mouseLoc = function(event) {
    var loc = "x: " + event.screenX + "\n" +              "y: " + event.screenY;
    alert(loc);
};
btn1.attachEvent("onclick",  mouseLoc);

IE中event对象的相关属性方法:

属性/方法 值类型 读写 描述
cancelBubble Boolean read/write 默认为false,置为true时取消事件冒泡(同DOM中stopPropagation)
returnValue Boolean read/write 默认为true,设为false取消事件默认行为(同DOM中preventDefault)
srcElement Element readonly 事件目标
type String readonly 事件类型

跨浏览器事件对象

解决跨浏览器问题的思路是一贯的,我们可以对浏览器进行能力检测,这里我们对上面的EventUtil对象进行扩展,对我们学习原生JS,这是一个很漂亮的对象:

var EventUtil = {
    addEventHandler : function(element, eventType, handler) {
        if(element.addEventListener){
            element.addEventListener(eventType, handler, flase);
        } else if(element.attachEvent) {
            element.attachEvent("on" + eventType, handler);
        } else {
            element["on" + eventType] = handler;
        }
    },

    removeEventHandler : function(element, eventType, handler) {
        if(element.aremoveEventListener){
            element.addEventListener(eventType, handler, flase);
        } else if(element.detachEvent) {
            element.attachEvent("on" + eventType, handler);
        } else {
            element["on" + eventType] = null;
        }
    },

    getEvent: function (event) {
        return event ? event : window.event;
    },

    getTarget: function (event) {
        return event.target || event.srcElement;
    },

    preventDefault: function (event) {
        if (event.preventDefault) {
            event.preventDefault();
        } else {
            event.returnValue = false;
        }
    },

    stopPropagation: function (event) {
        if (event.stopPropagation) {
            event.stopPropagation();
        } else {
            event.cancelBubbles = true;
        }
    },

    getRelatedTarget: function (event) {
        if (event.relatedTarger) {            return event.relatedTarget;
        } else if (event.toElement) {            return event.toElement;
        } else if (event.fromElement) {            return event.fromElement;
        } else { return null; }
    }
}

【相关推荐:javascript学习教程

以上是JavaScript事件之事件冒泡與時間捕獲(總結分享)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:CSDN。如有侵權,請聯絡admin@php.cn刪除
Python vs. JavaScript:學習曲線和易用性Python vs. JavaScript:學習曲線和易用性Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

Python vs. JavaScript:社區,圖書館和資源Python vs. JavaScript:社區,圖書館和資源Apr 15, 2025 am 12:16 AM

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

從C/C到JavaScript:所有工作方式從C/C到JavaScript:所有工作方式Apr 14, 2025 am 12:05 AM

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

JavaScript引擎:比較實施JavaScript引擎:比較實施Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

超越瀏覽器:現實世界中的JavaScript超越瀏覽器:現實世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

使用Next.js(後端集成)構建多租戶SaaS應用程序使用Next.js(後端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

如何使用Next.js(前端集成)構建多租戶SaaS應用程序如何使用Next.js(前端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:22 AM

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

JavaScript:探索網絡語言的多功能性JavaScript:探索網絡語言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器