2011-03-06 15 views
24

Estoy trabajando en un sitio que sirve contenido a través de AJAX.¿Puedo evitar que history.popstate se active en la carga de la página inicial?

Si hace clic en un elemento del menú, un div contenido se actualiza con $.get respuesta, nada especial.

estoy poniendo en práctica history.pushState para permitir la navegación con el botón de retroceso/avance del navegador.

Tengo el siguiente para cargar contenido en el historial de navegación:

$(function() { 
    $(window).bind("popstate", function() { 
     $.getScript(location.href); 
    }); 
}); 

El problema es que cuando se carga una página por primera vez, esta función no $.getScript por lo que la página se carga de nuevo inmediatamente. La primera vez que se carga la página, se renderiza la vista HTML inicial, luego, en la segunda carga, se representa la vista JS, ya que es una solicitud JS.

¿Cómo podría evitar que este evento se dispare en las páginas HTML con las solicitudes?

+0

Nota: history.popstate se llama una vez - de inmediato al cargar la primera página: y esto es por diseño. (marcado en Chrome) –

Respuesta

37

Uso de la API nativa de HTML5 Historia que va a encontrarse con algunos problemas, todos los navegadores HTML5 maneja la API de forma un poco diferente por lo que no sólo puede codificar una vez y esperar que funcione sin implementar soluciones . History.js proporciona una API multiproveedor para la API de historial de HTML5 y una alternativa de hashchange para los navegadores HTML4 si desea realizar esa ruta.

Para la actualización de su sitio web en un/Ajax-aplicación RIA puede utilizar este fragmento de código: https://github.com/browserstate/ajaxify

que es parte del artículo más largo Intelligent State Handling que entra en explicaciones sobre Hashbang, hashes y la API de la historia html5.

Déjeme saber si usted necesita cualquier ayuda adicional :) Saludos.

+1

Gracias por mencionar History.js. Estaba a punto de implementar PushState en nuestro framework y probablemente hubiera terminado por arrancarme los pelos. – andrew

+4

Publicidad desvergonzada de su propio plugin ... tsk tsk ... Es broma History.js me ha salvado la vida (¡y muchísimas horas de trabajo) en muchos proyectos ahora! – Martin

+1

Incluso hasherjs hace bien el trabajo. Funciona perfectamente bien en nuestro sistema de producción actual. –

4

Cuando los primeros navegador carga, que siempre se dispara un evento popstate. Por lo tanto, debe determinar si este estado emergente es suyo o no.

Cuando usted hace su pushState, asegúrese de que tiene un objeto de estado. De esa manera puedes consultarlo más tarde.

Luego, en el manejador de popstate, compruebe el objeto de estado :)

$(function() { 
    $(window).bind("popstate", function(data) { 
     if (data.state.isMine) 
      $.getScript(location.href); 
    }); 
}); 

// then add the state object 
history.pushState({isMine:true},title,url); 

Déjeme saber si usted necesita más ayuda :)

8

Cuando el evento es disparado popstate al cargar la página no lo hará tener una propiedad estatal en el objeto del evento. Esto le permite verificar si el evento se activa para una carga de página o no.

window.onpopstate = function (event) { 
    if (event.state) { 
    // do your thing 
    } else { 
    // triggered by a page load 
    } 
} 
+0

correcto: y puede usar: 'if (!! event.state)' without 'else' –

23

que necesita para obtener la event.originalEvent

// Somewhere in your previous code 
if (history && history.pushState) { 
    history.pushState({module:"leave"}, document.title, this.href); 
} 


$(window).bind("popstate", function(evt) { 
    var state = evt.originalEvent.state; 
    if (state && state.module === "leave") { 
    $.getScript(location.href); 
    } 
}); 
+0

¡Esto funciona increíblemente! Gracias :) – James

+0

¿No prueba la existencia de 'history.pushState' implica la existencia de' history'? ¿Alguien puede decir por qué las pruebas de 'history.pushState' no serían suficientes (use el caso)? –

+0

@OliverSchafeld acaba de ver esto. Si intenta hacer referencia a una propiedad de 'history', pero' history' no es un objeto, arrojará un error. Por lo tanto, debe verificar que 'history' existe (y es un objeto, si no está seguro) antes de intentar usar (o verificar) sus propiedades. –

0

Lo utilizo para cambiar dirección bar y guardar el estado actual, incluyendo el cuerpo HTML actual, y vuelvo a cargar en la espalda Bouton clic, sin ninguna otra llamada AJAX.Todo se guarda en su navegador:

  1. $(document).ajaxComplete(function(ev, jqXHR, settings) { 
    
        var stateObj = { url: settings.url, innerhtml: document.body.innerHTML }; 
        window.history.pushState(stateObj, settings.url, settings.url); 
    }); 
    
    
    window.onpopstate = function (event) { 
        var currentState = history.state; 
        document.body.innerHTML = currentState.innerhtml; 
    }; 
    
Cuestiones relacionadas