Me preguntaba si event.preventDefault()
y return false
sería lo mismo.
He hecho algunas pruebas y parece que
Si el controlador de eventos se agrega usando el modelo antiguo, por ejemplo
elem.onclick = function(){ return false; };
Luego,
return false
evita la acción predeterminada, comoevent.preventDefault()
.Si el controlador de eventos se agrega usando
addEventListener
, por ejemploelem.addEventListener( 'click', function(e){ return false; }, false );
Entonces,
return false
no evita la acción predeterminada.
¿Todos los navegadores se comportan así?
¿Hay más diferencias entre event.preventDefault()
y return false
?
¿Dónde puedo encontrar documentación (no pude en MDN) sobre cómo return false
comportarse como event.preventDefault()
en algunos casos?
Mi pregunta es solo sobre javascript simple, no jQuery, así que no lo marque como un duplicado de event.preventDefault () vs. return false , incluso si ambas preguntas tienen casi el mismo título.
return false
comporta diferente al de JavaScript simple. Además, la otra pregunta no tiene ninguna respuesta que explique la diferencia en JS simple (solo hay un comentario que lo explica, pero es difícil de encontrar). Entonces creo que es mejor tener dos preguntas diferentes.Respuestas:
La Especificación de eventos del modelo de objetos de documento del W3C en 1.3.1. Las interfaces de registro de eventos indican que
handleEvent
en EventListener no tiene valor de retorno:en 1.2.4. Cancelación de evento el documento también establece que
lo que debería disuadirlo de utilizar cualquier efecto que pueda tener la devolución de verdadero / falso en cualquier navegador y uso
event.preventDefault()
.Actualizar
La especificación HTML5 en realidad especifica cómo tratar un valor de retorno de manera diferente. La sección 7.1.5.1 de la especificación HTML establece que
para todo menos el evento "mouseover".
Conclusión
Aún así, recomendaría usarlo
event.preventDefault()
en la mayoría de los proyectos, ya que será compatible con la especificación anterior y, por lo tanto, con los navegadores más antiguos. Solo si solo necesita admitir navegadores de vanguardia, devolver falso para cancelar está bien.fuente
stopPropagation()
,preventDefault()
yreturn false
: jsfiddle.net/m1L6of9x . En los navegadores modernos, los dos últimos tienen el mismo comportamiento.Aquí hay algunos ejemplos que pueden ayudar a las personas a comprender y solucionar mejor sus problemas.
TL; DR
on*
controladores de eventos (por ejemplo,onclick
atributo en un elemento de botón): devuelve falso para cancelar el eventoaddEventListener
es una API diferente, los valores de retorno (pfalse
. ej. ) se ignoran: useevent.preventDefault()
.onclick="<somejs>"
tiene su propia confusión potencial porque<somejs>
está envuelto en el cuerpo de una función onclick.getEventListeners
API de devtools del navegador para ver cómo se ve su detector de eventos para solucionar problemas si su controlador de eventos no se comporta como se esperaba.Ejemplo
Este ejemplo es específico del
click
evento con un<a>
enlace ... pero se puede generalizar para la mayoría de los tipos de eventos.Tenemos un ancla (enlace) con la clase
js-some-link-hook
que queremos abrir un modal y evitar que suceda la navegación de la página.Los siguientes ejemplos se ejecutaron en google chrome (71) en MacOS Mojave.
Un error importante es asumir que
onclick=functionName
es el mismo comportamiento que usaraddEventListener
Digamos que tenemos una etiqueta de anclaje (enlace) que queremos manejar con javascript cuando javascript está habilitado. No queremos que el navegador siga el enlace cuando se hace clic en él (comportamiento "evitar predeterminado").
<a href="https://www.example.com/url/to/go/to/when/no/javascript" class="js-some-link-hook">click me!</a>
atributo 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();
Luego, ejecútelo en la consola de devtools del navegador:
var el = document.querySelector('a.js-some-link-hook'), listener = getEventListeners(el).click[0].listener; console.log(''+listener); // to avoid truncation of output
... y ves:
function onclick(event) { function eventHandler (event) {alert('eventHandler ran'); return false;} }
Esto no funciona en absoluto. Cuando se utiliza
onclick=
su función de controlador se envuelve en otra función.Puede ver que la definición de mi función está incluida pero no se llama porque especifiqué la referencia de la función sin invocarla. es decir, que necesitamos
onclick="functionName()"
noonclick="functionName"
para asegurarse de quefunctionName
se ejecuta cuando se hace clic en el elemento.Además, puede ver que incluso si se llamó a mi función y mi función devolvió falso ... la
onclick
función no devolvería ese valor falso ... que se requiere para 'cancelar' el evento.Para solucionar esto, podemos establecer
onclick
que sea loreturn myHandlerFunc();
que asegura queonclick
devuelve el valor de retorno (falso) demyHandlerFunc
.También puede eliminar el
return false;
demyHandlerFunc
y cambiar elonclick
por ser,myHandlerFunc(); return false;
pero esto tiene menos sentido, ya que probablemente desee mantener la lógica junta en su función de controlador.Tenga en cuenta que cuando configura
onclick
con javascript , cuando configuraonclick
directamente en html en lugar de hacerlo con javascript (como mis ejemplos), elonclick
valor del atributo es tipo cadena y todo funciona. Si está configurandoonclick
usando javascript, debe prestar atención al tipo. Si diceelement.setAttribute('onclick', myHandlerFunc())
myHandlerFunc
que se ejecutará ahora mismo y el resultado se almacenará en el atributo ... en lugar de ejecutarse en cada clic. En su lugar, debe asegurarse de que el valor del atributo esté establecido como una cadena.element.setAttribute('onclick', 'return myHandlerFunc();')
Ahora que vemos cómo funciona, podemos modificar el código para hacer lo que queramos. Ejemplo extraño con fines ilustrativos (no use este código):
function eventHandler (e) { // want to prevent link navigation alert('eventHandler ran'); console.log(e); return false; } function addEventListenerToElement () { var link = document.querySelector('.js-some-link-hook'); link.setAttribute('onclick', 'return ('+eventHandler+')(event);'); } addEventListenerToElement();
Verá que hemos envuelto nuestra definición de función eventHandler en una cadena. Específicamente: una función autoejecutable con una declaración de retorno al frente.
De nuevo en la consola de 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
... muestra:
function onclick(event) { return (function eventHandler (e) { // want to prevent link navigation alert('eventHandler ran'); console.log(e); return false; })(event); }
... así que sí, eso debería funcionar. Efectivamente, si hacemos clic en el enlace, recibimos la alerta y, al descartar la alerta, la página no navega a ninguna parte ni se actualiza.
Una nota más sobre
onclick
... Si desea recibir y utilizar elevent
parámetro en el momento del evento, debe tener en cuenta que se llama "evento". Puede acceder a esto dentro de su controlador usando el nombreevent
(disponible a través delonclick
alcance de la función principal ). O puede construir su controlador para tomarloevent
como parámetro (mejor para pruebas) ... por ejemplo,onclick="return myEventHandler(event);"
o como ve en el ejemplo anterior.addEventListener
function eventHandler (ev) { // want to prevent link navigation alert('eventHandler ran'); console.log(ev); return false; } function addEventListenerToElement () { var link = document.querySelector('.js-some-link-hook'); link.addEventListener('click', eventHandler, false); } addEventListenerToElement();
devtools del navegador:
var el = document.querySelector('a.js-some-link-hook'), listener = getEventListeners(el).click[0].listener; console.log(''+listener); // to avoid truncation of output
resultado:
function eventHandler (ev) { // want to prevent link navigation alert('eventHandler ran'); console.log(ev); return false; }
Entonces ya puedes ver la diferencia. Con
addEventListener
no estamos envueltos en unaonclick
función. Nuestro manejador recibe elevent
parámetro directamente (y así podemos llamarlo como queramos). También nuestroreturn false
está en el "nivel superior" aquí y no tenemos que preocuparnos por agregar una declaración de retorno adicional como cononclick
.Entonces parece que debería funcionar. Al hacer clic en el enlace obtenemos la alerta. Descarte la alerta y la página navega / se actualiza. es decir, el evento NO se canceló devolviendo falso.
Si buscamos la especificación (ver recursos en la parte inferior), vemos que nuestra función de devolución de llamada / controlador para addEventListener no admite un tipo de retorno. Podemos devolver lo que queramos, pero como no forma parte de la API / interfaz del navegador, no tiene ningún efecto.
Solución: usar en
event.preventDefault()
lugar dereturn false;
...function eventHandler (ev) { // want to prevent link navigation ev.preventDefault(); alert('eventHandler ran'); } function addEventListenerToElement () { var link = document.querySelector('.js-some-link-hook'); link.addEventListener('click', eventHandler, false); } addEventListenerToElement();
devtools del navegador ...
var el = document.querySelector('a.js-some-link-hook'), listener = getEventListeners(el).click[0].listener; console.log(''+listener); // to avoid truncation of output
da...
function eventHandler (ev) { // want to prevent link navigation ev.preventDefault(); alert('eventHandler ran'); }
...como se esperaba.
Probando de nuevo:
Entonces,
addEventListener
usarevent.preventDefault()
como devolver falso no hace nada.Recursos
La especificación html5 ( https://www.w3.org/TR/html5/webappapis.html#events ) confunde las cosas porque usan ambos
onclick
yaddEventListener
en sus ejemplos y dicen lo siguiente:Entonces parece implicar que
return false
cancela el evento para ambosaddEventListener
yonclick
.Pero, si miras su definición vinculada
event-handler
, ves:https://www.w3.org/TR/html5/webappapis.html#event-handler
Por lo tanto, parece que la
return false
cancelación del evento solo se aplica a los controladores de eventosonclick
(o en generalon*
) y no a los controladores de eventos registrados a través de losaddEventListener
cuales tiene una API diferente.Dado que la
addEventListener
API no está cubierta por la especificación html5 (solo loson*
controladores de eventos) ... sería menos confuso si se apegaran a loson*
controladores de eventos de estilo en sus ejemplos.fuente
Diferencia entre preventDefault, stopPropogation, return false
Acción predeterminada: acción del lado del servidor cuando se genera un evento de control.
Supongamos que tenemos el control div y dentro de él tenemos un botón. Entonces div es el control principal del botón. Tenemos el evento de clic del lado del cliente y el clic del lado del servidor del botón. También tenemos el evento de clic del lado del cliente del div.
Al hacer clic en el evento del botón en el lado del cliente, podemos controlar las acciones del control principal y el código del lado del servidor usando las siguientes tres formas:
return false
- Esto permite solo el evento del lado del cliente del control. El evento del lado del servidor y el evento del lado del cliente del control principal no se disparan.preventDefault()
- Esto permite el evento de control del lado del cliente y su control principal. Evento del lado del servidor, es decir. La acción predeterminada del control no se dispara.stopPropogation()
- Esto permite eventos del lado del cliente así como del lado del servidor del control. El evento del lado del cliente del control no está permitido.fuente
return false
no detiene la propagación, por lo que el control parental se activa ( demostración ). Además, no estoy seguro de a qué te refieres con " evento de clic del lado del servidor ".return false
es solo para IE,event.preventDefault()
es compatible con Chrome, ff ... navegadores modernosfuente
return false
funciona comoevent.preventDefault()
cuando se agrega el controlador de eventos con el modelo anterior