资讯专栏INFORMATION COLUMN

白话解释 Javascript事件preventDefault,stopPropagation及re

chanjarster / 3244人阅读

摘要:如图使用事件捕获模式注册事件监听对最外层,中间层,最内层分别用捕获模式注册事件监听,我们上面说了,如果使用捕获模式,那么第三个参数应该是,否则则是冒泡模式,如果不声明,默认为冒泡模式。

来源: 个人博客

想必好多童鞋都有直接复制粘贴event.preventDefault() 或者event.stopPropagation() 的经历,但是为什么这样做不甚了解,今天我们的目的就是要彻底搞懂这一区别。

javascript中的“事件传播”模式

为了彻底弄清楚它们之间的区别,我不得不要先说一下javascript中两种事件传播模式:

- 捕获模式(capturing)
- 冒泡模式(bubbling)

捕获模式又称为“滴流模式”(trickling),个人认为滴流模式更好理解,滴流就是“从上向下”,而冒泡就是“从下向上”,好了,先记住这两种模式的特点。

同时你还要记住,这两种模式是为了干什么的?
这两种模式就是为了一点:决定html中“元素”(比如div, p, button)接收到事件的“顺序”!当然接收到事件的顺序不同,自然事件监听函数被触发的顺序就不同了,于是间接地就出现了监听函数被执行顺序的不同。

所以。。

捕获模式

当事件发生时,该事件首先被最外层元素接受到,然后依次向内层元素传播。(从上向下)

冒泡模式

当事件发生时,该事件首先被最内层元素接受到,然后依次向外层元素传播。(从下向上)

顺便提一句,以前网景公司主推捕获模式而微软则偏向于冒泡模式,不过两者都是W3C DOM事件标准(2000)。

IE9以下仅仅支持冒泡模式,但是IE9+以及现在的主流浏览器都支持两种模式了。

声明方式

用哪种事件传播方式完全是我们自己说了算的,我们可以使用

addEventListener(type, listener, useCapture)

来注册事件处理方式,以及以何种传播模式进行。

例子

我们可以对上述代码添加一些样式,这样在网页中更直观。

outerMost
Middle click

如图:

使用事件捕获模式注册事件监听

对最外层,中间层,最内层分别用“捕获”模式注册事件监听,我们上面说了,如果使用捕获模式,那么addEventListener第三个参数应该是true,否则则是冒泡模式,如果不声明,默认为冒泡模式。

var outerElement = document.getElementById("outerMost");
var middleElement = document.getElementById("middle");
var innerElement = document.getElementById("innerMost");

outerElement.addEventListener("click", function () {
    console.log("trigger outermost div");
}, true);
middleElement.addEventListener("click", function () {
    console.log("trigger middle div");
}, true);
innerElement.addEventListener("click", function () {
    console.log("trigger innermost button");
}, true);

我们点击中间层Middle字样,如图:

可以看到,事件触发从外向里进行,如果大家把addEventListener中第三个参数改为false或者留空,点击middle字样,则会得到相反的结果,大家可以自己试一下。

preventDefault 及 stopPropagation函数区别

终于到了谈一谈preventDefault 和 stopPropagation了,大家可能注意到了,我上面的例子中没有涉及到点击click链接,为什么呢?大家可以试一下,点击click会发生什么?它会又立即跳转到了当前页面(因为我们href是一个空连接,这是链接元素的一个默认特性),虽然我们的监听函数被执行了,但是有时候我们不想这个默认特性被执行,比如,我们可能想在监听函数里面改变div的背景颜色等等,这样如果这个链接元素a默认特性的存在就会立即“刷新”了该页面,让我们的改变背景颜色无法进行。

所以为了“阻止”元素的“默认特性”,所以事件对象中有了一个preventDefault方法,如下:

innerElement.addEventListener("click", function (event) {
    event.preventDefault();
    console.log("trigger innermost button");
}, true);

这样我们点击click就会得到:

trigger outermost div
trigger middle div
trigger innermost button

