2012-10-11 68 views
5

Tengo una página web sencilla, a saber:¿Cómo hacer que Firefox active el evento popstate al volver desde una página en un dominio diferente?

<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
<title>History hacks</title> 
<script> 
window.onpopstate = function (e) { 
    alert("location: " + document.location + ", state: " + JSON.stringify(e.state)); 
} 
window.onload = function (e) { 
    alert('page loaded'); 
} 
</script> 
</head> 
<body> 
<p> <a href="http://www.yahoo.com">Yahoo</a> <a href="#part1">Part 1</a></p> 
</body> 
</html> 

Ahora bien, hay una serie de diferencias con respecto a cómo Chrome y Firefox desencadenan el evento popstate (quiero ni pensar lo que yo estoy en contra cuando llegue en torno a probando IE), pero uno que me está dando problemas aquí es que Chrome activará un evento de estado emergente cada vez que haga clic en cualquiera de esos dos enlaces, y luego otra vez cuando presione el botón Atrás. Firefox activará el evento para el enlace que cambia la parte hash (solo la primera vez si el enlace hash es el mismo), y no lo activará en absoluto si hago clic en el enlace Yahoo y luego hago clic en el botón Atrás.

Entonces, ¿hay alguna forma de saber en Firefox que un usuario acaba de hacer clic atrás y aterrizar en mi página desde un sitio completamente diferente en un dominio diferente? ¿Hay algún otro evento que funcione para este fin en Firefox? (El evento de carga no se desencadena cuando vuelvo de yahoo.com.)

Respuesta

1

Probablemente esté buscando el evento pageshow si desea que se le notifique cuando se muestre su página cuando regrese, incluso si se activó en caché en la memoria caché de la página.

Tenga en cuenta que si no hay un evento de carga que también significa que la página todavía tiene exactamente el mismo entorno de ejecución de scripts y DOM que cuando se navega desde. Básicamente es como si el usuario cambiara las pestañas por un tiempo, en lugar de navegar.

Por lo tanto, ¿aún desea obtener un evento en esa situación? ¿Obtienes eventos que buscas cuando el usuario vuelve a la pestaña con tu página?

9

Para obtener un acontecimiento popstate cuando el botón de atrás (o hacia delante) se utiliza para ir a la carga de la página inicial, utilice replaceState() como

window.onload = function(e) { 
    history.replaceState(null, null, document.URL); 
} 

Ignorar la inicial popstate que Chrome genera cuando la página se carga puede etiquetar el estado siempre que llame al pushState/replaceState, por ej.

history.pushState({myTag: true}, null, url); 

A continuación, el controlador de popstate simplemente filtra para myTag

window.onpopstate = function(e) { 
    if (!e.state.myTag) return; // none of my business 
    // code to handle popstate 
} 

Se pueden combinar estos dos para una solución multi-navegador trivial:

window.onpopstate = function(e) { 
    if (!e.state.myTag) return; // none of my business 
    // code to handle popstate 
} 

window.onload = function(e) { 
    history.replaceState({myTag: true}, null, document.URL); 
} 

@Boris Zbarsky ha detallado el bfcache. No he pensado en cómo combinar eso con mi enfoque. Yo sólo desactivarlo por adding a page unload handler

window.onunload = function(e) { } 
+0

Esta es una gran respuesta para explicar cómo hacer que la API de la historia funciona de la misma plataforma, pero en realidad no responder OP pregunta: ** cómo saber si el usuario realmente hizo clic en "volver" para terminar en la página. ** Usando su ejemplo, puede ver que el usuario hizo clic en Chrome y Safari porque mytag no será nulo en el controlador onpopstate . Sin embargo, en firefox, onpopstate no se llama, por lo que parece que no hay forma de determinar si el usuario regresa a la página o si es la primera vez que lo hace. Entonces, ¿hay alguna forma de distinguir esto en Firefox? – Karmacon

+1

@Karma: si desactivas el bfcache (mira la última parte de mi respuesta) entonces Firefox debería comportarse de manera similar a Chrome. Pero lea la respuesta de Boris Zbarsky para una buena ilustración de por qué debería preferir el caché de la página de Firefox al comportamiento de Chrome. –

+0

Gracias @Sean Hogan. Después de volver a leer en Firefox bfCaching, me di cuenta de que no funciona en mi sitio porque usamos https. Firefox siempre actualiza la página. Supongo que no hay nada que pueda hacer al respecto. – Karmacon

0

antes de descarga vuelvo a cargar mi página (para obtener el estado inicial) a continuación, establecer nuevos href

window.onunload = function(e) { 
 
    location.reload(); 
 
    location.href = **new_url** ; 
 
}

tengo que hacer eso porque Firefox guarda último estado de mi página y lo restaura en lugar de recrearlo.

0

Tuve la misma pregunta y tuve que profundizar en las especificaciones para descubrir por qué el evento popstate no se activa en ningún navegador cuando el botón Atrás se usa para regresar de una página en un dominio diferente. Resulta que el estado emergente no debería activarse en este caso, ya que el estado del documento modificado no es verdadero y el estado emergente solo debería activarse si el estado cambiado es verdadero. Para estado cambiado para que se establezca en verdadera especificación dice:

El estado de cambio será verdadero si el documento de la entrada especificada tiene una entrada más reciente, y esa entrada no es la entrada especificada; de lo contrario, que sea falso.

Según entiendo, cuando volvemos a nuestra página desde una página en un dominio diferente, nuestra página no tiene la última entrada ya que el documento ha cambiado y el documento nuevo no tiene la última entrada. De nuevo desde la especificación:

Cada documento en un contexto de navegación también puede tener una entrada más reciente. Esta es la entrada de ese documento al que se ha cruzado recientemente el historial de la sesión del contexto de exploración. Cuando se crea un documento, inicialmente no tiene la última entrada.

Sin embargo todavía hay una manera de ver si el usuario ha llegado de nuevo a su página estableciendo una bandera en history.state en su página utilizando pushState o replaceState métodos de la historia y la comprobación de la existencia de esta bandera en history.state en la carga de la página.

Para más lectura en formato HTML WHATWG spec la parte referente a eventos popstate: https://html.spec.whatwg.org/multipage/browsers.html#history-traversal

Cuestiones relacionadas