为了账号安全,请及时绑定邮箱和手机立即绑定

event.preventDefault()与返回false(无jQuery)

event.preventDefault()与返回false(无jQuery)

慕容森 2019-10-17 14:56:10
我想知道是否event.preventDefault()和return false相同。我做了一些测试,看来例如,如果事件处理程序是使用旧模型添加的elem.onclick = function(){    return false;};然后,return false阻止默认操作,例如event.preventDefault()。如果事件处理程序使用添加addEventListener,例如elem.addEventListener(    'click',    function(e){        return false;    },    false);然后,return false不要阻止默认操作。所有浏览器的行为都一样吗?event.preventDefault()和之间还有更多区别return false吗?在哪里可以找到一些有关return false行为的文档(我在MDN中找不到)event.preventDefault()?我的问题只是关于普通的javascript而不是jQuery,因此请不要将其标记为event.preventDefault()与return false的重复,即使两个问题的标题几乎相同。
查看完整描述

3 回答

?
慕尼黑8549860

TA贡献1818条经验 获得超11个赞

的W3C文档对象模型事件规范在1.3.1。事件注册接口指出,handleEventEventListener中没有返回值:


handleEvent 每当发生事件类型为注册了EventListener接口的事件时,都会调用此方法。[...] 没有返回值


根据1.2.4。事件取消文档还指出


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


这应该阻止您使用在任何浏览器中使用返回true / false可能产生的任何影响event.preventDefault()。


更新资料


HTML5规范实际上指定了如何对待不同的返回值。HTML规范的7.1.5.1节指出:


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


除了“ mouseover”事件以外的所有事件。


结论


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


查看完整回答
反对 回复 2019-10-17
?
智慧大石

TA贡献1946条经验 获得超3个赞

这里有一些例子,可以帮助人们更好地理解和解决他们的问题。


TL; DR

on*事件处理程序(例如onclick,按钮元素上的属性):返回false以取消事件

addEventListener是不同的API,返回值(例如false)将被忽略:use event.preventDefault()。

onclick="<somejs>"有其自身的潜在困惑,因为<somejs>它包装在onclick函数的主体中。

使用浏览器devtools getEventListenersAPI可以查看如果事件处理程序的行为异常,事件侦听器将如何解决。

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


我们在类的锚点(链接)上js-some-link-hook要打开模式并防止发生任何页面导航。


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


一个主要的陷阱是假定onclick=functionName与使用相同的行为addEventListener


onclick属性

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控制台中运行:


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}

}

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


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


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

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


再次在chrome devtools控制台中:


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(!1由于运行缩图,对不起)。果然,如果我们单击链接,我们将收到警报,并关闭该警报,该页面将不会在任何地方导航或刷新。


addEventListener

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

浏览器devtools:


var el = document.querySelector('a.js-some-link-hook'),

        listener = getEventListeners(el).click[0].listener;

    console.log(''+listener); // to avoid truncation of output

结果:


function e(n){return alert("eventHandler ran"),!1}

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


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


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


解决方案:使用event.preventDefault()代替return false;...


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

浏览器devtools ...


var el = document.querySelector('a.js-some-link-hook'),

        listener = getEventListeners(el).click[0].listener;

    console.log(''+listener); // to avoid truncation of output

给...


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

回调/处理程序/侦听器定义

注意返回类型为void。即返回值不是接口的一部分,并且无效。

https://www.w3.org/TR/dom41/#event

事件对象(例如Event.preventDefault)

html5规范(https://www.w3.org/TR/html5/webappapis.html#events)使事情变得混乱,因为它们在示例中同时使用onclick和addEventListener,并且它们表示以下内容:


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


...


处理返回值如下:

...


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


因此,它似乎暗示,return false取消两个事件addEventListener和onclick。


但是,如果您查看它们的链接定义,event-handler则会看到:


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


...


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


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


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


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


因此,似乎return false取消事件确实仅适用于onclick(或通常on*)事件处理程序,而不适用于通过addEventListener不同API 注册的事件处理程序。由于html5规范未涵盖addEventListener API,而仅on*事件处理程序未涵盖...如果它们坚持示例中的内容并明确指出差异,则不会造成混淆。


查看完整回答
反对 回复 2019-10-17
?
ibeautiful

TA贡献1993条经验 获得超5个赞

preventDefault,stopPropogation和return false之间的区别


//img1.sycdn.imooc.com//5da810c300013d5205230107.jpg

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


假设我们有div控件,并且在其中有一个按钮。因此div是按钮的父控件。我们有按钮的客户端单击和服务器端单击事件。另外,我们还有div的客户端点击事件。


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


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


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


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


查看完整回答
反对 回复 2019-10-17
  • 3 回答
  • 0 关注
  • 659 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信