目录
一、事件冒泡与事件捕获
1、事件冒泡
二、DOM0级事件处理
通过DOM0级方法指定事件处理程序
事件处理程序中的this
通过DOM0级方法删除事件处理程序
三、DOM2级事件处理
1、addEventListener与removeEventListener
DOM2事件处理程序中的this
四、IE事件处理程序及跨浏览器支持
attachEvent()与detachEvent()
跨浏览器支持
五、事件对象
1、DOM事件对象
2、IE事件对象与跨浏览器事件对象
IE事件对象
跨浏览器事件对象
首页 web前端 js教程 JavaScript事件之事件冒泡与时间捕获(总结分享)

JavaScript事件之事件冒泡与时间捕获(总结分享)

Dec 23, 2021 pm 06:49 PM

本篇文章给大家带来了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 id="btn1" type="button" value="Click Me" />
...//省略
<script type="text/javascript">
  <!--
  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 id="btn1" type="button" value="Click Me" />
...
<script type="text/javascript">
  <!--
  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 id="btn1" type="button" value="Click Me" />
...
<script type="text/javascript">
  <!--
  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()方法会取消阻止事件的行)在此就不一一列举了。其中常用的如下:

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

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对象的相关属性方法:

属性/方法值类型读写描述
cancelBubbleBooleanread/write默认为false,置为true时取消事件冒泡(同DOM中stopPropagation)
returnValueBooleanread/write默认为true,设为false取消事件默认行为(同DOM中preventDefault)
srcElementElementreadonly事件目标
typeStringreadonly事件类型

跨浏览器事件对象

解决跨浏览器问题的思路是一贯的,我们可以对浏览器进行能力检测,这里我们对上面的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中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热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.能量晶体解释及其做什么(黄色晶体)
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

在JavaScript中替换字符串字符 在JavaScript中替换字符串字符 Mar 11, 2025 am 12:07 AM

JavaScript字符串替换方法详解及常见问题解答 本文将探讨两种在JavaScript中替换字符串字符的方法:在JavaScript代码内部替换和在网页HTML内部替换。 在JavaScript代码内部替换字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 该方法仅替换第一个匹配项。要替换所有匹配项,需使用正则表达式并添加全局标志g: str = str.replace(/fi

如何创建和发布自己的JavaScript库? 如何创建和发布自己的JavaScript库? Mar 18, 2025 pm 03:12 PM

文章讨论了创建,发布和维护JavaScript库,专注于计划,开发,测试,文档和促销策略。

如何在浏览器中优化JavaScript代码以进行性能? 如何在浏览器中优化JavaScript代码以进行性能? Mar 18, 2025 pm 03:14 PM

本文讨论了在浏览器中优化JavaScript性能的策略,重点是减少执行时间并最大程度地减少对页面负载速度的影响。

前端热敏纸小票打印遇到乱码问题怎么办? 前端热敏纸小票打印遇到乱码问题怎么办? Apr 04, 2025 pm 02:42 PM

前端热敏纸小票打印的常见问题与解决方案在前端开发中,小票打印是一个常见的需求。然而,很多开发者在实...

如何使用浏览器开发人员工具有效调试JavaScript代码? 如何使用浏览器开发人员工具有效调试JavaScript代码? Mar 18, 2025 pm 03:16 PM

本文讨论了使用浏览器开发人员工具的有效JavaScript调试,专注于设置断点,使用控制台和分析性能。

立即提高jQuery性能的10种方法 立即提高jQuery性能的10种方法 Mar 11, 2025 am 12:15 AM

本文概述了十个简单的步骤,可以显着提高脚本的性能。 这些技术很简单,适用于所有技能水平。 保持更新:使用bundler(例如vite)的npm等软件包经理来确保

使用Passport与semelize和MySQL 使用Passport与semelize和MySQL Mar 11, 2025 am 11:04 AM

续集是一个基于承诺的node.js orm。它可以与PostgreSQL,MySQL,MariadB,Sqlite和MSSQL一起使用。在本教程中,我们将为Web应用程序的用户实施身份验证。我们将使用Passport,Passport,Midderw的流行身份验证

如何构建简单的jQuery滑块 如何构建简单的jQuery滑块 Mar 11, 2025 am 12:19 AM

本文将引导您使用jQuery库创建一个简单的图片轮播。我们将使用bxSlider库,它基于jQuery构建,并提供许多配置选项来设置轮播。 如今,图片轮播已成为网站必备功能——一图胜千言! 决定使用图片轮播后,下一个问题是如何创建它。首先,您需要收集高质量、高分辨率的图片。 接下来,您需要使用HTML和一些JavaScript代码来创建图片轮播。网络上有很多库可以帮助您以不同的方式创建轮播。我们将使用开源的bxSlider库。 bxSlider库支持响应式设计,因此使用此库构建的轮播可以适应任何

See all articles