2012-05-17 11 views
6

Estoy trabajando en un proyecto pequeño en el que quiero crear un sitio web de estilo Ajax. El contenido se carga con jQuery's load(). Como algunos de ustedes saben, la desventaja de esto es que la URL no cambia de acuerdo con el contenido que se muestra. Para que esto funcione, puede usar pushState(). Como esto no es compatible con varios navegadores, utilicé el complemento history.js.pushState() y popState(): manipulando la historia de los navegadores

Esto está funcionando bastante bien, pero el problema es que mis botones de atrás y de adelante no funcionan como deberían y no tengo idea de lo que estoy haciendo mal. La URL está cambiando correctamente y el contenido también lo está, pero el título no cambia en absoluto. Con el título me refiero a lo que se muestra como título de la ventana (o pestaña) de la ventana del navegador. Es decir. el <title> de la página que se carga O el atributo de título del enlace que hace referencia a esa página (son los mismos). Creo que tiene que ver con el hecho de que llamo solo a una sección de la página cuyo título necesito (es decir, agregando #content al load()). Aunque aún quiero el título de esa página. Aquí hay un caso de prueba de lo que tengo hasta ahora. (No está disponible ninguna de 2013. más desde el 28 de diciembre) archivo de jQuery:

$(document).ready(function() { 
    var firstLink = $("ul > li:first-child > a"); 
    var menuLink = $("ul > li > a"); 
    var firstLoadedHtml = firstLink.attr("href") + " #content"; 

    $("#sectionContainer").hide().load(firstLoadedHtml).fadeIn("fast"); 
    firstLink.addClass("active"); 

    menuLink.click(function(e) { 
     history.pushState(null, null, this.href); 

     e.preventDefault(); 
     e.stopImmediatePropagation(); 

     var CurLink = $(this); 
     var newLoadedHtml = CurLink.attr("href") + " #content"; 
     var oldSection = $(".contentPage"); 

     $("#sectionContainer").hide().load(newLoadedHtml).fadeIn("fast"); 
     menuLink.removeClass("active"); 
     CurLink.addClass("active"); 
    }); 

    $(window).bind('popstate', function() { 
      var returnLocation = history.location || document.location; 

      $('#sectionContainer').load(returnLocation + "#content"); 
    }); 
}); 

También he observado que cuando se va de nuevo a la página básica (es decir,/sectionLoaderTest /) se queda en blanco durante un tiempo y sólo después de un tiempo el contenido de la primera página está cargado. ¿Hay alguna forma de optimizar esto?

Además, estoy usando jQuery para agregar una clase activa al enlace que se ha hecho clic. ¿Cómo puedo asegurarme de que esto cambie de acuerdo con el historial? ¿Para que el enlace correcto se destaque cuando un usuario navega hacia atrás?

Así las tres preguntas son:

  1. Consigue el título de trabajo cuando se va hacia adelante y hacia atrás
  2. Optimizar el tiempo de carga de la MainPage
  3. Fije la clase activa cuando se va hacia adelante y hacia atrás

¡Toda ayuda es bienvenida!

NOTA 1: Me gustaría construir en history.js y mi propio script y, como tal, mantener la compatibilidad con los navegadores < HTML5. Preferiría esto porque 1. Sé que esto tiene que funcionar, simplemente hay algo que está yendo mal. 2. Ahorraría tiempo si pudiera ver la solución e implementarla en el guión que ya escribí en lugar de encontrar un guión completamente nuevo.

NOTA 2: ¡La recompensa solo se le dará a él o ella que pueda responder todas mis preguntas (3)!

+0

Todavía no está bien, vea un ejemplo de tales aquí http://stackoverflow.com/questions/6622449/why-is-history-pushstate-not-supported-in-ie-are-herehere-some -other-ways-to-ach/9470183 # 9470183 – devote

+0

Su comentario no es realmente útil. No necesito implementar history.js (todavía), solo estoy tratando de entender qué está haciendo pushState por ahora. Quiero solucionar este problema. –

+0

Mi comentario señala su error, cómo ubicar los métodos de procesamiento del evento.El método para interceptar el evento popstate, que ha publicado no es correcto, eliminarlo del método funciona cuando se hace clic. – devote

Respuesta

11

Respuesta 1 - Obtener el título de trabajo cuando se va hacia adelante y hacia atrás

Por lo que he entendido que desea cambiar el título del documento html desde el enlace se carga en un div. Cuando carga un archivo en un div a través de jQuery .load, solo está insertando el texto de respuesta completo después de una solicitud ajax. Entonces, con todas las cosas que no deberían estar en un div como la etiqueta title o meta. Sin embargo, el título del documento actual (http://bramvanroy.be/sectionLoaderTest/index.html) se define en el title que está dentro de la etiqueta head y no en la etiqueta title dentro de un div, por lo que el título del documento no cambia.

Entonces, ¿cómo puedo arreglarlo?

Buena pregunta, porque el elemento de title dentro de un elemento div no es válido, la mayoría de los navegadores le retirarlo por lo que no se puede simplemente usar esto:

document.title = $("#sectionContainer title").text(); 

porque el elemento de title puede no existir.

Lo que necesitamos es la respuesta directa de la función jQuery .load. Puedo conseguir añadiendo el argumento de devolución de llamada a la función:

$("#sectionContainer") 
    .hide() 
    .load(newLoadedHtml, function(responseText) { 
     document.title = $(responseText).filter("title").text(); 
    }) 
    .fadeIn("fast"); 

Lo que no entiendo es por qué utilizo el .filter y no la función .find. Esto se debe a que jQuery está analizando las etiquetas html, head y body del html pero no elimina los elementos secundarios.

Respuesta 2 - Optimizar el tiempo de carga de la MainPage

Un documento está siendo cargado desde la parte superior a la parte inferior.

Por lo tanto, primero debe cargarse el css, JavaScript, etc. y luego el documento principal. Como jQuery siempre está esperando el documento antes de ejecutarlo, no sería una mala idea colocar todos sus elementos script justo antes del final del cuerpo, de modo que su HTML pueda cargarse antes.

BtW Acabo de tener este problema por primera vez después de que todo estaba en caché y el documento se estaba cargando muy rápido.

Respuesta 3 - Fijar la clase activa cuando se va hacia adelante y hacia atrás

diría parabólicos las href atributos de los elementos a y compararlo con los datos de History.getState(). Debería ser fácil.

que usted hizo algunos errores en su código - Su código fijo:

Usted adjuntas, el hash de #content a todas las URL .. que no tiene sentido y se retira de nuevo por jQuery: https://github.com/jquery/jquery/blob/master/src/ajax.js#L617 (Comes a partir de líneas: 158, 190, 337, 617 - rhash está en la línea 6)

$(document).ready(function() { 
    var firstLink = $("ul > li:first-child > a"); 
    var menuLink = $("ul > li > a"); 
    var firstLoadedHtml = firstLink.attr("href"); 

    $("#sectionContainer").hide().load(firstLoadedHtml).fadeIn("fast"); 
    firstLink.addClass("active"); 

    menuLink.click(function(e) { 

     e.preventDefault(); 
     e.stopImmediatePropagation(); 

     var newLoadedHtml = $(this).attr("href"); 

     History.pushState(null, newLoadedHtml, newLoadedHtml); 

     $("#sectionContainer") 
      .hide() 
      .load(newLoadedHtml, function(responseText) { 
       document.title = $(responseText).filter("title").text(); 
      }) 
      .fadeIn("fast"); 
    }); 

    History.Adapter.bind(window, "statechange", function() { 
     menuLink.removeClass("active"); 
     $("a[href='" + History.getState().title + "']").addClass("active"); 
     $('#sectionContainer').load(document.location.href, function(responseText) { 
      document.title = $(responseText).filter("title").text(); 
     }); 
    }); 
}); 
+0

Podría estar perdiendo algo (bastante ocupado con muchas cosas al mismo tiempo) pero no funciona. Título sobre los cambios en el primer y último enlace al que está definido en 'incluye'. Además (y más importante) los botones de retroceso ya no cambian el contenido. Tengo la sensación de que es algo muy básico que estoy revisando. El caso de prueba ha sido editado: http://bramvanroy.be/sectionLoaderTest/ –

+0

La primera página ('Home') tiene un buen título en el documento, todas las otras páginas tienen el título 'Untitled Document' como título. Lo siento, tienes razón, ya no cambia el contenido del historial anterior/reenviar. Es porque 'document.location' es un objeto y necesitas una cadena, antes de que fuera' document.location + "#content" 'Que devolvió una cadena. Entonces necesitas 'document.location.href', mira mi edición. – noob

+1

¡Después de todo, he hecho una nueva edición que funcionará! ** PROBADO ** ¡Incluso el enlace correcto siempre tendrá la clase 'activa'! – noob

Cuestiones relacionadas