event.stopPropagation 和 event.preventDefault 之间有什么区别?术语接口例子

他们似乎在做同样的事情...
一个是现代的,一个是旧的吗?或者它们是否受不同浏览器的支持?

当我自己处理事件(没有框架)时,我总是检查两者,如果存在,则执行两者。(我也是,但我有一种感觉,这与 所附的事件不起作用)。return falsenode.addEventListener

那么为什么两者兼而有之呢?我应该继续检查两者吗?还是真的有区别?

(我知道,很多问题,但它们都是一样的=))


答案 1

stopPropagation防止当前事件在捕获和冒泡阶段进一步传播。

preventDefault阻止浏览器对该事件执行的默认操作。

例子

预防缺省

$("#but").click(function (event) {
  event.preventDefault()
})
$("#foo").click(function () {
  alert("parent click event fired!")
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo">
  <button id="but">button</button>
</div>

停止传播

$("#but").click(function (event) {
  event.stopPropagation()
})
$("#foo").click(function () {
  alert("parent click event fired!")
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo">
  <button id="but">button</button>
</div>

使用 ,仅调用按钮的单击处理程序,而 div 的单击处理程序从不触发。stopPropagation

如果像使用 一样,只有浏览器的默认操作停止,但 div 的单击处理程序仍然触发。preventDefault

以下是有关MDN的DOM事件属性和方法的一些文档:

对于IE9和FF,你可以使用 preventDefault & stopPropagation。

要支持IE8及更低版本,请替换为和替换为stopPropagationcancelBubblepreventDefaultreturnValue


答案 2

术语

quirksmode.org

事件捕获

使用事件捕获时

               | |
---------------| |-----------------
| element1     | |                |
|   -----------| |-----------     |
|   |element2  \ /          |     |
|   -------------------------     |
|        Event CAPTURING          |
-----------------------------------

element1 的事件处理程序首先触发,element2 的事件处理程序最后触发。

事件冒泡

使用事件冒泡时

               / \
---------------| |-----------------
| element1     | |                |
|   -----------| |-----------     |
|   |element2  | |          |     |
|   -------------------------     |
|        Event BUBBLING           |
-----------------------------------

element2 的事件处理程序首先触发,element1 的事件处理程序最后触发。

首先捕获 W3C 事件模型中发生的任何事件,直到它到达目标元素,然后再次冒泡

                 | |  / \
-----------------| |--| |-----------------
| element1       | |  | |                |
|   -------------| |--| |-----------     |
|   |element2    \ /  | |          |     |
|   --------------------------------     |
|        W3C event model                 |
------------------------------------------

接口

w3.org 开始,用于事件捕获

如果捕获希望阻止事件的进一步处理发生,则可以调用接口的方法。这将阻止事件进一步调度,尽管在同一层次结构级别注册的其他事件仍将收到该事件。调用事件的方法后,对该方法的进一步调用不会产生其他影响。如果不存在其他捕获器并且尚未调用,则该事件将在目标本身上触发相应的捕获器。EventListenerstopPropagationEventEventListenersstopPropagationstopPropagationEventListeners

对于事件冒泡

任何事件处理程序都可以选择通过调用接口的方法来防止进一步的事件传播。如果有任何调用此方法,则将触发电流上的所有附加内容,但在该级别将停止冒泡。只需拨打一个电话即可防止进一步冒泡。stopPropagationEventEventListenerEventListenersEventTargetstopPropagation

对于事件取消

取消是通过调用 的方法来完成的。如果在事件流的任何阶段进行一个或多个调用,则默认操作将被取消。EventpreventDefaultEventListenerspreventDefault

例子

在以下示例中,单击 Web 浏览器中的超链接将触发事件流(执行事件侦听器)和事件目标的默认操作(打开新选项卡)。

网页:

<div id="a">
  <a id="b" href="http://www.google.com/" target="_blank">Google</a>
</div>
<p id="c"></p>

JavaScript:

var el = document.getElementById("c");

function capturingOnClick1(ev) {
    el.innerHTML += "DIV event capture<br>";
}

function capturingOnClick2(ev) {
    el.innerHTML += "A event capture<br>";
}

function bubblingOnClick1(ev) {
    el.innerHTML += "DIV event bubbling<br>";
}

function bubblingOnClick2(ev) {
    el.innerHTML += "A event bubbling<br>";
}

// The 3rd parameter useCapture makes the event listener capturing (false by default)
document.getElementById("a").addEventListener("click", capturingOnClick1, true);
document.getElementById("b").addEventListener("click", capturingOnClick2, true);
document.getElementById("a").addEventListener("click", bubblingOnClick1, false);
document.getElementById("b").addEventListener("click", bubblingOnClick2, false);

示例 1:它导致输出

DIV event capture
A event capture
A event bubbling
DIV event bubbling

示例 2:添加到函数stopPropagation()

function capturingOnClick1(ev) {
    el.innerHTML += "DIV event capture<br>";
    ev.stopPropagation();
}

结果在输出

DIV event capture

事件侦听器阻止了事件的进一步向下和向上传播。但是,它没有阻止默认操作(打开新选项卡)。

示例 3:添加到函数stopPropagation()

function capturingOnClick2(ev) {
    el.innerHTML += "A event capture<br>";
    ev.stopPropagation();
}

或函数

function bubblingOnClick2(ev) {
    el.innerHTML += "A event bubbling<br>";
    ev.stopPropagation();
}

结果在输出

DIV event capture
A event capture
A event bubbling

这是因为两个事件侦听器都注册在同一个事件目标上。事件侦听器阻止了事件的进一步向上传播。但是,他们没有阻止默认操作(打开新选项卡)。

示例 4:添加到任何函数,例如preventDefault()

function capturingOnClick1(ev) {
    el.innerHTML += "DIV event capture<br>";
    ev.preventDefault();
}

阻止新选项卡打开。