event.stop传播和event.prevent默认值有什么区别?

他们似乎在做同样的事情…
一个是现代的,一个是旧的?还是它们被不同的浏览器支持?

当我自己处理事件(没有框架)时,我总是检查两者,如果存在,则执行两者。(我也是return false,但我有一种感觉,不适用于附带node.addEventListener的事件)。

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

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

592510 次浏览

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>

对于stopPropagation,只有#1的单击处理程序被调用,而#2的单击处理程序永远不会触发。

如果您使用preventDefault,则仅停止浏览器的默认操作,但div的单击处理程序仍会触发。

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

对于IE9和FF,您可以只使用预防默认和停止传播。

要支持IE8和更低版本,请将stopPropagation替换为cancelBubble,将preventDefault替换为returnValue

这是这里中的引语

Event.prevent默认

预防默认方法可防止事件执行其默认功能。例如,您可以在A元素上使用预防默认值来阻止单击该元素离开当前页面:

//clicking the link will *not* allow the user to leave the pagemyChildElement.onclick = function(e) {e.preventDefault();console.log('brick me!');};
//clicking the parent node will run the following console statement because event propagation occurslogo.parentNode.onclick = function(e) {console.log('you bricked my child!');};

虽然元素的默认功能是砖砌的,但事件继续冒泡DOM。

Event.stop传播

第二个方法,停止传播,允许事件的默认功能发生,但阻止事件传播:

//clicking the element will allow the default action to occur but propagation will be stopped...myChildElement.onclick = function(e) {e.stopPropagation();console.log('prop stop! no bubbles!');};
//since propagation was stopped by the child element's onClick, this message will never be seen!myChildElement.parentNode.onclick = function(e) {console.log('you will never see this message!');};

停止传播有效地阻止父元素了解其子元素上的给定事件。

虽然一个简单的停止方法允许我们快速处理事件,但重要的是要考虑你到底想要发生什么冒泡。我敢打赌,开发人员真正想要的是预防默认值90%的时间!错误地“停止”事件可能会导致您许多麻烦;您的插件可能无法工作,您的第三方插件可能被砖块。或者更糟的是——你的代码破坏网站上的其他功能。

术语

quirksmode.org

事件捕获

当您使用事件捕获时

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

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

事件冒泡

当你使用事件冒泡

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

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

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

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

接口

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

如果捕获EventListener希望阻止进一步处理事件发生时,它可以调用stopPropagation方法Event接口。这将阻止事件的进一步调度,虽然其他EventListeners注册在同一层次结构中级别仍将接收事件。一旦事件stopPropagation方法已被调用,对该方法的进一步调用没有附加效果。如果没有额外的俘虏存在并且stopPropagation未被调用,事件触发在目标本身上适当的EventListeners

对于冒泡

任何事件处理程序都可以选择通过以下方式防止进一步的事件传播调用Event接口的stopPropagation方法。如果有的话EventListener调用此方法,所有额外的EventListeners当前EventTarget将被触发,但冒泡将在此时停止水平。只需要调用stopPropagation一次即可防止进一步冒泡。

对于活动取消

取消是通过调用EventpreventDefault来完成的方法。如果一个或多个EventListeners调用preventDefault事件流的任何阶段,默认操作都将被取消。

示例

在以下示例中,单击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 captureA event captureA event bubblingDIV 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 captureA event captureA event bubbling

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

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

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

阻止打开新选项卡。

event.preventDefault();停止元素的默认操作发生。

event.stopPropagation();防止事件在DOM树中冒泡,防止任何父处理程序收到事件通知。

例如,如果在DIVFORM中附加了一个具有单击方法的链接,该链接也附加了一个单击方法,它将阻止DIVFORM单击方法触发。

返回false;


当你调用它时,return false;做了3件不同的事情:

  1. event.preventDefault()-它停止浏览器的默认行为。
  2. event.stopPropagation()-它防止事件传播(或“冒泡”)DOM。
  3. 停止回调执行并在调用时立即返回。

请注意,此行为不同于普通(非jQuery)事件处理程序,其中,值得注意的是,return false不会阻止事件冒泡。

//预防默认值


preventDefault();做了一件事:它停止浏览器的默认行为。

什么时候使用它们?


我们知道它们的作用,但什么时候使用它们?简单地说,这取决于你想完成什么。如果你想“只是”阻止默认浏览器行为,请使用preventDefault();。当你想阻止默认浏览器行为并阻止事件传播DOM时,请使用返回false。在大多数情况下,你会使用返回false;你真正想要的是preventDefault()

示例:


让我们试着用例子来理解:

我们将看到纯JAVASCRIPT示例

示例1:

<div onclick='executeParent()'><a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a></div><script>function executeChild() {alert('Link Clicked');}
function executeParent() {alert('div Clicked');}</script>

运行上面的代码,你会看到超链接'点击这里访问stackoverflow.com'现在如果你先点击那个链接,你会得到javascript警报链接点击接下来你会得到javascript警告div点击,您将立即被重定向到stackoverflow.com.

示例2:

<div onclick='executeParent()'><a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a></div><script>function executeChild() {event.preventDefault();event.currentTarget.innerHTML = 'Click event prevented'alert('Link Clicked');}
function executeParent() {alert('div Clicked');}</script>

