Mantener el historial de cambios hash/anchor en JavaScript


Actualmente estoy implementando una biblioteca JavaScript que realiza un seguimiento del historial de cambios en la parte hash en la barra de direcciones. La idea es que puede mantener un estado en la parte hash, y luego usar el botón atrás para volver al estado anterior.

En la mayoría de los navegadores recientes, esto es automático y solo tiene que sondear la propiedad location.hash para los cambios (En IE8 ni siquiera tiene que hacer eso; simplemente adjunte una función al evento onhashchange.)

Lo que me pregunto es, ¿qué métodos diferentes hay para llevar un registro de la historia? He implementado la funcionalidad que ha sido probada para funcionar en Internet Explorer 6/7/8, Firefox y Chrome, pero ¿qué pasa con otros navegadores? Estas son las formas en que actualmente mantengo la historia:

Editar: Ver mi respuesta a continuación en lugar de un paseo a través de los diversos navegadores.

Author: Paramaeleon, 2009-07-03

5 answers

En primer lugar, gracias a ustedes que respondieron! =)

Ahora he hecho mucha más investigación y creo que estoy satisfecho con mi implementación. Aquí están los resultados de mi investigación.

En primer lugar, mi biblioteca terminada Hash . Es una biblioteca independiente sin dependencias. Tiene dos funciones: Hash.init(callback, iframe) y Hash.go(newHash). La función callback se llama cada vez que el hash cambia con el nuevo hash como su primer argumento, y como su segundo argumento una bandera que indica si la devolución de llamada se llama debido al estado inicial (true) o un cambio real en el hash (false).

Hachís.js (licencia MIT)

También hice un plugin de jQuery para hacerlo más fácil de usar. Añade un evento global hashchange también. Vea el ejemplo en el código fuente para saber cómo usarlo.

Jquery.hash.js (licencia MIT)

Para verlos en uso, vaya a mi página "realm" de JavaScript:

Javascript de Blixt realm

Internet Explorer 8

¡Smoooth cruisin'! Solo tienes que golpear en uno de ellos onhashchange eventos al objeto window (usando attachEvent) y obtener el valor location.hash en el controlador de eventos.

No importa si el usuario hace clic en un enlace con un hash, o si establece el hash mediante programación; el historial se mantiene perfectamente.

Chrome, Firefox, Safari 3+, Opera 8+

¡Crucero suave! Basta con sondear los cambios en la propiedad location.hash usando setInterval y un función.

La historia funciona perfectamente. Para Opera, pongo history.navigationMode a 'compatible'. Para ser honesto, no estoy seguro de lo que hace, lo hice por recomendación de un comentario en el código YUI.

Nota: Opera necesita algunas pruebas adicionales, pero ha funcionado bien para mí hasta ahora.

Sorpresa de bonificación peculiaridad! (Puede ser?!) Resulta que Firefox (solo confirmado en 3.5+) decodifica la propiedad location.hash, por lo que esto puede desencadenar un evento hashchange dos veces (primero para la versión codificada y luego para la versión no codificada.) Hay una nueva versión de mi Hash.biblioteca js que toma esto en cuenta usando la propiedad location.href en su lugar (cambios proporcionados por Aaron Ogle.)

Internet Explorer 6, 7

Ahora se vuelve más desagradable. El historial de navegación en versiones anteriores de Internet Explorer ignora los cambios de hash. Para solucionar esto, la solución comúnmente aceptada es crear un iframe y establecer su contenido en el nuevo hash. Esto crea una nueva entrada en el historial de navegación. Cuando el usuario regresa, esto cambia el contenido de iframe a su contenido anterior. Al detectar el cambio de contenido, puede obtenerlo y configurarlo como el hash activo.

La comprobación de cambios en la propiedad location.hash sigue siendo necesaria para los cambios manuales en la dirección actual. Sin embargo, ten cuidado con las peculiaridades que he mencionado a continuación.