那么stopPropagation呢?
向上面这种情况,如果当你点击click的时候,只想出发绑定在click上的监听函数,而不想触发“传播链”上的其他函数,那么则使用stopPropagation。

注意:你在那个事件监听函数中使用event.stopPropagation();那么传播链就会终止,向上面这个例子,因为我们使用的是捕获模式,即使我们添加了:

innerElement.addEventListener("click", function (event) {
    event.preventDefault();
    event.stopPropagation();
    console.log("trigger innermost button");
}, true);

依然会得到和上面一样的结果,为什么呢?因为捕获模式是由外往里传播,我们只是在a这里阻止了继续像里传播,因为没有更里的元素了,所以结果一样,为了更好地演示,我们可以把捕获模式改为冒泡模式如下:

var outerElement = document.getElementById("outerMost");
var middleElement = document.getElementById("middle");
var innerElement = document.getElementById("innerMost");

outerElement.addEventListener("click", function (event) {
    console.log("trigger outermost div");
});
middleElement.addEventListener("click", function () {
    console.log("trigger middle div");
});
innerElement.addEventListener("click", function (event) {
    event.preventDefault();
    event.stopPropagation();
    console.log("trigger innermost button");
});

这样点击click,就只得到了一条log:

trigger innermost button
return false;

最后说一下return false; 这是jQuery中提供,比如:

$("#innermost").on("click", function () {
    return false;
})

它帮我们同时做了:

    - event.preventDefault();
    - event.stopPropagation();

这两个工作,你可以看做是一种快捷方式,但是你在原生javascript中的监听回调函数中写return false; 是没有任何用的。比如:

innerElement.addEventListener("click", function (event) {
    return false;
});

只是jQuery提供的一种特性。

来源:个人博客

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88117.html

相关文章

  • javascript经典问题总结代码实例(未完待续)

    摘要:在这段代码中,实际上就是闭包函数。定时器例子假设,某个事件处理程序使用设置了一个间隔的重复定时器。在下一个间隔,即处,第一个定时器代码仍在运行,同时在队列中已经有了一个定时器代码的实例。结果是,在这个时间点上的定时器代码不会被添加到队列中。 函数 匿名函数立即调用 (function (){alert(1)}()) function的左圆括号是必须的 函数的调用 1,作为函数的调用,2...

    刘福 评论0 收藏0
  • JavaScript 设计模式读书笔记(六)——门面模式

    摘要:简单的门面模式实例事件绑定函数门面模式的作用是将复杂的接口进行包装,变成一个便于使用的接口。还是以事件相关为例,事件绑定中还有两个常用的分别是和。 门面模式是什么,与其我去用笨拙的语言去解释,不如看下面这张图,曾经在网上很火的一张图片,说的是一位儿子为他的爸妈设置的电脑桌面。 showImg(http://segmentfault.com/img/bVcgHm); 有了这些起好名字...

    pubdreamcc 评论0 收藏0
  • DOM中的各种区别小节

    摘要:欢迎光临小弟博客我的博客原文中的各种区别小节参考普通添加事件和事件绑定的事件监听与捕获和冒泡和的区别 相信大家在DOM的实际开发与学习过程中,肯定也遇到不少需要比较的东西,这里我主要列比较以下几点,更多的区别和总结,希望想到和遇到的朋友给我留言哦。 clientHeight/scrollHeight/offsetHeight defer vs async 事件模型-捕获/目标/冒泡...

    Guakin_Huang 评论0 收藏0
  • jQuery源码解析之trigger()

    摘要:一和的作用和区别触发被选元素上的指定事件以及事件的默认行为比如表单提交不会引起事件比如表单提交的默认行为触发所有匹配元素的指定事件只触发第一个匹配元素的指定事件会冒泡不会冒泡二被点击了作用看一源码触发事件,是自定义事件的额外参数源码行解析本 showImg(https://segmentfault.com/img/remote/1460000019375685); 一、$().trig...

    Youngs 评论0 收藏0

发表评论

0条评论

chanjarster

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<