目录
一、事件
二、事件流
首页 web前端 前端问答 javascript有哪几种事件流

javascript有哪几种事件流

Jan 26, 2022 pm 01:02 PM
javascript

javascript的事件流有:1、冒泡型事件流,事件的传播是从最特定的事件目标到最不特定的事件目标;2、捕获型事件流,事件的传播是从最不特定的事件目标到最特定的事件目标;3、DOM事件流。

javascript有哪几种事件流

本教程操作环境:windows7系统、javascript1.8.5版、Dell G3电脑。

一、事件

事件是文档或者浏览器窗口中发生的,特定的交互瞬间。

事件是用户或浏览器自身执行的某种动作,如click,load和mouseover都是事件的名字。

事件是javaScript和DOM之间交互的桥梁。

你若触发,我便执行——事件发生,调用它的处理函数执行相应的JavaScript代码给出响应。

典型的例子有:页面加载完毕触发load事件;用户单击元素,触发click事件。

二、事件流

事件流描述的是从页面中接收事件的顺序。

1、事件流感性认识

问题:单击页面元素,什么样的元素能感应到这样一个事件?

答案:单击元素的同时,也单击了元素的容器元素,甚至整个页面。

例子:有三个同心圆, 给每个圆添加对应的事件处理函数,弹出对应的文字。单击最里面的圆,同时也单击了外面的圆,所以外面圆的click事件也会被触发。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<style>
    #outer{
        position: absolute;
        width: 400px;
        height: 400px;
        top:0;
        left: 0;
        bottom:0;
        right: 0;
        margin: auto;
        background-color: deeppink;
    }
    #middle{
        position: absolute;
        width: 300px;
        height:300px;
        top:50%;
        left: 50%;
        margin-left: -150px;
        margin-top: -150px;
        background-color: deepskyblue;
    }
    #inner{
        position: absolute;
        width: 100px;
        height:100px;
        top:50%;
        left:50%;
        margin-left: -50px;
        margin-top: -50px;;
        background-color: darkgreen;
        text-align: center;
        line-height: 100px;
        color:white;
    }
    #outer,#middle,#inner{
border-radius:100%;
    }
</style>
<body>
<div id="outer">
   <div id="middle">
        <div id="inner">
            click me!
        </div>
    </div>
</div>
<script>
       var innerCircle= document.getElementById("inner");
        innerCircle.onclick= function () {
            alert("innerCircle");
        };
        var middleCircle= document.getElementById("middle");
        middleCircle.onclick=function(){
            alert("middleCircle");
        }
        var outerCircle= document.getElementById("outer");
        outerCircle.onclick= function () {
            alert("outerCircle");
        }
</script>
</body>
</html>
登录后复制

效果如下:

2、事件流

事件发生时会在元素节点与根节点之间按照特定的顺序传播,路径所经过的所有节点都会收到该事件,这个传播过程即DOM事件流。

1)、两种事件流模型

事件传播的顺序对应浏览器的两种事件流模型:捕获型事件流和冒泡型事件流。

冒泡型事件流事件的传播是从最特定事件目标到最不特定的事件目标。即从DOM树的叶子到根。【推荐】

捕获型事件流事件的传播是从最不特定事件目标到最特定的事件目标。即从DOM树的根到叶子。

事件捕获的思想就是不太具体的节点应该更早接收到事件,而最具体的节点最后接收到事件。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<div id="myDiv">Click me!</div>
</body>
</html>
登录后复制

上面这段html代码中,单击了页面中的

元素,

在冒泡型事件流中click事件传播顺序为

—》—》—》document

在捕获型事件流中click事件传播顺序为document—》—》—》

note:

1)、所有现代浏览器都支持事件冒泡,但在具体实现中略有差别:

IE5.5及更早版本中事件冒泡会跳过元素(从body直接跳到document)。

IE9、Firefox、Chrome、和Safari则将事件一直冒泡到window对象。

2)、IE9、Firefox、Chrome、Opera、和Safari都支持事件捕获。尽管DOM标准要求事件应该从document对象开始传播,但这些浏览器都是从window对象开始捕获事件的。

3)、由于老版本浏览器不支持,很少有人使用事件捕获。建议使用事件冒泡

2)、DOM事件流

DOM标准采用捕获+冒泡。两种事件流都会触发DOM的所有对象,从document对象开始,也在document对象结束。

DOM标准规定事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。

  • 事件捕获阶段:实际目标

    )在捕获阶段不会接收事件。也就是在捕获阶段,事件从document到再到就停止了。上图中为1~3.

  • 处于目标阶段:事件在

    上发生并处理。但是事件处理会被看成是冒泡阶段的一部分

  • 冒泡阶段:事件又传播回文档。

note:

1)、尽管“DOM2级事件”标准规范明确规定事件捕获阶段不会涉及事件目标,但是在IE9、Safari、Chrome、Firefox和Opera9.5及更高版本都会在捕获阶段触发事件对象上的事件。结果,就是有两次机会在目标对象上面操作事件。