Si bien esta solución parece ser la mejor que hay, todavía no es perfecta en Internet Explorer 6, que es un poco peculiar sobre los botones atrás / adelante. Internet Explorer 7 funciona bien, sin embargo.

Sorpresa peculiaridad bono # 1! En Internet Explorer 6, cada vez que hay un signo de interrogación en el hash, esto se extrae y se pone en el location.search ¡propiedad! Se retira de la location.hash propiedad. Sin embargo, si hay una cadena de consulta real, location.search contendrá que uno en su lugar, y solo será capaz de obtener todo el verdadero hash mediante el análisis de la location.href propiedad.

Sorpresa peculiaridad bono # 2! Si el location.search la propiedad se establece, los siguientes # los personajes serán eliminados de la location.href (y location.hash) de la propiedad. En Internet Explorer 6 esto significa que cada vez que hay un signo de interrogación en la ruta o el hash, experimentarás esta peculiaridad. En Internet Explorer 7, esta peculiaridad solo ocurre cuando hay un signo de interrogación en el camino. ¿No te encanta la consistencia en Internet Explorer?

Sorpresa peculiaridad bono # 3! Si otro elemento de la página tiene el mismo id que el valor de un hash, que hash totalmente estropear la historia. Por lo tanto, la regla general es evitar los hashes con el mismo id que cualquier elemento de la página. Si los hashes se generan dinámicamente y pueden colisionar con los ids, considere usar un prefijo / sufijo.

Otros navegadores

A menos que tengas una base de usuarios fuera de lo común, no necesitarás soporta más navegadores. Los navegadores no mencionados anteriormente están en la categoría de uso

 32
Author: Blixt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-17 11:52:16

Basado en el esfuerzo que has puesto en esto, asumiría que has visto YUI Browser History Manager, pero por si acaso ...

Dan un buen escrito de su implementación, y encuentro su código fuente muy legible.

Esto es lo que dice sobre Opera

* location.hash is a bit buggy on Opera. I have seen instances where
* navigating the history using the back/forward buttons, and hence
* changing the URL, would not change location.hash. That's ok, the
* implementation of an equivalent is trivial ... more below

Buscando en la fuente encontré algunos alojamientos para Safari 1.x y 2.0 también. Parece que te interesaría.

Espero que eso ayude.

 3
Author: Keith Bentrup,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-04 15:55:16

No estoy seguro de entender completamente sus necesidades, pero he utilizado la biblioteca de Historia Realmente Simple ( http://code.google.com/p/reallysimplehistory / ) para implementar algo similar. Puedes verlo aquí: http://whiteoak.sourceforge.net /

 1
Author: Itay Maman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-03 09:27:39

No he visto nada mencionado sobre lo que estoy a punto de decir en ninguna parte, así que pensé en compartir y ver qué tan común es el conocimiento.

En IE (solo verificado en IE7), el historial con el hash funciona correctamente cuando hay un elemento page en la pantalla con un id igual al hash. Por ejemplo, piense en una tabla de contenidos (TOC) en una página wiki. Cada enlace en el ÍNDICE enlaza a un hash de un elemento id o anchor name en algún lugar de la página:

<div id="TOC">
<a id="SampleHeaderLink" href="#SampleHeader">Sample Header</a>
</div>

<h2 id="SampleHeader">Sample Header</a>

Así que cuando SampleHeaderLink es al hacer clic, la configuración predeterminada del navegador IE es navegar a SampleHeader y registrar el estado en el historial. Usar el botón atrás y el botón adelante funciona como se espera.

Sin embargo, si el div de SampleHeader no existe en la página, el navegador solo registra el cambio de url, pero no crea un nuevo estado para él.

Nuevamente, esto solo se verifica en IE7. Y no se cuan común-conocimiento esta información es, pero nunca encontré nada relacionado cuando estaba navegando para arreglar este mismo tema en mi propia solicitud.

 0
Author: Beez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-28 20:34:50

GWT proporciona gestión del historial. También es una parte integral de su marco MVP. También han mejorado la API de historia con lugares y actividades.

 -1
Author: James Annesley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-08 17:00:01