2010-05-06 15 views
5

Con una sola aplicación, donde se cambia el hash y carga y cambiar sólo el contenido de la página, estoy tratando de decidir sobre la forma de gestionar el código JavaScript que cada " página "podría necesitar.mejores prácticas de gestión de código JavaScript en una aplicación de una sola página

Ya tengo un módulo de historial que supervisa el hash de ubicación que podría verse como domain.com/#/company/about, y una clase de página que usará XHR para obtener el contenido e insertarlo en el área de contenido.

function onHashChange(hash) { 
    var skipCache = false; 
    if(hash in noCacheList) { 
     skipCache = true; 
    } 
    new Page(hash, skipCache).insert(); 
} 


// Page.js 
var _pageCache = {}; 
function Page(url, skipCache) { 

    if(!skipCache && (url in _pageCache)) { 
     return _pageCache[url]; 
    } 
    this.url = url; 
    this.load(); 

} 

La memoria caché debe permitir que las páginas que ya se han cargado omitan el XHR. También estoy almacenando el contenido en un documentFragment, y luego extrayendo el contenido actual del documento cuando inserto el nuevo Page, por lo que el navegador solo tendrá que generar el DOM para el fragmento una vez.

Se puede perder la caché si la página tiene datos confidenciales.

Esto es lo que necesito ayuda para tomar una decisión: Es muy probable que cualquiera de las páginas que se carguen tenga su propio JavaScript para controlar la página. Por ejemplo, si la página usará pestañas, necesita una presentación de diapositivas, tiene algún tipo de animación, tiene una forma Ajax o lo que sea que tenga.

¿Qué es exactamente la mejor manera de ir alrededor de la carga que JavaScript en la página? Incluir las etiquetas de script en el documento Fragmento que obtengo del XHR? ¿Qué pasa si necesito omitir el caché y volver a descargar el fragmento? Siento que el mismo JavaScript que se llama por segunda vez puede causar conflictos, como volver a definir las mismas variables.

¿La mejor manera de ser para unir las secuencias de comandos para la cabeza cuando se agarra el nuevo Page? Eso requeriría que la página original conozca todos los recursos que cualquier otra página podría necesitar.

Y además de conocer la mejor manera de incluir todo, a que no tenga que preocuparse por la gestión de memoria, y las posibles fugas de carga tantas diferentes bits de JavaScript en una sola instancia de página?

+0

¿Qué es una aplicación de una sola página? –

+1

Donde carga en la primera página desde el servidor y todo lo demás usa XHR, en lugar de solicitudes de página completa. Facebook es un ejemplo. – seanmonstar

+0

jQuery es tu amigo. Cómprelo una bebida. –

Respuesta

0

Nunca he creado un sitio así que no sé si es la mejor práctica, pero pondría algún tipo de información de control (como un comentario o un encabezado HTTP) en la respuesta, y dejaría que el script del cargador manejar el cheching de redundancia/dependencia y agregar las etiquetas de script al encabezado.

0

¿Tiene control sobre las páginas que se cargan? De lo contrario, recomendaría insertar la página cargada en un IFrame.

Tomando los guiones de la página de su contexto y la inserción de ellos en la cabeza o la adición de ellos a otro elemento HTML puede causar problemas a menos que sepa exactamente cómo se construye la página.

Si usted tiene el control total de las páginas que se está cargando, yo recomendaría que convertir todo el código HTML a JS. Puede sonar extraño, pero en realidad, un convertidor HTML-> JS no está tan lejos. Puede comenzar con Pure JavaScript HTML Parser y luego dejar que el analizador genere el código JS, que crea el DOM utilizando JQuery, por ejemplo.

Estaba a punto de ir por ese camino hace un rato en una aplicación web en la que comencé a trabajar, pero ahora se la pasé a un contratista que convirtió todas mis páginas JS en HTML + JQuery, lo que sea que El trabajo diario es productivo, no me importa, pero realmente me interesaba ese enfoque de JS Webapp puro y definitivamente lo intentaré.

+0

Tengo control sobre las páginas. Estaba considerando un analizador JS. Pero ya estaré creando las páginas en PHP, y dado que PHP es mucho más rápido que JS, simplemente iba a devolver el HTML. – seanmonstar

1

Si entiendo el caso correctamente, está tratando de tomar un sitio que actualmente tiene páginas ya hechas para la navegación normal, y desea bajarlas a través de ajax, para ahorrar la página de recarga?

Entonces, cuando esto sucede, no necesita volver a cargar las etiquetas de script para esas páginas, a menos que ya no estén cargadas en la página.

