replacestate recargar onpopstate mdn example event change cambiar javascript safari

javascript - recargar - window history replacestate({}



El problema del botón Atrás Safari (10)

Hago una pequeña programación y trabajo en la web para una universidad comunitaria local. Trabajo que incluye mantener un sitio web muy grande y destructor de almas que consiste en una mezcla de VBScript, JavaScript, Dreamweaver y una colección de complementos que varios estafadores han convencido a comprar a lo largo de los años.

Hace unos días recibí una llamada "¡El sitio web se está bloqueando para las personas que usan Safari!" De acuerdo, paso uno, descarga Safari (v3.1.2), paso dos navega al sitio. Todo parece funcionar bien.

Para resumir, finalmente aislé el problema y se relaciona con el botón de retroceso de Safari. El sitio web utiliza un menú javascript de pantalones de fantasía que funciona en todos los navegadores que he probado, incluida Safari, la primera vez. Pero en Safari, si sigues un enlace fuera de la página y luego presionas el botón Atrás, el menú ya no funciona.

Hice una página web reducida para ilustrar el principio.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head><title>Safari Back Button Test</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> </head> <body onload="alert(''Hello'');"> <a href="http://www.codinghorror.com">Coding Horror</a> </body> </html>

Cargue la página y verá el cuadro de alerta. Luego sigue el enlace de la página y presiona el botón Atrás. En IE y Firefox verá nuevamente el cuadro de alerta, en Safari no lo hace.

Después de una búsqueda inteligente en Google, descubrí a otros con problemas similares pero sin respuestas realmente satisfactorias. Entonces mi pregunta es ¿cómo puedo hacer que mis páginas funcionen de la misma manera en Safari después de que el usuario presione el botón Atrás como lo hacen en otros navegadores?

Si esta es una pregunta estúpida, por favor sea gentil, javascript es algo nuevo para mí.


Me di cuenta de algo muy similar. Creo que es porque Firefox e IE, al volver, están recuperando la página del servidor otra vez y Safari no. ¿Has intentado agregar un encabezado de caducidad de página / sin caché? Iba a examinarlo cuando descubriera el comportamiento, pero aún no he tenido tiempo.


No tengo idea de qué es lo que está causando el problema, pero sé quién podría ayudarlo. Safari se basa en Webkit y, aparte de Apple (que no tiene tanta mente comunitaria), el equipo de Webkit podría saber cuál es el problema.

No es una pregunta estúpida en absoluto.


Un iframe resuelve el problema:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head><title>Safari Back Button Test</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> </head> <body onload="alert(''Hello'');"> <a href="http://www.codinghorror.com">Coding Horror</a> <iframe style="height:0px;width:0px;visibility:hidden" src="about:blank"> this prevents back forward cache </iframe> </body> </html>

más detalles


La solución iframe de Stefan funciona, pero si eso no es lo suficientemente elegante, creo que el siguiente JavaScript también lo resuelve:

window.onunload = function(){};

Es decir, si su menú es JavaScript, quizás prefiera resolver este problema con JavaScript también.

La idea de definición del controlador de eventos de descarga provino de este artículo de Firefox 1.5: https://developer.mozilla.org/en/Using_Firefox_1.5_caching .



Solo ponga esto en la etiqueta del <body onunload="">

esto obligará a Safari, Chrome, FF a recargar cada vez que presione el botón Atrás


Aquí hay una buena solución para Mobile Safari:

/*! Reloads page on every visit */ function Reload() { try { var headElement = document.getElementsByTagName("head")[0]; if (headElement && headElement.innerHTML) headElement.innerHTML += " "; } catch (e) {} } /*! Reloads on every visit in mobile safari */ if ((/iphone|ipod|ipad.*os 5/gi).test(navigator.appVersion)) { window.onpageshow = function(evt) { if (evt.persisted) { document.body.style.display = "none"; location.reload(); } }; }

( fuente )

Lo modifiqué según mis necesidades, pero como está bien. (pantalla blanca molesta en actualización si no la modifica).


Tuve el mismo problema en iPad.

No es tan hermoso, pero funciona :). Cómo funciona.

Me di cuenta de que en iPad Safari, la página no se volvió a cargar cuando se presionó el botón Atrás. Puse un contador cada segundo en la página y guardo la marca de tiempo actual.

Cuando se carga la página, el contador y el tiempo se sincronizan. En el botón Atrás, el contador continúa donde se detuvo y hay un espacio entre la marca de tiempo y el contador. Si el espacio es superior a 500 ms, fuerza a volver a cargar la página.

En el archivo action.js

var showLoadingBoxSetIntervalVar; var showLoadingBoxCount = 0; var showLoadingBoxLoadedTimestamp = 0 function showLoadingBox(text) { var showLoadingBoxSetIntervalVar=self.setInterval(function(){showLoadingBoxIpadRelaod()},1000); showLoadingBoxCount = 0 showLoadingBoxLoadedTimestamp = new Date().getTime(); //Here load the spinner } function showLoadingBoxIpadRelaod() { //Calculate difference between now and page loaded time minus threshold 500ms var diffTime = ( (new Date().getTime()) - showLoadingBoxLoadedTimestamp - 500)/1000; showLoadingBoxCount = showLoadingBoxCount + 1; var isiPad = navigator.userAgent.match(/iPad/i) != null; if(diffTime > showLoadingBoxCount && isiPad){ location.reload(); } }


No sigas ninguno de los consejos que te dicen que ignores el caché. Las páginas se almacenan en caché por una razón: para mejorar la experiencia del usuario. Los métodos que está utilizando empeorarán la experiencia del usuario, por lo tanto, a menos que odie a los usuarios, no lo haga.

La solución correcta para Safari (Desktop e iOS) es utilizar el evento pageshow lugar del evento onload (consulte https://developer.mozilla.org/en-US/docs/Using_Firefox_1.5_caching para conocer cuáles son).

El evento de pageshow se activará al mismo tiempo que espera que se pageshow evento de pageshow , pero también funcionará cuando las páginas se sirvan a través del caché. Esto parece ser lo que quieres de todos modos.


$(window).bind("pageshow", function(event) { if (event.originalEvent.persisted) { window.location.reload() } });

Respondió más recientemente aquí por mshah .