在 JavaScript 事件处理中,为啥“return false”或“event.preventDefault()”和“停止事件流”会有所不同?

Posted

技术标签:

【中文标题】在 JavaScript 事件处理中,为啥“return false”或“event.preventDefault()”和“停止事件流”会有所不同?【英文标题】:In JavaScript event handling, why "return false" or "event.preventDefault()" and "stopping the event flow" will make a difference?在 JavaScript 事件处理中,为什么“return false”或“event.preventDefault()”和“停止事件流”会有所不同? 【发布时间】:2011-03-03 19:07:00 【问题描述】:

据说我们在处理“点击事件”的时候,返回false或者调用event.preventDefault()会有所不同,其中

不同之处在于 preventDefault 只会阻止默认事件 发生的动作,即页面重定向 点击链接,提交表单, 等等,返回 false 也将停止 事件流。

这是否意味着,如果点击事件为多个操作注册了多次,使用

$('#clickme').click(function()  … )

返回 false 将停止其他处理程序的运行?

我现在在 Mac 上,所以只能使用 Firefox 和 Chrome,但不能使用 IE,它具有不同的事件模型,并通过添加 3 个处理程序在 Firefox 和 Chrome 上进行了测试,所有 3 个处理程序都在没有任何停止的情况下运行......。那么真正的区别是什么,或者,是否存在“停止事件流”不可取的情况?

这与

有关

Using jQuery's animate(), if the clicked on element is "<a href="#" ...> </a>", the function should still return false?

What's the difference between e.preventDefault(); and return false?

【问题讨论】:

见:Event Flow 【参考方案1】:

希望这段代码能给你解释一下……

html

<div>
<a href="index.html" class="a1">click me</a>
<a href="index.html" class="a2">click me</a>
</div>​

jquery

$('div').click(function()
    alert('I am from <div>');
);

$('a.a1').click(function()
    alert('I am from <a>');
    return false; // this will produce one alert
);

$('a.a2').click(function(e)
    alert('I am from <a>');
    e.preventDefault(); // this will produce two alerts
);​

demo

$('div').click(function()
    alert('I am from <div>');
);

$('a').click(function()
    alert('I am from <a>');
);

$('a.a1').click(function()
    alert('I am from <a class="a1">');
    return false;
);

$('a.a2').click(function(e)
    alert('I am from <a class="a2">');
    e.preventDefault();
);​

demo 2

【讨论】:

【参考方案2】:

写入return falsee.preventDefault() 不会阻止其他处理程序运行。

相反,它们会阻止浏览器的默认反应,例如导航到链接。

在 jQuery 中,您可以编写 e.stopImmediatePropagation() 以防止其他处理程序运行。

【讨论】:

【参考方案3】:

return falsepreventDefault() 用于阻止浏览器与事件相关联的默认操作(例如,单击链接时跟随该链接)。对于三种不同场景中的每一种,都有不同的技术来实现这一点:

1.使用 addEventListener()(非 IE 浏览器) 添加的事件处理程序。在这种情况下,请使用Event 对象的preventDefault() 方法。该事件的其他处理程序仍将被调用。

function handleEvent(evt) 
    evt.preventDefault();

2。使用attachEvent() (IE) 添加的事件处理程序。在这种情况下,将window.eventreturnValue 属性设置为true。该事件的其他处理程序仍将被调用,并且也可能更改此属性。

function handleEvent() 
    window.event.returnValue = false;

3.使用属性或事件处理程序属性添加的事件处理程序

<input type="button" value="Do stuff!" onclick="return handleEvent(event)">

button.onclick = handleEvent;

在这种情况下,return false 将完成这项工作。通过addEventListener()attachEvent() 添加的任何其他事件处理程序仍将被调用。

function handleEvent() 
    return false;

【讨论】:

【参考方案4】:

有时一个事件监听器想要取消事件的副作用是感兴趣的。想象一个你希望只允许数字的文本框。因为文本框可以接受任何内容,所以有必要告诉浏览器忽略输入的非数字。这是通过监听键事件并在键入错误键时返回 false 来实现的。

【讨论】:

【参考方案5】:

这并不能完全回答您的问题,但前几天我在 &lt;a&gt; 元素上使用 YUI 的 e.preventDefault() 来压缩 href 操作,因为我只希望 javascript onclick 事件具有控制权(除非没有检测到 JS)。在这种情况下,停止整个事件链不会影响我。

但在那之前的几天,我有一个 &lt;input type="checkbox"&gt; 嵌套在 &lt;label&gt; 元素中,我必须在事件处理程序中使用条件来确定单击的目标是否是标签,因为 e.preventDefault() 都不是e.stopEvent() 也没有阻止我的“点击”事件从 (legitimately) 触发两次(IE6 除外)。

如果我已经尝试过传播和return false ;,那么能够压缩整个相关事件链会更好,但由于我的标签元素,我总是会触发第二个事件。


编辑:如果有人愿意对此发表评论,我不介意知道 jQuery 将如何处理我的双重事件情况。

【讨论】:

以上是关于在 JavaScript 事件处理中,为啥“return false”或“event.preventDefault()”和“停止事件流”会有所不同?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在使用 javascript 自动完成时在 Eclipse 中收到消息:“未处理的事件循环异常 Java 堆空间”?

为啥 onkeyup 事件不会在 Javascript 游戏中触发

为啥使用 element.innerHTML 后事件监听器会停止工作?

为啥以及何时需要在 React 中绑定函数和事件处理程序?

为啥 bind() 在 Vue 模板事件处理程序中的工作方式如此不一致?

为啥警告:未知事件处理程序属性`onSession`显示在 React 应用程序中?