2012-06-07 17 views
9

Por quéhistory.pushState no desencadena evento 'popstate'

$(function() { 
    $(window).bind('popstate', function() {alert('pop');}); 

    window.history.pushState(null, '', '/foo'); 
}); 

no lo hace alerta pop?

Nota: Las pruebas en el último cromo

-

Según MDN:

Un evento popstate se envía a la ventana cada vez que cambia la entrada del historial de activos. Si la entrada de historial activada fue creada por una llamada a pushState o afectada por una llamada a replaceState, la propiedad de estado del evento popstate contiene una copia del objeto de estado de la entrada del historial.

¿Por qué mi pushState no desencadena el evento popstate?

Respuesta

8

El párrafo al que hace referencia es un poco ambiguo. Al leer el example en la misma página, está claro que el estado emergente solo se activa cuando el usuario hace clic en el botón Atrás, no cuando el script llama al pushState().

+5

popstate también se activa cuando el usuario presiona el botón de avance. – circuitry

+0

pushstate activa popstate! Por lo tanto, "un evento de estado emergente se envía a la ventana cada vez que cambia la entrada del historial activo". –

+1

@AlexGill ¿Tiene un caso de prueba que demuestre este comportamiento? Algo como: ' window.onpopstate = function (e) {alert ('popstate'); } history.pushState (null, ''); ' –

0

Me encontré con esto también ... Creo que el evento solo se dispara si tiene algo en el nivel superior de su objeto de datos que es distinto del estado anterior.

Prueba esto:

var data = {rand: Math.random()}; 
window.history.pushState(data, '', '/foo'); 
+0

Esto tampoco llama a estado emergente. Al menos no en Firefox 26. – circuitry

2

Mi solución:

var url = "http://awesome.website.net/route/to/paradise"; 
window.history.pushState({}, "", url); 
window.history.pushState({}, "", url); // yes twice 
window.history.back(); 

se activará una suave navegación a través de eventos 'popstate' y no hay petición HTTP.

+0

¿Esto es lo que hacen todos los frameworks de front-end también? – elliottregan

+0

Eso apesta, porque terminas con un estado directo redundante. No, los marcos no hacen eso. Simplemente tienen un buen código que llama a la misma devolución de llamada tanto en 'popstate' como después de 'pushState'. –

3

Está leyendo la "página de guía" de MDN, que no pretende ser normativa.

considerar leer de MDN "documentation page" for WindowEventHandlers.onpopstate lugar:

Tenga en cuenta que sólo llamar history.pushState() o history.replaceState() no se disparará un evento popstate. El evento de estado emergente solo se desencadena al realizar una acción del navegador, como hacer clic en el botón Atrás (o invocar history.back() en JavaScript). Y el evento solo se desencadena cuando el usuario navega entre dos entradas del historial para el mismo documento.

12

Puede activar manualmente popstate evento en window cada vez que llame history.pushState().

history.pushState(state, '', url); 

var popStateEvent = new PopStateEvent('popstate', { state: state }); 
dispatchEvent(popStateEvent); 
+0

Excelente respuesta, muchas gracias !! – Sachin

0

Documento https://developer.mozilla.org/en-US/docs/Web/Events/popstate dice:

Tenga en cuenta que sólo llamar history.pushState() o history.replaceState() no se disparará un evento popstate. El evento de estado emergente se activará haciendo una acción del navegador, como hacer clic en el botón Atrás o Atrás (o llamando al history.back() o history.forward() en JavaScript).

Cuestiones relacionadas