2)、并非所有的事件都会经过冒泡阶段 。所有的事件都要经过捕获阶段和处于目标阶段,但是有些事件会跳过冒泡阶段:如,获得输入焦点的focus事件和失去输入焦点的blur事件。

两次机会在目标对象上面操作事件例子:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<style>
    #outer{
        position: absolute;
        width: 400px;
        height: 400px;
        top:0;
        left: 0;
        bottom:0;
        right: 0;
        margin: auto;
        background-color: deeppink;
    }
    #middle{
        position: absolute;
        width: 300px;
        height:300px;
        top:50%;
        left: 50%;
        margin-left: -150px;
        margin-top: -150px;
        background-color: deepskyblue;
    }
    #inner{
        position: absolute;
        width: 100px;
        height:100px;
        top:50%;
        left:50%;
        margin-left: -50px;
        margin-top: -50px;;
        background-color: darkgreen;
        text-align: center;
        line-height: 100px;
        color:white;
    }
    #outer,#middle,#inner{
        border-radius:100%;
    }
</style>
<body>
<div id="outer">
    <div id="middle">
        <div id="inner">
            click me!
        </div>
    </div>
</div>
<script>
    var innerCircle= document.getElementById("inner");
    innerCircle.addEventListener("click", function () {
        alert("innerCircle的click事件在捕获阶段被触发");
    },true);
    innerCircle.addEventListener("click", function () {
        alert("innerCircle的click事件在冒泡阶段被触发");
    },false);
    var middleCircle= document.getElementById("middle");
    middleCircle.addEventListener("click", function () {
        alert("middleCircle的click事件在捕获阶段被触发");
    },true);
    middleCircle.addEventListener("click", function () {
        alert("middleCircle的click事件在冒泡阶段被触发");
    },false);
    var outerCircle= document.getElementById("outer");
    outerCircle.addEventListener("click", function () {
        alert("outerCircle的click事件在捕获阶段被触发");
    },true);
    outerCircle.addEventListener("click", function () {
        alert("outerCircle的click事件在冒泡阶段被触发");
    },false);
</script>
</body>
</html>
登录后复制

运行效果就是会陆续弹出6个框,为说明原理我整合成了一个图:

3、事件流的典型应用事件代理

传统的事件处理中,需要为每个元素添加事件处理器。js事件代理则是一种简单有效的技巧,通过它可以把事件处理器添加到一个父级元素上,从而避免把事件处理器添加到多个子级元素上。

1)、事件代理

事件代理的原理用到的就是事件冒泡和目标元素,把事件处理器添加到父元素,等待子元素事件冒泡,并且父元素能够通过target(IE为srcElement)判断是哪个子元素,从而做相应处理。关于target更多内容请参考javaScript事件(四)event的公共成员(属性和方法) 下面举例来说明。

传统事件处理,为每个元素添加事件处理器,代码如下:

<body>
<ul id="color-list">
<li>red</li>
<li>orange</li>
<li>yellow</li>
<li>green</li>
<li>blue</li>
<li>indigo</li>
<li>purple</li>
</ul>
<script>
(function(){
    var colorList=document.getElementById("color-list");
    var colors=colorList.getElementsByTagName("li");
    for(var i=0;i<colors.length;i++)
    {
        colors[i].addEventListener(&#39;click&#39;,showColor,false);
    };
    function showColor(e)
    {
        e=e||window.event;
        var targetElement=e.target||e.srcElement;
        alert(targetElement.innerHTML);
    }
})();
</script>
</body>
登录后复制

事件代理的处理方式,代码如下:

<body>
<ul id="color-list">
<li>red</li>
<li>orange</li>
<li>yellow</li>
<li>green</li>
<li>blue</li>
<li>indigo</li>
<li>purple</li>
</ul>
<script>
(function(){
    var colorList=document.getElementById("color-list");
    colorList.addEventListener(&#39;click&#39;,showColor,false);
    function showColor(e)
    {
        e=e||window.event;
        var targetElement=e.target||e.srcElement;
        if(targetElement.nodeName.toLowerCase()==="li"){
        alert(targetElement.innerHTML);
        }
    }
})();
</script>
</body>
登录后复制

2)、事件代理的好处

总结一下事件代理的好处:

  • 将多个事件处理器减少到一个,因为事件处理器要驻留内存,这样就提高了性能。想象如果有一个100行的表格,对比传统的为每个单元格绑定事件处理器的方式和事件代理(即table上添加一个事件处理器),不难得出结论,事件代理确实避免了一些潜在的风险,提高了性能。
  • DOM更新无需重新绑定事件处理器,因为事件代理对不同子元素可采用不同处理方法。如果新增其他子元素(a,span,p等),直接修改事件代理的事件处理函数即可,不需要重新绑定处理器,不需要再次循环遍历。

3)、事件代理的问题:【update20170502】

代码如下:事件代理同时绑定了li和span,当点击span的时候,li和span都会冒泡。

<li><span>li中的span的内容</span></li>

<script>
    $(document).on(&#39;click&#39;, &#39;li&#39;, function(e){
        alert(&#39;li li&#39;);
    });

    $(document).on(&#39;click&#39;, &#39;span&#39;, function(e){
        alert(&#39;li span&#39;);
    })
