广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >基于事件冒泡、事件捕获和事件委托详解
  • 566
分享到

基于事件冒泡、事件捕获和事件委托详解

2024-04-02 19:04:59 566人浏览 泡泡鱼
摘要

事件冒泡、事件捕获和事件委托 在javascript里,事件委托是很重要的一个东西,事件委托依靠的就是事件冒泡和捕获的机制,我先来解释一下事件冒泡和事件捕获: 事件冒泡会从当前触发

事件冒泡、事件捕获和事件委托

javascript里,事件委托是很重要的一个东西,事件委托依靠的就是事件冒泡和捕获的机制,我先来解释一下事件冒泡和事件捕获:

事件冒泡会从当前触发的事件目标一级一级往上传递,依次触发,直到document为止。

事件捕获会从document开始触发,一级一级往下传递,依次触发,直到真正事件目标为止。

这么说是不是很抽象,其实就像我敲击了一下键盘,我在敲击键盘的同时,我是不是也敲击了这台电脑,我写个例子大家就明白了:


<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <style type="text/CSS">
        #box1 { width: 300px; height: 300px; background: blueviolet; }
        #box2 { width: 200px; height: 200px; background: aquamarine; }
        #box3 { width: 100px; height: 100px; background: tomato; }
        div { overflow: hidden; margin: 50px auto; }
    </style>
    <body>
        <div id="box1">
            <div id="box2">
                <div id="box3"></div>
            </div>
        </div>
        <script>
            function sayBox3() {
                console.log('你点了最里面的box');
            }
            function sayBox2() {
                console.log('你点了最中间的box');
            }
            function sayBox1() {
                console.log('你点了最外面的box');
            }
            // 事件监听,第三个参数是布尔值,默认false,false是事件冒泡,true是事件捕获
            document.getElementById('box3').addEventListener('click', sayBox3, false);
            document.getElementById('box2').addEventListener('click', sayBox2, false);
            document.getElementById('box1').addEventListener('click', sayBox1, false);
        </script>
    </body>
</html>

我们画了三个box,结构是父子关系,分别绑定了打印事件,现在我们来点击最中间的红色box:

我们发现,我们仅仅是点击了红色的box,但是绿色和紫色的box也被触发了打印事件,触犯顺序是 红色>绿色>紫色,这种现象就是事件冒泡了。

我们再试试事件捕获,把上面代码里监听事件的第三个参数改为true,然后点击红色的box:

我们还是只点击最中间的红色box,和上一次一样,也是三个box都触发了事件,但是顺序反过来了,紫色>绿色>红色,这种现象称为事件捕获。

通过上面的例子,应该很容易就理解了事件冒泡和事件捕获,我们平时都是默认冒泡的,冒泡是一直冒到document根文档为止。

现在来谈谈事件委托,事件委托又称之为事件代理,我们通过一个通俗的例子来解释:

有三个同事预计会在周一收到快递,为了签收快递,有两种办法:1.三个人在公司门口等快递;2.委托给前台MM代为签收。现实当中,我们大都采用委托的方案(公司也不会容忍那么多员工站在门口就为了等快递)。前台MM收到快递后,她会判断收件人是谁,然后按照收件人的要求签收,甚至代为付款。这种方案还有一个优势,那就是即使公司里来了新员工(不管多少),前台MM也会在收到寄给新员工的快递后核实并代为签收(可以给暂时不存在的节点也绑定上事件)。

我们再举另一个例子:

现在有一个ul,ul里又有100个li,我想给这100个li都绑定一个点击事件,我们一般可以通过for循环来绑定,但是要是有1000个li呢? 为了提高效率和速度,所以我们这时可以采用事件委托,只给ul绑定一个事件,根据事件冒泡的规则,只要你点了ul里的每一个li,都会触发ul的绑定事件,我们在ul绑定事件的函数里通过一些判断,就可以给这100li都触发点击事件了。

具体怎么实现,看代码:


// 这里不讲IE,结尾再说
function clickLi() {
    alert('你点击了li');
}
document.getElementById('isUl').addEventListener('click', function(event) {
    // 每一个函数内都有一个event事件对象,它有一个target属性,指向事件源
    var src = event.target;
    // 我们判断如果target事件源的节点名字是li,那就执行这个函数
    // target里面的属性是非常多的,id名、class名、节点名等等都可以取到
    if(src.nodeName.toLowerCase() == 'li') {
       clickLi() ;
    }
});

这样我们就通过给ul绑定一个点击事件,让所有的li都触发了函数。

那如果想给不同的li绑定不同的函数怎么办?

假设有3个li,我们先写3个不同的函数,再给3个li设置不同的id名,通过判断id名是不是就能给不同的li绑定不同的函数啦:


