I wondered if event.preventDefault()
and return false
were the same.
I have done some tests, and it seems that
If the event handler is added using old model, for example
elem.onclick = function(){ return false; };
Then,
return false
prevents default action, likeevent.preventDefault()
.If the event handler is added using
addEventListener
, for exampleelem.addEventListener( 'click', function(e){ return false; }, false );
Then,
return false
doesn't prevent the default action.
Do all browsers behave like this?
Are there more differences between event.preventDefault()
and return false
?
Where I can find some documentation (I couldn't in MDN) about return false
behaving like event.preventDefault()
in some cases?
My question is only about plain javascript, not jQuery, so please don't mark it as a duplicate of event.preventDefault() vs. return false, even if both questions have almost the same title.
The W3C Document Object Model Events Specification in 1.3.1. Event registration interfaces states that handleEvent
in the EventListener has no return value:
handleEvent
This method is called whenever an event occurs of the type for which the EventListener interface was registered. [...] No Return Value
under 1.2.4. Event Cancelation the document also states that
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.
which should discourage you from using any effect that returning true / false could have in any browser and use event.preventDefault()
.
Update
The HTML5 spec actually specifies how to treat a return value different. Section 7.1.5.1 of the HTML Spec states that
If return value is a WebIDL boolean false value, then cancel the event.
for everything but the "mouseover" event.
Conclusion
I would still recommend to use event.preventDefault()
in most projects since you will be compatible with the old spec and thus older browsers. Only if you only need to support cutting edge browsers, returning false to cancel is okay.
Here are a few examples that might help people to understand and troubleshoot their problems better.
TL;DR
- using
onclick
directly in html markup or viasetAttribute('onclick'...)
has its own pitfalls in terms of making sure you are actually returning because the contents ofonclick=
are wrapped into anonclick
function. - when using
onclick
, you can cancel the event by making sure theonclick
function returns false...your function gets wrapped...so you need to doonclick="return myHandler();"
oronclick="myHandler(); return false;"
or something like that to make sure that onclick returns false. - when using addEventListener...returning false doesn't have any effect. The interface in the spec says return type void. Use event.preventDefault() instead.
- You can use the browser devtools
getEventListeners
API to see what your event listener looks like to avoid guess and check if your event handler is not behaving as expected.
Example
This example is specific to the click
event with an <a>
link...but can be generalized for most event types.
We have an anchor (link) with class js-some-link-hook
that we want to open a modal and prevent any page navigation from happening.
The below examples were run in google chrome (71) on MacOS Mojave.
One major pitfall is assuming that onclick=functionName
is the same behaviour as using addEventListener
onclick attribute
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();
Then run in the browser devtools console:
var el = document.querySelector('a.js-some-link-hook'),
listener = getEventListeners(el).click[0].listener;
console.log(''+listener); // to avoid truncation of output
...and you see:
function onclick(event) {
function t(n){return alert("eventHandler ran"),!1}
}
This doesn't work at all. When using onclick=
your handler function is wrapped in another function. In this case you can see that my function definition is included but not called because I specified the function reference without invoking it. Further you can see that even if my function was invoked and my function returned false...the onclick function would not return that false value...which is required to 'cancel' the event. We really need return myHandlerFunc();
to be wrapped in the onclick function for things to work.
Now that we see how that is working, we can modify the code to do whatever we want. Odd example for illustration purposes (don't use this code):
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();
You see we have wrapped our eventHandler function definition into string. Specifically: a self-executing function with a return statement at the front.
Again in chrome devtools console:
var el = document.querySelector('a.js-some-link-hook'),
listener = getEventListeners(el).click[0].listener;
console.log(''+listener); // to avoid truncation of output
...shows:
function onclick(event) {
return (function t(e){return alert("eventHandler ran"),!1})();
}
...so yeah, that should work. Our return false
(!1
due to minification running, sorry). Sure enough if we click on the link we get the alert and dismissing the alert the page doesn't navigate anywhere or refresh.
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();
browser devtools:
var el = document.querySelector('a.js-some-link-hook'),
listener = getEventListeners(el).click[0].listener;
console.log(''+listener); // to avoid truncation of output
result:
function e(n){return alert("eventHandler ran"),!1}
So you can already see the difference. We aren't wrapped in an onclick function. So our return false
(return !1
due to minification) is at the top level here and we don't have to worry about adding an extra return statement like before.
So it looks like it should work. Clicking on the link we get the alert. Dismiss the alert and the page navigates/refreshes. ie the event was NOT cancelled by returning false.
If we lookup the spec (see resources at bottom), we see that our callback/handler function for addEventListener does not support a return type. We can return whatever we want, but since it isn't part of the interface, it doesn't have any effect.
Solution: using event.preventDefault()
instead of 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();
browser devtools...
var el = document.querySelector('a.js-some-link-hook'),
listener = getEventListeners(el).click[0].listener;
console.log(''+listener); // to avoid truncation of output
gives...
function n(e){e.preventDefault(),alert("eventHandler ran")}
...as expected.
Testing: get the alert. Dismiss alert. No page navigation or refresh...which is what we want.
Resources
- https://www.w3.org/TR/dom41/#dom-eventtarget-addeventlistener
- Event Registration (e.g. addEventListener)
- https://www.w3.org/TR/dom41/#callbackdef-eventlistener
- callback/handler/listener def.
- NOTE return type is void. ie return value is not part of the interface and has no effect.
- https://www.w3.org/TR/dom41/#event
- Event Object (e.g. Event.preventDefault)
The html5 spec (https://www.w3.org/TR/html5/webappapis.html#events) confuses things because they use both onclick
and addEventListener
in their examples and they say the following:
The event handler processing algorithm for an event handler H and an Event object E is as follows:
...
- Process return value as follows:
...
If return value is a Web IDL boolean false value, then cancel the event.
So it seems to imply that return false
cancels the event for both addEventListener
and onclick
.
But, if you look at their linked definition of event-handler
you see:
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.
...
Event handlers are exposed in one of two ways.
The first way, common to all event handlers, is as an event handler IDL attribute.
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.
https://www.w3.org/TR/html5/webappapis.html#event-handler
So it seems that the return false
cancelling the event really does only apply to the onclick
(or generally on*
) event handlers and not to event handlers registered via addEventListener
which has a different API. Since the addEventListener API is not covered under the html5 spec and only the on*
event handlers...it would be less confusing if they stuck to that in their examples and specifically called out the difference.
Difference between preventDefault, stopPropogation, return false

Default Action – Server side action when control event raise.
Suppose we have div control and inside it we have a button. So div is the parent control of the button. We have Client side click and server side click event of the button. Also we have client side click event of the div.
On click event of the button on client side, we can control the actions of parent control and server side code using following three ways:
return false
- This allow only client side event of the control. Server side event and client side event of the parent control is not fired.preventDefault()
- This allow client side event of control and its parent control. Server side event ie. Default action of the control is not fired.stopPropogation()
– This allow client side as well as server side event of the control. Client side event of the control is notallowed.
return false
is just for IE, event.preventDefault()
is supported by chrome,ff... modern browsers
来源:https://stackoverflow.com/questions/18971284/event-preventdefault-vs-return-false-no-jquery