</script>
登录后复制

解决办法:

方法一:span的事件处理程序中阻止冒泡

 $(document).on(&#39;click&#39;, &#39;span&#39;, function(e){
        alert(&#39;li span&#39;);
        e.stopPropagation();
    })
登录后复制

方法二:li的事件处理程序中检测target元素

$(document).on(&#39;click&#39;, &#39;li&#39;, function (e) {
        if (e.target.nodeName == &#39;SPAN&#39;) {
            e.stopPropagation();
            return;
        }
        alert(&#39;li li&#39;);
    });
登录后复制

4)、事件代理的一个有趣应用【update20170502】

点击一个列表时,输出对应的索引

<script>
    var ul=document.querySelector(&#39;ul&#39;);
    var lis=ul.querySelectorAll(&#39;ul li&#39;);
    ul.addEventListener(&#39;click&#39;, function (e) {
        var target= e.target;
        if(target.nodeName.toUpperCase()===&#39;LI&#39;){
            alert([].indexOf.call(lis,target));
        }
    },false)
</script>
登录后复制

【相关推荐: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脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

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

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

如何使用WebSocket和JavaScript实现在线语音识别系统 如何使用WebSocket和JavaScript实现在线语音识别系统 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript实现在线语音识别系统引言:随着科技的不断发展,语音识别技术已经成为了人工智能领域的重要组成部分。而基于WebSocket和JavaScript实现的在线语音识别系统,具备了低延迟、实时性和跨平台的特点,成为了一种被广泛应用的解决方案。本文将介绍如何使用WebSocket和JavaScript来实现在线语音识别系

WebSocket与JavaScript:实现实时监控系统的关键技术 WebSocket与JavaScript:实现实时监控系统的关键技术 Dec 17, 2023 pm 05:30 PM

WebSocket与JavaScript:实现实时监控系统的关键技术引言:随着互联网技术的快速发展,实时监控系统在各个领域中得到了广泛的应用。而实现实时监控的关键技术之一就是WebSocket与JavaScript的结合使用。本文将介绍WebSocket与JavaScript在实时监控系统中的应用,并给出代码示例,详细解释其实现原理。一、WebSocket技

如何利用JavaScript和WebSocket实现实时在线点餐系统 如何利用JavaScript和WebSocket实现实时在线点餐系统 Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket实现实时在线点餐系统介绍:随着互联网的普及和技术的进步,越来越多的餐厅开始提供在线点餐服务。为了实现实时在线点餐系统,我们可以利用JavaScript和WebSocket技术。WebSocket是一种基于TCP协议的全双工通信协议,可以实现客户端与服务器的实时双向通信。在实时在线点餐系统中,当用户选择菜品并下单

如何使用WebSocket和JavaScript实现在线预约系统 如何使用WebSocket和JavaScript实现在线预约系统 Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript实现在线预约系统在当今数字化的时代,越来越多的业务和服务都需要提供在线预约功能。而实现一个高效、实时的在线预约系统是至关重要的。本文将介绍如何使用WebSocket和JavaScript来实现一个在线预约系统,并提供具体的代码示例。一、什么是WebSocketWebSocket是一种在单个TCP连接上进行全双工

JavaScript和WebSocket:打造高效的实时天气预报系统 JavaScript和WebSocket:打造高效的实时天气预报系统 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的实时天气预报系统引言:如今,天气预报的准确性对于日常生活以及决策制定具有重要意义。随着技术的发展,我们可以通过实时获取天气数据来提供更准确可靠的天气预报。在本文中,我们将学习如何使用JavaScript和WebSocket技术,来构建一个高效的实时天气预报系统。本文将通过具体的代码示例来展示实现的过程。We

简易JavaScript教程:获取HTTP状态码的方法 简易JavaScript教程:获取HTTP状态码的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教程:如何获取HTTP状态码,需要具体代码示例前言:在Web开发中,经常会涉及到与服务器进行数据交互的场景。在与服务器进行通信时,我们经常需要获取返回的HTTP状态码来判断操作是否成功,根据不同的状态码来进行相应的处理。本篇文章将教你如何使用JavaScript获取HTTP状态码,并提供一些实用的代码示例。使用XMLHttpRequest

javascript中如何使用insertBefore javascript中如何使用insertBefore Nov 24, 2023 am 11:56 AM

用法:在JavaScript中,insertBefore()方法用于在DOM树中插入一个新的节点。这个方法需要两个参数:要插入的新节点和参考节点(即新节点将要被插入的位置的节点)。

JavaScript和WebSocket:打造高效的实时图像处理系统 JavaScript和WebSocket:打造高效的实时图像处理系统 Dec 17, 2023 am 08:41 AM

JavaScript是一种广泛应用于Web开发的编程语言,而WebSocket则是一种用于实时通信的网络协议。结合二者的强大功能,我们可以打造一个高效的实时图像处理系统。本文将介绍如何利用JavaScript和WebSocket来实现这个系统,并提供具体的代码示例。首先,我们需要明确实时图像处理系统的需求和目标。假设我们有一个摄像头设备,可以采集实时的图像数

See all articles