<body>
    <ul id="isUl">
        <li id="li01">1</li>
        <li id="li02">2</li>
        <li id="li03">3</li>
    </ul>
    <script>
        function clickLi01() {
            alert('你点击了第1个li');
        }
        function clickLi02() {
            alert('你点击了第2个li');
        }
        function clickLi03() {
            alert('你点击了第3个li');
        }
        document.getElementById('isUl').addEventListener('click', function(event) {
            var srcID = event.target.id;
            if(srcID == 'li01'){
                clickLi01();
            }else if(srcID == 'li02') {
                clickLi02();
            }else if(srcID == 'li03') {
                clickLi03();
            }
        });
    </script>
</body>

这就是所谓的事件委托,通过监听一个父元素,来给不同的子元素绑定事件,减少监听次数,从而提升速度。

那么,能不能阻止元素的事件冒泡呢,答案是可以的。

一开始那个例子,假如我们真的只想点击最里面的那个红色box,不想另外两个box的事件被触发,我们可以在给红色box绑定事件的函数里这么写:


function sayBox3(event) {
    // 阻止冒泡
    event.stopPropagation();
    console.log('你点了最里面的box');
}
document.getElementById('box3').addEventListener('click', sayBox3, false);

这样我们再点击红色的box,那就只会触发它本身的事件啦。

那阻止冒泡有没有实际用途呢?答案是有的,我们看这个例子:

这是一个模态框,现在的需求是当我们点击红色的按钮需要跳转页面,然后点击白色的对话框不需要任何反应,点其它任何地方就关闭这个模态框。

这里就需要用到阻止冒泡了,红色的按钮是白色对话框的子元素,白色对话框又是这整个模态框的子元素,我们给模态框加上一个点击事件关闭,然后给红色的按钮加上一个点击事件跳转,这时就产生了一个问题,只要点击白色的对话框,由于冒泡机制,这个模态框也会关闭,实际上我们并不想点击白色的对话框有任何反应,这时我们就给这个白色的对话框绑定一个点击事件,函数里写上event.stopPropagation();,这样就OK了。

关于IE

老版本的IE存在兼容问题,根本不支持addEventListener()的添加事件和removeEventListener()的删除事件,它有自己的监听方法:


// 添加事件,事件流固定为冒泡
attachEvent(事件名,事件处理函数)
// 删除事件
detachEvent(事件名,事件处理函数)

还有IE里的事件对象是window.event,事件源是srcElement,阻止冒泡写法也不一样:


function() {
    // IE里阻止冒泡
    window.event.cancelBubble = true;
    // IE里获取事件源的id
    var srcID = window.event.srcElement.id;
}
function(event) {
    // 非IE里阻止冒泡
    event.stopPropagation();
    // 非IE里获取事件源的id
    var srcID = event.target.id;
}

补充

关于js的浏览器兼容问题,一般用能力检测来解决,if(){}else{}

我们平时工作一般都是用Jquery,IE这些特殊情况早就帮我们做好兼容啦。

jquery在1.7的版本之后,最流行的事件监听方法是$(元素).on(事件名,执行函数),它还有一种事件委托的写法$(委托给哪个元素).on(事件名,被委托的元素,执行函数)

最后说一点,如果元素被阻止冒泡了,千万别去用事件委托的方式监听事件,因为事件委托的原理是利用事件冒泡,当冒泡被阻止,就无法监听了。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: 基于事件冒泡、事件捕获和事件委托详解

