关于javascript:event.preventDefault()与return false(没有jQuery)

event.preventDefault() vs. return false (no jQuery)

我想知道event.preventDefault()return false是否相同。

我做了一些测试,似乎

  • 例如,如果使用旧模型添加事件处理程序

    1
    2
    3
    elem.onclick = function(){
        return false;
    };

    然后,return false防止违约行为,如event.preventDefault()

  • 例如,如果使用addEventListener添加事件处理程序

    1
    2
    3
    4
    5
    6
    7
    elem.addEventListener(
        'click',
        function(e){
            return false;
        },
        false
    );

    那么,return false并不能阻止违约行为。

所有浏览器的行为都是这样吗?

event.preventDefault()return false之间有更多的区别吗?

我可以在哪里找到一些关于return false行为类似event.preventDefault()的文档(在MDN中找不到)?

我的问题只是简单的javascript,而不是jquery,所以请不要将其标记为even t.preventDefault()与return false的副本,即使这两个问题的标题几乎相同。


1.3.1中的W3C文档对象模型事件规范。事件注册接口声明EventListener中的handleEvent没有返回值:

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可能在任何浏览器中产生的任何效果,并使用event.preventDefault()

更新

HTML5规范实际上指定了如何处理不同的返回值。HTML规范第7.1.5.1节规定

If return value is a WebIDL boolean false value, then cancel the
event.

除了"鼠标悬停"事件。

结论

我仍然建议在大多数项目中使用event.preventDefault(),因为您将与旧的规范兼容,从而与旧的浏览器兼容。只有当您只需要支持尖端浏览器时,返回false取消就可以了。


这里有几个例子可以帮助人们更好地理解和解决他们的问题。好的。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 getEventListenersAPI查看事件侦听器的外观,以避免猜测,并检查事件处理程序是否未按预期运行。

例子

此示例特定于具有链接的click事件,但可以对大多数事件类型进行一般化。好的。

我们有一个类js-some-link-hook的锚(链接),我们希望打开一个模式并防止任何页面导航发生。好的。

下面的示例在MacOS Mojave上的Google Chrome(71)中运行。好的。

一个主要的陷阱是假设onclick=functionName与使用addEventListener的行为相同。好的。onclick属性

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}
}

这根本不起作用。使用onclick=时,处理程序函数被包装在另一个函数中。在这种情况下,您可以看到包含了我的函数定义,但没有调用它,因为我没有调用它就指定了函数引用。此外,您还可以看到,即使调用了我的函数,并且我的函数返回了false…onclick函数也不会返回那个false值…这是"取消"事件所必需的。我们真的需要将return myHandlerFunc();包装在onclick函数中,以便工作。好的。

现在我们看到了这是如何工作的,我们可以修改代码来做我们想要做的任何事情。举例说明(不要使用此代码):好的。

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

…所以是的,这应该管用。我们的return false(!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函数中。所以我们的return false(return !1由于缩小)在这里处于最高层,我们不必像以前那样担心增加额外的退货声明。好的。

所以它看起来应该起作用。点击链接,我们会收到警报。解除警报,页面导航/刷新。也就是说,返回false并没有取消事件。好的。

如果我们查找规范(请参阅底部的参考资料),我们会看到addEventListener的回调/处理程序函数不支持返回类型。我们可以返回我们想要的任何东西,但是由于它不是接口的一部分,所以没有任何效果。好的。

解决办法:用event.preventDefault()代替return false;…好的。

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)混淆了事物,因为它们在示例中同时使用了onclickaddEventListener,并且它们说:好的。

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.

    因此,这似乎意味着return false取消了addEventListeneronclick的事件。好的。

    但是,如果你看看他们对event-handler的关联定义,你会发现:好的。

    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事件处理程序好的。

    因此,似乎取消事件的return false实际上只适用于onclick事件处理程序(通常是on*事件处理程序,而不适用于通过addEventListener注册的具有不同API的事件处理程序。由于addEventListener API不在HTML5规范中,而且只包含on*事件处理程序……如果他们在示例中坚持这一点并特别指出区别,就不会那么容易混淆了。好的。好啊。


    preventdefault、stopperopogation、return false之间的差异

    Table Showing Difference

    默认操作–控制事件引发时的服务器端操作。

    假设我们有一个DIV控件,其中有一个按钮。所以DIV是按钮的父控件。按钮的客户端单击和服务器端单击事件。我们还有DIV的客户端点击事件。

    在客户端按钮的click事件上,我们可以通过以下三种方式控制父控件和服务器端代码的操作:

    • return false—这只允许控件的客户端事件。未激发父控件的服务器端事件和客户端事件。

    • preventDefault()—这允许客户端控制事件及其父控制。服务器端事件,即不激发控件的默认操作。

    • stopPropogation()–这允许控制的客户端和服务器端事件。不允许控件的客户端事件。


    return false仅用于IE,event.preventDefault()由chrome支持,ff…当代浏览器