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

当我自己处理事件时(没有框架),我总是检查两者,如果存在,就执行两者。(我也返回false,但我觉得这与node.addEventListener附加的事件不起作用)。

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

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


当前回答

这是这里的引语

Event.preventDefault

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

//clicking the link will *not* allow the user to leave the page 
myChildElement.onclick = function(e) { 
    e.preventDefault(); 
    console.log('brick me!'); 
};

//clicking the parent node will run the following console statement because event propagation occurs
logo.parentNode.onclick = function(e) { 
    console.log('you bricked my child!'); 
};

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

Event.stopPropagation

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

//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!'); 
};

stopPropagation有效地阻止父元素知道其子元素上的给定事件。

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

其他回答

术语

从quirksmode.org:

Event capturing When you use event capturing | | ---------------| |----------------- | element1 | | | | -----------| |----------- | | |element2 \ / | | | ------------------------- | | Event CAPTURING | ----------------------------------- the event handler of element1 fires first, the event handler of element2 fires last. Event bubbling When you use event bubbling / \ ---------------| |----------------- | element1 | | | | -----------| |----------- | | |element2 | | | | | ------------------------- | | Event BUBBLING | ----------------------------------- the event handler of element2 fires first, the event handler of element1 fires last. Any event taking place in the W3C event model is first captured until it reaches the target element and then bubbles up again. | | / \ -----------------| |--| |----------------- | element1 | | | | | | -------------| |--| |----------- | | |element2 \ / | | | | | -------------------------------- | | W3C event model | ------------------------------------------

接口

来自w3.org,用于事件捕获:

If the capturing EventListener wishes to prevent further processing of the event from occurring it may call the stopPropagation method of the Event interface. This will prevent further dispatch of the event, although additional EventListeners registered at the same hierarchy level will still receive the event. Once an event's stopPropagation method has been called, further calls to that method have no additional effect. If no additional capturers exist and stopPropagation has not been called, the event triggers the appropriate EventListeners on the target itself.

对于事件冒泡:

任何事件处理程序都可以选择通过 调用Event接口的stopPropagation方法。如果有任何 对象上的所有其他EventListener调用此方法 current EventTarget将被触发,但冒泡将在此停止 的水平。只需要调用一个stopPropagation来阻止进一步的操作 冒泡。

取消事件:

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

例子

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

HTML:

<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();
}

阻止打开新标签页。

event.preventDefault () 阻止浏览器的默认行为(例如打开链接),但不能阻止事件在DOM中冒泡。 event. stoppropagation()阻止事件在DOM中冒泡,但不会停止浏览器的默认行为。 通常在jQuery代码中看到,它防止浏览器的默认行为,防止事件冒泡 DOM,并立即从任何回调返回。

看看这篇非常漂亮和简单的4分钟阅读文章,上面的例子来自上面的文章。

事件。preventDefault-停止浏览器默认行为。现在来看看浏览器的默认行为。假设你有一个锚标签,它有一个href属性,这个锚标签嵌套在一个div标签中,这个div标签有一个点击事件。锚标签的默认行为是,当点击锚标签时,它应该导航,但什么事件。preventDefault的作用是在这种情况下停止导航。但它从未停止事件的冒泡或事件的升级

<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 anywhere
  console.log('element was clicked');
});

结果将是

"元素被点击"

"容器被点击"

现在的事件。停止传播:停止事件冒泡或事件升级。现在来看上面的例子

$('.container').on('click', function(e) {
  console.log('container was clicked');
});

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

结果将是

"元素被点击"

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

这是这里的引语

Event.preventDefault

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

//clicking the link will *not* allow the user to leave the page 
myChildElement.onclick = function(e) { 
    e.preventDefault(); 
    console.log('brick me!'); 
};

//clicking the parent node will run the following console statement because event propagation occurs
logo.parentNode.onclick = function(e) { 
    console.log('you bricked my child!'); 
};

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

Event.stopPropagation

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

//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!'); 
};

stopPropagation有效地阻止父元素知道其子元素上的给定事件。

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

$(" #但是”).click(函数(事件){ console.log(“hello”); event.preventDefault (); }); $ (" # foo ") .click(函数(){ 警报(“父点击事件触发!”); }); < script src = " https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js " > < /脚本> < div id = " foo " > <按钮id = "但是" > < /按钮>按钮 < / div >