本文链接: https://www.lsjlt.com/news/130062.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 基于事件冒泡、事件捕获和事件委托详解
    事件冒泡、事件捕获和事件委托 在javascript里,事件委托是很重要的一个东西,事件委托依靠的就是事件冒泡和捕获的机制,我先来解释一下事件冒泡和事件捕获: 事件冒泡会从当前触发...
    99+
    2022-11-12
  • javascript事件冒泡,事件捕获和事件委托详解
    1、事件冒泡:在javascript事件传播过程中,当事件在一个元素上出发之后,事件会逐级传播给先辈元素,直到document为止,有的浏览器可能到window为止。并不是所有的事件...
    99+
    2022-11-12
  • JavaScript 事件捕获冒泡与捕获详情
    目录一、事件流1、概念2、DOM事件流二、事件委托1、事件委托的优点2、事件委托的使用三、禁止事件冒泡与捕获四、参考文献一、事件流 JavaScript中,事件流指的是DOM事件流。...
    99+
    2022-11-12
  • 浅析js中事件冒泡与事件捕获
    目录01-事件冒泡1.1-事件冒泡介绍1.2-事件冒泡利用(事件委托)1.3-事件冒泡影响 与 阻止事件冒泡02-事件捕获1.1-事件捕获介绍1.2-事件三个阶段01-事件冒泡 1...
    99+
    2022-11-12
  • JavaScript事件捕获冒泡分析
    本篇内容主要讲解“JavaScript事件捕获冒泡分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JavaScript事件捕获冒泡分析”吧!一、事件流JavaScript中,事件流指的是DOM...
    99+
    2023-06-25
  • js事件冒泡与事件捕获的示例分析
    这篇文章给大家分享的是有关js事件冒泡与事件捕获的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。(一)事件绑定1.普通事件绑定给html添加一个以on开头的特定的属性(如...
    99+
    2022-10-19
  • Javascript事件的捕获方式和冒泡方式详解
    目录一、事件处理模型1、事件冒泡(1)给三个div元素绑定事件(2)运行结果:2、事件捕获(1)给三个div元素绑定事件(2)运行结果:二、阻止事件冒泡(1)w3c标准 event....
    99+
    2022-11-12
  • JavaScript中怎么捕捉事件和阻止冒泡事件
    JavaScript中怎么捕捉事件和阻止冒泡事件,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。一、要探究捕获和冒泡事件,首先要...
    99+
    2022-10-19
  • js事件委托详解
    1、每个函数都是对象,占用内存。内存中的对象越多,性能越差。解决事件处理过多问题的办法是事件委托。 2、事件委托冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。 实例 ...
    99+
    2022-11-12
  • js事件流、事件委托与事件阶段实例详解
    目录前言1、事件流2、事件处理程序3、事件对象4、跨浏览器事件处理5、事件委托总结前言 JavaScript 与 HTML 的交互是通过事件实现的,事件代表文档或浏览器窗口中某个有意...
    99+
    2022-11-13
  • c#委托与事件(详解)
    目录前言一、声明方法二、声明委托三、实例化委托四、使用委托总结前言 .NET中的委托是一个类,它定义了方法的类型,是一个方法容器。委托把方法当作参数,可以避免在程序中大量使用条件判...
    99+
    2022-11-12
  • 如何进行JS中的事件冒泡与捕获
    这期内容当中小编将会给大家带来有关如何进行JS中的事件冒泡与捕获,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。刚接触 JS 的那个时候,啥也不懂,只想着如何利用 Goog...
    99+
    2022-10-19
  • JavaScript中的事件冒泡与捕获怎么实现
    这篇文章主要讲解了“JavaScript中的事件冒泡与捕获怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript中的事件冒泡与捕获怎么实...
    99+
    2022-10-19
  • C#中的委托和事件详解
    从大学就开始做C#这块,也做C#几年了,最近又从ios转回.Net,继续做C#,之前也没有写博客的习惯,写博客也是从我做ios的时候开始的,现在既然又做回了.net,那就写点关于.N...
    99+
    2022-11-13
  • 事件冒泡、事件委托、jQuery元素节点操作、滚轮事件与函数节流的示例分析
    这篇文章主要介绍事件冒泡、事件委托、jQuery元素节点操作、滚轮事件与函数节流的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、事件冒泡定义事件冒泡是指在一个对象触发某类...
    99+
    2022-10-19
  • JavaScript中如何实现事件冒泡与时间捕获
    小编给大家分享一下JavaScript中如何实现事件冒泡与时间捕获,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!一、事件冒泡与事件捕获当我们在Web页面单击某一个元素的时候,比如某个p元素...
    99+
    2022-10-19
  • 如何实现Javascript事件的捕获方式和冒泡方式
    这篇文章将为大家详细讲解有关如何实现Javascript事件的捕获方式和冒泡方式,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、事件处理模型事件冒泡、捕获:事件冒泡和事件捕获分别由微软和网景公司提出,这...
    99+
    2023-06-22
  • 微信小程序事件绑定传参冒泡及捕获的示例详解
    目录常见的事件有:currentTarget和target的区别事件传递参数touches和changedTouches的区别事件的绑定两种方法事件传参事件的冒泡与事件的捕获小结常见...
    99+
    2022-11-13
  • JavaScript中事件委托的示例详解
    目录事件流事件委托结尾大家好,我是前端西瓜哥。今天我们来认识一下事件委托。 所谓事件委托,就是将原本应该在当前元素绑定的事件,放到它的祖先元素上,让祖先元素来委托处理。 事件流 事件...
    99+
    2022-11-13
  • C#委托和事件怎么理解
    这篇文章主要介绍“C#委托和事件怎么理解”,在日常操作中,相信很多人在C#委托和事件怎么理解问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C#委托和事件怎么理解”的疑惑有所帮助!接下来,请跟着小编一起来学习吧...
    99+
    2023-06-17
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作