window.onbeforeunload no funciona en el iPad?

84

¿Alguien sabe si el onbeforeunloadevento es compatible con el iPad y / o si hay una forma diferente de usarlo?

Probé casi todo y parece que el onbeforeunloadevento nunca se activa en el iPad (navegador Safari).

Específicamente, esto es lo que he probado:

  • window.onbeforeunload = function(event) { event.returnValue = 'test'; }
  • window.onbeforeunload = function(event) { return 'test'; }
  • (ambos de los anteriores juntos)
  • window.onbeforeunload = function(event) { alert('test')'; }
  • (todas las funciones anteriores pero dentro <body onbeforeunload="...">

Todos estos funcionan en FF y Safari en la PC, pero no en el iPad.

Además, hice lo siguiente justo después de cargar la página:

alert('onbeforeunload' in window);
alert(typeof window.onbeforeunload);
alert(window.onbeforeunload);

Respectivamente, los resultados son:

  • true
  • object
  • null

Entonces, el navegador tiene la propiedad, pero por alguna razón no se activa.

Las formas en las que trato de navegar fuera de la página son haciendo clic en los botones de retroceso y avance, haciendo una búsqueda en Google en la barra superior, cambiando la ubicación en la barra de direcciones y haciendo clic en un marcador.

¿Alguien tiene alguna idea de lo que está pasando? Agradecería mucho cualquier aporte.

Gracias

Arte Zambrano
fuente
Gracias a ambos por su aporte. Debe ser una de las razones que mencionaste. Desafortunadamente, no hay documentación oficial de Apple sobre esta y otras limitaciones. Con suerte, encontrarán una forma más creativa de habilitar esta función, al tiempo que evitan su uso malicioso. Escucho muy a menudo que la gente toca accidentalmente fuera de la página y pierde todos los datos que ingresaron en un formulario.
Art Zambrano
¿Has probado a usar addEventListener()?
Hola71
2
Estoy bastante seguro de beforeunloadque no funciona en Safari en iOS. :-( Quizás no sea lo que está buscando, pero tengo una sugerencia sobre cómo probar de manera confiable para un funcionamientobeforeunload
Peter V. Mørch
1
El 3 de marzo de 2016, The window.onbeforeunload = function(event) { event.returnValue = 'test'; }no funciona tanto en Chrome como en Safari de iOS 9.2.1. Me gusta mucho onbeforeunloadporque la página no cambia si hago clic en cancelar.
vanduc1102
Parece que este problema se resolvió en Safari e iOS 13
Finesse

Respuestas:

20

Descubrí que el evento onunload () se activa. Su comportamiento es algo extraño; lo que sea que tenga en su función de devolución de llamada adjunta al evento se ejecuta realmente después de que la nueva página se haya cargado en segundo plano (no puede saber si está cargada todavía, pero el registro del servidor mostrará que sí).

Más curiosamente, si tiene una llamada confirm () en su onunload (), y el usuario ha hecho clic en un enlace para ir a otro lugar, está en el negocio. Sin embargo, si el usuario cierra la pestaña del navegador Safari del iPad, el evento onunload () se activará, pero su confirm () tendrá una cancelación implícita como respuesta.

Danny Armstrong
fuente
Eh, parece que esta peculiaridad de confirmación (que se accede a la segunda página antes del mensaje de confirmación) es cierta no solo para el safari móvil sino también para Firefox (y probablemente otros). Simplemente me voló la cabeza.
Amalgovinus
4
unloadevento obsoleto a favor de pagehidever developer.apple.com/library/ios/documentation/AppleApplications/…
sol0mka
1
@ sol0mka: ¡Eso es, hombre! ¡Excelente! En mi caso, el siguiente código hizo el trabajo, hasta donde puedo ver para todos mis navegadores Y iOS: $ (window) .on ('beforeunload pagehide', function () {// mis cosas que deben hacerse en la página cambio } ); Esta debería ser la respuesta aceptada en mis ojos.
Garavani
18

Este fragmento de JavaScript me funciona en Safari y Chrome en ipad y iphone, así como en computadoras de escritorio / portátiles / otros navegadores:

var isOnIOS = navigator.userAgent.match(/iPad/i)|| navigator.userAgent.match(/iPhone/i);
var eventName = isOnIOS ? "pagehide" : "beforeunload";

window.addEventListener(eventName, function (event) { 
    window.event.cancelBubble = true; // Don't know if this works on iOS but it might!
    ...
} );
Peligro
fuente
1
Puede detectar el evento, pero ¿cómo puede aparecer el mensaje de confirmación? Usar return 'test';similar a eso por
operación
Gracias, me perdí eso en la pregunta original. No lo he probado específicamente en iOS, pero posiblemente agregar esta línea adicional funcionaría: window.event.cancelBubble = true; Agregaré a mi respuesta
peligro
2
Gracias, pero lamentablemente no funciona ... Traté de poner alert () dentro, parece que la nueva página ha comenzado a cargarse antes de que se active la alerta (). También vea esto: stackoverflow.com/questions/3239834/…
user2335065
@ user2335065 ¿encontró alguna solución para lo mismo?
Neeraj Rathod
chicos, ¿encontraron alguna solución para mostrar el mensaje de confirmación antes de salir de la página? Esto funciona bien en todos los navegadores, excepto IOS Safari. Probé el evento pagehide también, pero no funcionó para mí. Gracias por adelantado.
Rahul
6

Solo Apple lo sabría con certeza, pero supongo que deliberadamente no habilitaron esa funcionalidad en Safari móvil porque los personajes turbios la utilizan con mayor frecuencia para que permanezcas en su sitio o aparezcan muchas ventanas de pornografía / publicidad.

Charles Boyung
fuente
55
O, ya sabe, guarde sus cambios automáticamente para que no se pierdan solo porque accidentalmente tocó lo incorrecto.
Joel Mueller
4
No dije que no hubiera usos válidos, solo dije que esos eran los usos más frecuentes.
Charles Boyung
3
@JoelMueller Tu comentario debe ser la respuesta aceptada :)
sanchez
1
@JoelMueller Ese es exactamente mi caso de uso. Grrr @ apple
user2808054
@JoelMueller, ¿podría compartir algún documento oficial donde podamos abordar esta declaración de que el safari móvil guarda los cambios automáticamente?
Neeraj Rathod
3

Hay un error conocido en WebKit con onbeforeunload. Creo que está solucionado en la última versión beta de Chrome 5, pero es muy posible que el navegador del iPad esté hecho de una versión de WebKit que no tiene la solución.

Informe de errores de Chrome relacionado .

Joel Mueller
fuente
1
Estoy confundido o ¿este error todavía existe en el navegador del iPad?
Peter
2

https://code.google.com/p/chromium/issues/detail?id=97035

ver escuchar.

ya no se permiten alertas durante los eventos de cierre de página (antes de descargar, descargar, ocultar página).

Creo que las alertas, la solicitud, la confirmación y otras acciones como estas tampoco están permitidas.

zelda.j
fuente
1

Si solo necesita saber si la página se ha abandonado, puede usar document.unload. Funciona bien en los navegadores iOS. Si ve en la documentación de Apple , encontrará que está obsoleta y recomiendan usar document.pagehide

Miquel
fuente
sí, este evento se activa en Safari, pero el mensaje de confirmación no viene como en Chrome.
Rahul
1

Aquí hay una solución que debería funcionar en todos los navegadores modernos:

var unloaded = false;
window.addEventListener("beforeunload", function(e)
{
    if (unloaded)
        return;
    unloaded = true;
    console.log("beforeUnload");
});
window.addEventListener("visibilitychange", function(e)
{
    if (document.visibilityState == 'hidden')
    {
        if (unloaded)
            return;
        unloaded = true;
        console.log("beforeUnload");
    }
});

Los navegadores móviles no tienden a no ser compatibles beforeunloadporque el navegador puede pasar a segundo plano sin descargar la página y luego ser eliminado por el sistema operativo en cualquier momento.

La mayoría de los navegadores de escritorio contienen un error que hace visibilityStateque no se llame cuando se descarga el documento. Ver: aquí .

Por lo tanto, es importante incluir ambos eventos para cubrir todos los escenarios.

nótese bien

Lo he usado en console.loglugar de alerten mi ejemplo porque alertalgunos navegadores lo bloquearán cuando se llame desde beforeunloado visibilitychange.

Dan Bray
fuente