Scriptia. Javascript y buenas prácticas en español



Scriptia / artículos / onbeforeunload: tiende una mano al usuario

onbeforeunload: tiende una mano al usuario

Saltar a Anotaciones relacionadas

¿Alguna vez has cerrado una ventana cuando tenías un formulario a medio rellenar? ¿Has invertido media hora en escribir un email y, por error, has abandonado la página sin enviarlo? Evita a tus usuarios pasar por este trauma –y el de aprender hebreo– usando onbeforeunload.

onbeforeunload se dispara _antes_ de que se descargue el contenido actual de la ventana. Microsoft lo introdujo en nuestras vidas y páginas web junto con la versión 4.0 de Internet Explorer. Los desarrolladores de Mozilla tuvieron en cuenta la utilidad de este evento –a pesar de no estar definido por ningún estándar–, así que desde la versión 1.7 de Mozilla (1.0 en términos firefoxísticos) podemos usarlo también en navegadores Gecko.

Lo curioso es que el manejo de este evento es distinto del habitual. Para cancelar la descarga –o mejor dicho, para preguntarle al usuario si está seguro de que quiere abandonar la página– el manejador del evento debe devolver _una cadena_.

Un ejemplito:

window.onbeforeunload = function(e) {
	return "Todavía no has guardado los datos. Si abandonas la página, se perderán por siempre jamás.";
};

Presentará un cuadro de diálogo al usuario en el que se mostrará el texto indicado, adornado convenientemente. Algo así:

¿Está seguro de que quiere abandonar esta página?

Todavía no has guardado los datos. Si abandonas la página, se perderán por siempre jamás.

Pulse Aceptar para continuar, o Cancelar para continuar en la página actual.

Botón aceptar / botón cancelar

(Los _extras_ que incluye el navegador en el diálogo no se pueden eliminar. Ni falta que hace.)

Evidentemente, si no hay riesgo para el usuario (pérdida de datos), es innecesario mostrar el diálogo. Podemos recurrir a una variable _bandera_, a una función, a lo que sea. Sin miedo:

window.onbeforeunload = function(e) {
	if (seHaModificadoElFormularioPeroNoSeHaGuardadoEntodavia()) {
		return "Todavía no has guardado los datos. Si abandonas la página, se perderán por siempre jamás.";
	}
};

## Para usuarios de jQuery

Ojito cuidadín: decíamos más arriba que este evento no funciona como es habitual. Si usas jQuery, deberás _tocar_ el atributo returnValue del objeto que representa al evento:

$(window).bind("beforeunload", function(e) {
	if (seHaModificadoElFormularioPeroNoSeHaGuardadoEntodavia()) {
		e.returnValue = "Todavía no has guardado los datos, etcétera."
	}
});

En resumen, podemos usar onbeforeunload para ofrecer un _seguro_ extra al usuario, pero siempre teniendo en cuenta que hay _cienes y cienes_ de navegadores que no saben qué hacer con él.

Aclaro, a petición de are, que los navegadores que «no saben qué hacer con él» simplemente ignorarán la asignación del evento. En ningún caso se darán errores por tratar de usar onbeforeunload en navegadores que no lo soportan. Simplemente, sus usuarios no dispondrán de esa «red de seguridad».



8 comentarios RSS

1 MikiBroki (2007-03-13 @ 12:14 pm):

Está genial, no documentada en w3schools.com. Sólo una puntualización: también sucede al intentar recargar la página… estaría genial si se pudiera cancelar la recarga. Gracias!

2 choan (2007-03-13 @ 2:46 pm):

Naturalmente. Si refrescas la página, antes de cargar la nueva versión se descarga la anterior.

No se me ocurre cómo evitar la aparición del mensaje en caso de recarga :(

3 ditman (2007-11-19 @ 9:45 am):

Hola choan.

Gracias a tu consejo de jQuery me acabas de solucionar un problema que he tenido los últimos días con esto… hay que ver lo que se parecen jQuery y prototype :)

El caso es que yo estaba intentando hacer algo así:

ev.returnValue = “Aquí va mi error”;
return Event.stop(ev);

Cuando sólo hacía falta establecer el returnValue y dejar que JavaScript hiciera el resto :)

¡Muchísimas gracias, de verdad :) !

4 Fran García (2008-11-11 @ 2:55 pm):

Pero el problema es que el mensaje sigue saliendo cuando se le da al botón Enviar del formulario, y no sé como conseguir que no aparezca.

5 Julio Tuozzo (2009-07-31 @ 12:05 am):

Para que no aparezca el mensaje se puede usar el siguiente truco:

window.onbeforeunload = function(e)
{ if (verifico_click())
{return “No has guardado el formulario”;
}
};

function verifico_click()
{ if (document.form_name.guardar.value!=’Espera’)
{return true

}
else
{return false
}
}

En el formulario:

6 Julio Tuozzo (2009-07-31 @ 12:07 am):

Para que no aparezca el mensaje se puede usar el siguiente truco:

window.onbeforeunload = function(e)
{ if (verifico_click())
{return “No has guardado el formulario”;
}
};

function verifico_click()
{ if (document.form_name.guardar.value!=’Espera’)
{return true

}
else
{return false
}
}

En el formulario:

form name=’form_name’
input type=’submit’ value=’Guardar’ name=’guardar’ onclick=’this.value=”Espera”‘

7 José María Pérez (2010-04-12 @ 1:01 am):

Gracias Choan por compartir.
Encontre esta pequeña joya y un gran sitio donde aprender.

8 Diego Molina (2010-05-31 @ 4:43 pm):

hola

Tengo un problema y es que en los navegadores en ingles la mitad del mesaje me sale en ese idioma, y texto que yo le agrego en español.

Como puedo solucionar esto?

Desde ya muchas gracias


Di la tuya

Puedes usar estas etiquetas HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> . Por favor, evita el abuso de las mayúsculas y cuida la ortografía.


Acerca de Scriptia

Saltar a la caja de búsqueda

Scriptia forma parte del PDM de Choan C. Gálvez, desarrollador web residente en Barcelona. Scriptia pretende mejorar la calidad de la documentación acerca de javascript disponible en español.