event.preventDefault() vs. return false (no jQuery)
我想知道
我做了一些测试,似乎
例如,如果使用旧模型添加事件处理程序
1
2
3elem.onclick = function(){
return false;
};然后,
return false 防止违约行为,如event.preventDefault() 。例如,如果使用
addEventListener 添加事件处理程序1
2
3
4
5
6
7elem.addEventListener(
'click',
function(e){
return false;
},
false
);那么,
return false 并不能阻止违约行为。
所有浏览器的行为都是这样吗?
我可以在哪里找到一些关于
我的问题只是简单的javascript,而不是jquery,所以请不要将其标记为even t.preventDefault()与return false的副本,即使这两个问题的标题几乎相同。
1.3.1中的W3C文档对象模型事件规范。事件注册接口声明EventListener中的
handleEvent
This method is called whenever an event occurs of the type
for which the EventListener interface was registered. [...] No Return
Value
1.2.4以下。事件取消文档还声明
Cancelation is accomplished by calling the Event's preventDefault
method. If one or more EventListeners call preventDefault during any
phase of event flow the default action will be canceled.
这将阻止您使用返回true/false可能在任何浏览器中产生的任何效果,并使用
更新
HTML5规范实际上指定了如何处理不同的返回值。HTML规范第7.1.5.1节规定
If return value is a WebIDL boolean false value, then cancel the
event.
除了"鼠标悬停"事件。
结论
我仍然建议在大多数项目中使用
这里有几个例子可以帮助人们更好地理解和解决他们的问题。好的。DR
- 直接在HTML标记中使用
onclick 或通过setAttribute('onclick'...) 使用EDOCX1在确保实际返回方面有其自身的缺陷,因为onclick= 的内容被包装到onclick 函数中。 - 当使用
onclick 时,您可以通过确保onclick 函数返回false…您的函数被包装…所以您需要执行onclick="return myHandler();" 或onclick="myHandler(); return false;" 或类似的操作来确保onclick返回false来取消事件。 - 使用AddEventListener时…返回false没有任何效果。规范中的接口表示返回类型void。改用event.preventDefault()。
- 您可以使用浏览器devtools
getEventListeners API查看事件侦听器的外观,以避免猜测,并检查事件处理程序是否未按预期运行。
例子
此示例特定于具有
我们有一个类
下面的示例在MacOS Mojave上的Google Chrome(71)中运行。好的。
一个主要的陷阱是假设
1 2 3 4 5 6 7 8 9 10 11 | function eventHandler (event) { // want to prevent link navigation alert('eventHandler ran'); return false; } function addEventListenerToElement () { var link = document.querySelector('.js-some-link-hook'); link.setAttribute('onclick', eventHandler); } addEventListenerToElement(); |
然后在浏览器devtools控制台中运行:好的。
1 2 3 | var el = document.querySelector('a.js-some-link-hook'), listener = getEventListeners(el).click[0].listener; console.log(''+listener); // to avoid truncation of output |
你知道:好的。
1 2 3 | function onclick(event) { function t(n){return alert("eventHandler ran"),!1} } |
这根本不起作用。使用
现在我们看到了这是如何工作的,我们可以修改代码来做我们想要做的任何事情。举例说明(不要使用此代码):好的。
1 2 3 4 5 6 7 8 9 10 11 | function eventHandler (event) { // want to prevent link navigation alert('eventHandler ran'); return false; } function addEventListenerToElement () { var link = document.querySelector('.js-some-link-hook'); link.setAttribute('onclick', 'return ('+eventHandler+')();'); } addEventListenerToElement(); |
您可以看到,我们已经将事件处理程序函数定义包装为字符串。具体来说:一个在前面有返回语句的自执行函数。好的。
再次在chrome devtools控制台中:好的。
1 2 3 | var el = document.querySelector('a.js-some-link-hook'), listener = getEventListeners(el).click[0].listener; console.log(''+listener); // to avoid truncation of output |
……显示:好的。
1 2 3 | function onclick(event) { return (function t(e){return alert("eventHandler ran"),!1})(); } |
…所以是的,这应该管用。我们的
1 2 3 4 5 6 7 8 9 10 11 | function eventHandler (event) { // want to prevent link navigation alert('eventHandler ran'); return false; } function addEventListenerToElement () { var link = document.querySelector('.js-some-link-hook'); link.addEventListener('click', eventHandler, false); } addEventListenerToElement(); |
浏览器开发工具:好的。
1 2 3 | var el = document.querySelector('a.js-some-link-hook'), listener = getEventListeners(el).click[0].listener; console.log(''+listener); // to avoid truncation of output |
结果:好的。
1 | function e(n){return alert("eventHandler ran"),!1} |
所以你已经看到了区别。我们没有包装在onclick函数中。所以我们的
所以它看起来应该起作用。点击链接,我们会收到警报。解除警报,页面导航/刷新。也就是说,返回false并没有取消事件。好的。
如果我们查找规范(请参阅底部的参考资料),我们会看到addEventListener的回调/处理程序函数不支持返回类型。我们可以返回我们想要的任何东西,但是由于它不是接口的一部分,所以没有任何效果。好的。
解决办法:用
1 2 3 4 5 6 7 8 9 10 11 | function eventHandler (event) { // want to prevent link navigation event.preventDefault(); alert('eventHandler ran'); } function addEventListenerToElement () { var link = document.querySelector('.js-some-link-hook'); link.addEventListener('click', eventHandler, false); } addEventListenerToElement(); |
浏览器开发工具…好的。
1 2 3 | var el = document.querySelector('a.js-some-link-hook'), listener = getEventListeners(el).click[0].listener; console.log(''+listener); // to avoid truncation of output |
给予。。。好的。
1 | function n(e){e.preventDefault(),alert("eventHandler ran")} |
……正如预期的那样。好的。
测试:获得警报。解除警报。没有页面导航或刷新…这是我们想要的。好的。资源
- https://www.w3.org/tr/dom41/dom eventtarget addeventListener
- 事件注册(例如AddEventListener)
- https://www.w3.org/tr/dom41/callbackdef事件侦听器
- 回调/处理程序/侦听器定义。
- 备注返回类型为空。IE返回值不是接口的一部分,没有任何效果。
- https://www.w3.org/tr/dom41/事件
- 事件对象(例如,event.preventdefault)
HTML5规范(https://www.w3.org/tr/html5/webappipis.html events)混淆了事物,因为它们在示例中同时使用了
The event handler processing algorithm for an event handler H and an Event object E is as follows:
Ok.
...
Ok.
Process return value as follows: ...
Ok.
If return value is a Web IDL boolean false value, then cancel the event.
Ok.
因此,这似乎意味着
但是,如果你看看他们对
An event handler has a name, which always starts with"on" and is followed by the name of the event for which it is intended.
Ok.
...
Ok.
Event handlers are exposed in one of two ways.
Ok.
The first way, common to all event handlers, is as an event handler IDL attribute.
Ok.
The second way is as an event handler content attribute. Event handlers on HTML elements and some of the event handlers on Window objects are exposed in this way.
Ok.
https://www.w3.org/tr/html5/webappipis.html事件处理程序好的。
因此,似乎取消事件的
preventdefault、stopperopogation、return false之间的差异
默认操作–控制事件引发时的服务器端操作。
假设我们有一个DIV控件,其中有一个按钮。所以DIV是按钮的父控件。按钮的客户端单击和服务器端单击事件。我们还有DIV的客户端点击事件。
在客户端按钮的click事件上,我们可以通过以下三种方式控制父控件和服务器端代码的操作:
return false —这只允许控件的客户端事件。未激发父控件的服务器端事件和客户端事件。preventDefault() —这允许客户端控制事件及其父控制。服务器端事件,即不激发控件的默认操作。stopPropogation() –这允许控制的客户端和服务器端事件。不允许控件的客户端事件。