他们似乎在做同样的事情......是一个现代的还是一个旧的?或者他们是否受到不同浏览器的支持?
当我自己处理事件(没有框架)时,我总是检查两者并执行两者(如果存在)。 (我也是return false
,但我觉得这与node.addEventListener
附带的事件不起作用。
为什么两者兼而有之?我应该继续检查两者吗?或者实际上是否存在差异?
(我知道,很多问题,但它们都是一样的=))
答案 0 :(得分:880)
stopPropagation
阻止事件冒泡事件链。
preventDefault
会阻止浏览器对该事件执行的默认操作。
假设你有
<div id="foo">
<button id="but" />
</div>
$("#foo").click(function() {
// mouse click on div
});
$("#but").click(function(ev) {
// mouse click on button
ev.stopPropagation();
});
示例强>
$("#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
仅调用按钮点击处理程序, divs点击处理程序永远不会触发。
如果只是preventDefault
,只有浏览器默认操作被停止,但div的点击处理程序仍然会触发。
以下是来自MDN
和MSDN
<强> MDN:强>
对于IE9和FF,你可以使用preventDefault&amp; stopPropagation。
支持IE8并将stopPropagation
替换为cancelBubble
并将preventDefault
替换为returnValue
答案 1 :(得分:206)
事件捕获
使用事件捕获时
| | ---------------| |----------------- | 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
。
事件冒泡:
任何事件处理程序都可以选择阻止进一步的事件传播 调用
stopPropagation
接口的Event
方法。如果有的话EventListener
调用此方法,所有额外的EventListeners
都在 当前EventTarget
将被触发,但冒泡将停止 水平。只需拨打stopPropagation
一次电话即可进一步阻止 鼓泡。
事件取消:
取消是通过致电
Event
&#39>preventDefault
来完成的 方法。如果有一个或多个EventListeners
来电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);
Example 1:它会产生输出
DIV event capture
A event capture
A event bubbling
DIV event bubbling
Example 2:将stopPropagation()
添加到函数
function capturingOnClick1(ev) {
el.innerHTML += "DIV event capture<br>";
ev.stopPropagation();
}
导致输出
DIV event capture
事件监听器阻止了事件的进一步向下和向上传播。但是它并没有阻止默认操作(新的选项卡打开)。
Example 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
这是因为两个事件侦听器都在同一个事件目标上注册。事件监听器阻止了事件的进一步向上传播。但是它们并没有阻止默认操作(新的标签打开)。
Example 4:将preventDefault()
添加到任何功能,例如
function capturingOnClick1(ev) {
el.innerHTML += "DIV event capture<br>";
ev.preventDefault();
}
阻止新标签打开。
答案 2 :(得分:55)
返回false;
当你打电话时, return false;
分别做三件事:
event.preventDefault()
- 它会停止浏览器的默认行为。event.stopPropagation()
- 它可以阻止事件传播(或“冒泡”)DOM。请注意,此行为与普通(非jQuery)事件处理程序不同,其中,return false
不会阻止事件冒泡。
<强>的preventDefault(); 强>
preventDefault();
做了一件事:它停止了浏览器的默认行为。
何时使用?
我们知道他们做了什么但是何时使用它们?这完全取决于你想要完成什么。如果您想“仅”阻止默认的浏览器行为,请使用preventDefault();
。使用return false;当您想要阻止默认浏览器行为并阻止事件传播DOM时。在大多数情况下你会使用return 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>
&#13;
运行上面的代码,你会看到超链接'点击这里访问 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>
&#13;
运行上面的代码,你会看到超链接'点击这里访问 stackoverflow.com'现在,如果你先点击该链接,你会得到 javascript提醒链接点击接下来,您将获得javascript 警告 div单击接下来,您将看到超链接'点击此处 访问stackoverflow.com'替换为文本'Click事件被阻止' 您将不重定向到stackoverflow.com。这是因为&gt; to 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>
&#13;
这次如果单击Link,则函数executeParent()不会 被叫,你不会得到javascript警告 div Clicked 这次。这是由于我们阻止了传播到 父div使用event.stopPropagation()方法。接下来你会看到 超链接'点击此处访问stackoverflow.com'替换为文本 '点击事件将被执行'并立刻就会被执行 重定向到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>
&#13;
如果单击Link,则函数executeParent()将不会 被叫,你不会得到javascript警报。这是由于我们 防止使用传播到父div event.stopPropagation()方法。接下来,您将看到超链接'Click 这里访问stackoverflow.com'替换为文本'Click事件 阻止',你不会被重定向到stackoverflow.com。这个 是因为我们阻止了触发默认点击操作 这次使用event.preventDefault()方法。
示例5:
对于return false,我有三个例子,所有似乎都做了完全相同的事情(只是返回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>
&#13;
<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>
&#13;
<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>
&#13;
希望这些例子清楚。尝试在html文件中执行所有这些示例,看看它们是如何工作的。
答案 3 :(得分:15)
这是here
的引用<强> 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%的时间!错误地&#34;停止&#34;一个事件可能会导致你 无数的麻烦;你的插件可能无法正常工作 第三方插件可能会被砖砌。或者更糟 - 你的代码 打破网站上的其他功能。
答案 4 :(得分:1)
event.preventDefault();
停止发生元素的默认操作。
event.stopPropagation();
防止事件冒泡DOM树,防止任何父处理程序被通知事件。
例如,如果在DIV
或FORM
内附加了点击方法的链接也附加了点击方法,则会阻止DIV
或{{ 1}}点击触发方法。
答案 5 :(得分:0)
Event.preventDefault-停止浏览器默认行为。现在是什么是浏览器默认行为。假设您有一个定位标记,并且具有href属性,并且该定位标记嵌套在具有click事件的div标记内。锚标记的默认行为是在锚标记上单击时应导航,但event.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');
});
结果将是
“元素被点击”
“已单击容器”
现在event.StopPropation它停止事件冒泡或事件升级。现在使用上面的示例
$('.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/
答案 6 :(得分:-3)
$("#but").click(function(event){
console.log("hello");
event.preventDefault();
});
$("#foo").click(function(){
alert("parent click event fired !");
});
&#13;
<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>
&#13;