运行上面的代码,你会看到超链接点击这里访问stackoverflow.com'现在如果你点击该链接首先你会得到javascript警报链接点击接下来你会得到javascript警报div点击接下来,您将看到超链接'单击此处访问stackoverflow.com'替换为文本'单击事件预防'您将没有重定向到stackoverflow.com.这是由于>event.preventDefault()方法我们用来防止默认单击要触发的操作。

示例3:

<div onclick='executeParent()'><a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a></div><script>function executeChild() {event.stopPropagation();event.currentTarget.innerHTML = 'Click event prevented'alert('Link Clicked');}
function executeParent() {alert('div Clicked');}</script>

这一次,如果你点击链接,函数执行父()将不会被调用,您将不会收到JavaScript警报div点击这一次。这是由于我们阻止了传播到使用event.stop传播()方法的父div。接下来,您将看到超链接“单击此处访问stackoverflow.com”被文本替换'Click事件将被执行',您将立即执行重定向到stackoverflow.com.这是因为我们没有阻止默认的单击操作触发这一次使用event.preventDefault()方法。

例4:

<div onclick='executeParent()'><a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a></div><script>function executeChild() {event.preventDefault();event.stopPropagation();event.currentTarget.innerHTML = 'Click event prevented'alert('Link Clicked');}
function executeParent() {alert('Div Clicked');}</script>

如果您单击链接,则不会出现执行父()函数调用,你不会得到JavaScript警报。这是由于我们使用阻止传播到父divevent.stop传播()方法。接下来,您将看到超链接单击此处访问stackoverflow.com'替换为文本'点击事件已阻止,您将不会被重定向到stackoverflow.com.是因为我们阻止了默认的点击操作触发这次使用event.preventDefault()方法。

例5:

对于返回false,我有三个例子,它们似乎都在做同样的事情(只是返回false),但实际上结果是完全不同的。这是实际发生在每个上面的。

案例:

  1. 从内联事件处理程序返回虚假会阻止浏览器导航到链接地址,但不会阻止事件通过DOM传播。
  2. 从jQuery事件处理程序返回虚假会阻止浏览器导航到链接地址,并阻止事件通过DOM传播。
  3. 从常规DOM事件处理程序返回虚假绝对没有任何作用。

我们将看到这三个例子。

  1. 内联返回false。

<div onclick='executeParent()'><a href='https://stackoverflow.com' onclick='return false'>Click here to visit stackoverflow.com</a></div><script>var link = document.querySelector('a');
link.addEventListener('click', function() {event.currentTarget.innerHTML = 'Click event prevented using inline html'alert('Link Clicked');});

function executeParent() {alert('Div Clicked');}</script>

  1. 从jQuery事件处理程序返回虚假

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><div><a href='https://stackoverflow.com'>Click here to visit stackoverflow.com</a></div><script>$('a').click(function(event) {alert('Link Clicked');$('a').text('Click event prevented using return FALSE');$('a').contents().unwrap();return false;});$('div').click(function(event) {alert('Div clicked');});</script>

  1. 从常规DOM事件处理程序返回false。

<div onclick='executeParent()'><a href='https://stackoverflow.com' onclick='executeChild()'>Click here to visit stackoverflow.com</a></div><script>function executeChild() {event.currentTarget.innerHTML = 'Click event prevented'alert('Link Clicked');return false}
function executeParent() {alert('Div Clicked');}</script>

希望这些示例很清楚。尝试在html文件中执行所有这些示例以查看它们是如何工作的。

$("#but").click(function(event){console.log("hello");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>

Event.preventDefault-停止浏览器默认行为。现在是浏览器默认行为。假设你有一个锚标签,它有一个href属性,这个锚标签嵌套在一个有点击事件的div标签中。锚标签的默认行为是当点击它应该导航的锚标签时,但默认event.prevent做的是在这种情况下停止导航。但它永远不会停止事件的冒泡或事件的升级,即

<div class="container"><a href="#" class="element">Click Me!</a></div>
$('.container').on('click', function(e) {console.log('container was clicked');});
$('.element').on('click', function(e) {e.preventDefault(); // Now link won't go anywhereconsole.log('element was clicked');});

结果将是

"元素被点击"

"容器已点击"

现在事件。StopPropation它停止事件的冒泡或事件的升级。现在有了上面的例子

$('.container').on('click', function(e) {console.log('container was clicked');});
$('.element').on('click', function(e) {e.preventDefault(); // Now link won't go anywheree.stopPropagation(); // Now the event won't bubble upconsole.log('element was clicked');});

结果将是

"元素被点击"

更多信息请参考此链接https://codeplanet.io/preventdefault-vs-stoppropagation-vs-stopimmediatepropagation/

event.preventDefault()
防止浏览器的默认行为(例如打开链接),但不会阻止事件冒泡DOM。

event.stop传播()
防止事件冒泡DOM,但不会停止浏览器的默认行为。

返回false;
通常在jQuery代码中看到,它防止浏览器的默认行为,防止事件冒泡DOM,并立即从任何回调返回。

看看这个非常好&容易4分钟阅读,上面的作品是在哪里拍摄的。