Si ese es el caso, se podría tratar de agarrar todas las etiquetas de la página antes de insertar el nuevo HTML en el DOM:

//first set up a cache of urls you already have loaded. 
var loadedScripts = []; 

//after user has triggered the ajax call, and you've received the text-response 
function clearLoadedScripts(response){ 
    var womb = document.createElement('div'); 
    womb.innerHTML = response; 
    var scripts = womb.getElementsByTagName('script'); 
    var script, i = scripts.length; 
    while (i--) { 
     script = scripts[i]; 
     if (loadedScripts.indexOf(script.src) !== -1) { 
      script.parentNode.removeChild(script); 
     } 
     else { 
      loadedScripts.push(script.src); 
     } 
    } 

    //then do whatever you want with the contents.. something like: 
    document.body.innerHTML = womb.getElementsByTagName('body')[0].innerHTML); 

} 
+0

Esta es una implementación bastante impresionante ... – gnarf

0

A mí me suena como que está creando una aplicación de una sola página desde el comienzo (es decir, no volver a factorizar un sitio existente).

varias opciones que se me ocurren:

  1. dejar que el control de servidor qué etiquetas de secuencia de comandos se incluyen. pase una lista de etiquetas de script ya cargadas con la solicitud XHR y haga que el servidor determine qué scripts adicionales deben cargarse.
  2. Cargue todos los scripts de antemano (quizás agréguelos al DOM después de la página se ha cargado para ahorrar tiempo) y luego olvídese de ello. Para las secuencias de comandos que necesitan inicializar la interfaz de usuario, simplemente haga que cada llamada de página solicitada incluya una etiqueta de secuencia de comandos que llame a una función de inicio global con el nombre de la página.
  3. Haga que cada página solicitada llame a la función JS que se ocupa de cargar/almacenar en caché las secuencias de comandos. Esta función sería accesible desde el alcance global y se vería así: require_scripts('page_1_init', 'form_code', 'login_code') Luego solo haga que la función mantenga una lista de scripts cargados y solo añada etiquetas de scripts DOM para scripts que aún no se han cargado.
0

Se puede usar un cargador de script como YUI cargador, LAB.js o de otro tipo, como jaf

Jaf le proporciona el mecanismo para cargar puntos de vista (fragmentos de HTML) y sus respectivos js, css para crear una sola página aplicaciones. Echa un vistazo a la aplicación de la lista de tareas pendientes. Aunque no está completo, todavía hay muchas bibliotecas útiles que puedes usar.

1

Oh chico estás de suerte. Acabo de hacer toda esta investigación para mi propio proyecto.

1: El evento de hash/gerente que debe utilizar es barbacoa de Ben Alman: http://benalman.com/projects/jquery-bbq-plugin/

2: Para hacer que los motores de búsqueda les encanta, es necesario seguir esta muy claro conjunto de reglas: http://code.google.com/web/ajaxcrawling/docs/specification.html

Encontré esto tarde y el juego y tuve que desechar un montón de mi código. Parece que también tendrás que desechar algunos, pero como consecuencia, obtendrás mucho más de ellos.

¡Buena suerte!

+0

gracias por ese artículo google.com ajaxcrawling. Estaba buscando eso. – seanmonstar

+0

NP! Marque esta como la respuesta si es lo que estaba buscando. – Matrym

+0

estaba buscando el enlace, pero no creo que esto responda la pregunta, lo siento. Estoy más interesado en la administración de Javascript requerida por varias páginas, manejo de variables recién declaradas, eventos adjuntos y desconectados, y administración de memoria. – seanmonstar

0

Personalmente, me gustaría transmitir JSON en lugar de HTML puro:

{ 
    "title": "About", 
    "requires": ["navigation", "maps"], 
    "content": "<div id=…" 
} 

Esto le permite enviar metadatos, como una serie de secuencias de comandos requeridos, junto con el contenido.Luego usaría un gestor de carga, como uno de los mencionados anteriormente, o el suyo, para verificar cuáles ya están cargados y desplegar los que no están (insertándolos en el <head>) antes de representar la página.

En lugar de incluir scripts en línea para la lógica específica de la página, utilizaría clases predeterminadas, identificadores y atributos en elementos que requieren un manejo especial. Puede iniciar un evento "onrender" o dejar que cada parte de la lógica registre una devolución de llamada en el render que su cargador de página llamará después de que una página se represente o cargue por primera vez.

Cuestiones relacionadas