Acerca de Scriptia
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.
onbeforeunload: tiende una mano al usuarioSaltar 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.";
}
};
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».
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.
3 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 :) !