白话解释 Javascript事件preventDefault,stopPropagation及return false的区别

来源: 我的博客

想必好多童鞋都有直接复制粘贴event.preventDefault() 或者event.stopPropagation() 的经历,可是为何这样作不甚了解,今天咱们的目的就是要完全搞懂这一区别。javascript

javascript中的“事件传播”模式

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

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

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

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

因此。。github

捕获模式

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

冒泡模式

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

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

IE9如下仅仅支持冒泡模式,可是IE9+以及如今的主流浏览器都支持两种模式了。code

声明方式

用哪一种事件传播方式彻底是咱们本身说了算的,咱们可使用htm

addEventListener(type, listener, useCapture)

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

例子

<div id="outerMost">
    <div id="middle">
        <a href="" id="innerMost" >click</a>
    </div>
</div>

咱们能够对上述代码添加一些样式,这样在网页中更直观。

<div id="outerMost" style="border: 1px solid black; width: 150px; height: 120px; padding: 20px;">
    outerMost
    <div id="middle" style="border: 1px solid black; width: 60px; height: 60px; padding: 20px;">
        Middle
        <a href="" id="innerMost" style="border: 1px solid black; width: 30px; height: 20px; display: block; margin: 20px;">click</a>
    </div>
</div>

如图:图片描述

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

对最外层,中间层,最内层分别用“捕获”模式注册事件监听,咱们上面说了,若是使用捕获模式,那么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提供的一种特性。

来源:我的博客

相关文章
相关标签/搜索