event.preventDefault()与return false(没有jQuery)

时间:2013-09-24 00:54:20

标签: javascript events javascript-events event-handling preventdefault

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

我已完成some tests,似乎

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

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

    然后,return false会阻止默认操作,例如event.preventDefault()

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

    elem.addEventListener(
        'click',
        function(e){
            return false;
        },
        false
    );
    

    然后,return false不会阻止默认操作。

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

event.preventDefault()return false之间是否存在更多差异?

在某些情况下我可以找到一些文档(我无法在MDN中)return false表现得像event.preventDefault()


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

4 个答案:

答案 0 :(得分:50)

1.3.1中的W3C Document Object Model Events Specification。事件注册接口表明EventListener中的handleEvent没有返回值:

  

handleEvent   只要类型发生事件,就会调用此方法   已为其注册EventListener接口。 [...] 不归   值

1.2.4下。事件取消该文件还说明了

  

通过调用Event的preventDefault来完成取消   方法。如果一个或多个EventListeners在任何期间调用preventDefault   事件流的阶段将取消默认操作。

应该阻止您使用任何返回true / false的效果在任何浏览器中都可以使用event.preventDefault()

<强>更新

HTML5规范实际上指定了如何处理不同的返回值。 Section 7.1.5.1 of the HTML Spec表示

  

如果返回值是WebIDL布尔值false,则取消   事件

除了“鼠标悬停”事件之外的所有事情。

<强>结论

我仍然建议在大多数项目中使用event.preventDefault(),因为您将与旧规范和旧浏览器兼容。只有当您只需要支持最先进的浏览器时,返回false才能取消即可。

答案 1 :(得分:1)

以下是一些示例,可以帮助人们更好地理解和解决问题。

TL; DR

  • 直接在html标记中使用onclick或通过setAttribute('onclick'...)使用onclick=有其自身的陷阱,因为将onclick的内容包装到{{1} }函数。
  • 使用onclick时,可以通过确保onclick函数返回false来取消事件...您的函数被包装了...所以您需要执行onclick="return myHandler();"或{ {1}}或类似的方法来确保onclick返回false。
  • 使用addEventListener ...时,返回false无效。规范中的接口说返回类型为void。改用event.preventDefault()。
  • 您可以使用浏览器devtools onclick="myHandler(); return false;" API来查看事件侦听器的外观,以避免猜测并检查事件处理程序的行为是否与预期不符。

示例

此示例特定于带有getEventListeners链接的click事件...但是可以推广到大多数事件类型。

我们有一个类<a>的锚点(链接),我们想要打开一个模式并防止任何页面导航的发生。

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

一个主要的陷阱是假设js-some-link-hook与使用onclick=functionName的行为相同

onclick属性

addEventListener

然后在浏览器devtools控制台中运行:

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

...,您会看到:

var el = document.querySelector('a.js-some-link-hook'),
        listener = getEventListeners(el).click[0].listener;
    console.log(''+listener); // to avoid truncation of output

这根本不起作用。使用function onclick(event) { function t(n){return alert("eventHandler ran"),!1} } 时,处理程序函数将包装在另一个函数中。在这种情况下,您可以看到包含但未调用我的函数定义,因为我在不调用它的情况下指定了函数引用。此外,您还可以看到,即使调用了我的函数并且我的函数返回了false,onclick函数也不会返回该false值……这是“取消”事件所必需的。我们确实需要将onclick=包裹在onclick函数中才能正常工作。

现在我们看到了它的工作原理,我们可以修改代码以执行我们想要的任何事情。出于说明目的的奇怪示例(请勿使用此代码):

return myHandlerFunc();

您会看到我们已将eventHandler函数定义包装到字符串中。具体来说:一个自执行函数,在前面有一个return语句。

再次在chrome devtools控制台中:

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

...显示:

var el = document.querySelector('a.js-some-link-hook'),
        listener = getEventListeners(el).click[0].listener;
    console.log(''+listener); // to avoid truncation of output

...所以,应该可以。我们的function onclick(event) { return (function t(e){return alert("eventHandler ran"),!1})(); } return false由于运行了缩小功能,很抱歉)。果然,如果我们单击链接,我们将收到警报,并关闭该警报,该页面将不会在任何地方导航或刷新。

addEventListener

!1

浏览器devtools:

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

结果:

var el = document.querySelector('a.js-some-link-hook'),
        listener = getEventListeners(el).click[0].listener;
    console.log(''+listener); // to avoid truncation of output

因此您已经可以看到区别。我们没有包装在onclick函数中。因此,我们的function e(n){return alert("eventHandler ran"),!1} return false由于最小化)位于此处的顶层,我们不必担心像以前一样添加额外的return语句。

所以看起来应该可以。单击链接,我们会收到警报。解除警报,页面导航/刷新。 即未通过返回false取消该事件。

如果我们查找规范(请参阅底部的资源),则会发现addEventListener的回调/处理函数不支持返回类型。我们可以返回想要的任何东西,但是由于它不是接口的一部分,因此没有任何作用。

解决方案:使用return !1代替event.preventDefault() ...

return false;

浏览器devtools ...

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

给予...

var el = document.querySelector('a.js-some-link-hook'),
        listener = getEventListeners(el).click[0].listener;
    console.log(''+listener); // to avoid truncation of output

...按预期。

测试:获取警报。解除警报。 页面导航或刷新...这就是我们想要的。

资源

html5规范(https://www.w3.org/TR/html5/webappapis.html#events)令人困惑,因为它们在示例中同时使用了function n(e){e.preventDefault(),alert("eventHandler ran")} onclick,并且他们说以下话:

  

事件处理程序H和事件对象E的事件处理程序处理算法如下:

     

...

     
      
  1. 处理返回值如下:
  2.   
     

...

     

如果返回值是Web IDL布尔假值,则取消该事件。

因此,似乎暗示addEventListener取消了return falseaddEventListener的事件。

但是,如果您查看他们对onclick的链接定义,则会看到:

  

事件处理程序具有一个名称,该名称始终以“ on”开头,后跟要使用的事件的名称。

     

...

     

事件处理程序以两种方式之一公开。

     

所有事件处理程序共有的第一种方法是作为事件处理程序IDL属性。

     

第二种方法是作为事件处理程序的内容属性。 HTML元素上的事件处理程序和Window对象上的某些事件处理程序都以这种方式公开。

https://www.w3.org/TR/html5/webappapis.html#event-handler

因此,似乎event-handler取消事件确实仅适用于return false(或通常为onclick)事件处理程序,而不适用于通过on*注册的事件处理程序具有不同的API。由于html5规范未涵盖addEventListener API,仅addEventListener事件处理程序未涵盖...如果坚持使用示例中的内容并明确指出两者之间的区别,则不会造成混淆。

答案 2 :(得分:-1)

preventDefault,stopPropogation,return false

之间的区别

Table Showing Difference

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

假设我们有div控制,在里面我们有一个按钮。所以div是按钮的父控件。我们有按钮的客户端点击和服务器端点击事件。我们还有div的客户端点击事件。

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

  • return false - 这只允许控件的客户端事件。不会触发父控件的服务器端事件和客户端事件。

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

  • stopPropogation() - 这允许客户端以及控件的服务器端事件。不允许控件的客户端事件。

答案 3 :(得分:-12)

return false仅适用于IE,event.preventDefault()受Chrome,ff支持...现代浏览器