¿Puedes usar la navegación hash sin afectar el historial?


99

Me temo que puede ser imposible, pero ¿hay alguna manera de cambiar el valor hash de una URL sin dejar una entrada en el historial del navegador y sin recargar ? ¿O el equivalente?

En cuanto a los detalles, estaba desarrollando una navegación hash básica en las líneas de:

//hash nav -- works with js-tabs
var getHash = window.location.hash;
var hashPref = "tab-";
function useHash(newHash) {
    //set js-tab according to hash
    newHash = newHash.replace('#'+hashPref, '');
    $("#tabs li a[href='"+ newHash +"']").click();
}
function setHash(newHash) {
    //set hash according to js-tab
    window.location.hash = hashPref + newHash;

    //THIS IS WHERE I would like to REPLACE the location.hash
    //without a history entry

}
    // ... a lot of irrelavent tabs js and then....

    //make tabs work
    $("#tabs.js-tabs a").live("click", function() {
        var showMe = $(this).attr("href");
        $(showMe).show();
        setHash(showMe);
        return false;
    });
    //hash nav on ready .. if hash exists, execute
    if ( getHash ){
        useHash(getHash);
    }

Usando jQuery, obviamente. La idea es que en esta instancia específica 1) hacer que el usuario vuelva a cada cambio de pestaña podría efectivamente 'romper el botón de retroceso' al acumular referencias innecesarias, y 2) no retener en qué pestaña se encuentra actualmente si presiona actualizar es una molestia.


¿Por qué quiere cambiar el hash si no quiere mantener un historial? : |
Ionuț Staicu

9
Porque en la actualización sería mejor presentar al usuario la pestaña en la que se encontraba, pero dado que puede estar cambiando entre pestañas, saturaría su historial con entradas innecesariamente, haciendo que el botón Atrás sea menos útil. Sin embargo, este es solo un ejemplo; podría ser para cualquier momento en el que necesite guardar un estado temporal pero no quiera depender de las cookies o llenar el archivo temporal del usuario con ellas. Cuando actualiza, el contenido de js es como lo dejó: no ha abandonado la página y no es un punto de salto o una página psuedo, por lo que la entrada del historial solo puede interferir con la navegación estándar.

Respuestas:


94

location.replace("#hash_value_here");funcionó bien para mí hasta que descubrí que no funciona en IOS Chrome. En cuyo caso, utilice:

history.replaceState(undefined, undefined, "#hash_value")

history.replaceState () funciona exactamente como history.pushState () excepto que replaceState () modifica la entrada actual del historial en lugar de crear una nueva.

Recuerde mantener la #o la última parte de la URL será alterada.


3
Totalmente el camino a seguir para los navegadores modernos; Sin embargo, tenga en cuenta la gestión del historial de sesiones de soporte parcial .
Matt

Estoy confundido sobre cómo usar esto. ¿Debo seguir usando window.location.hash = 'my-hash';seguido de history.replaceState(undefined, undefined, "#my-hash")?
Bram Vanroy

2
@BramVanroy No, usar este último es suficiente.
Lucia

2
A menos que use: selectores de destino ... entonces las funciones de historial son inútiles, ya que esa parte de la especificación (interacción css con operaciones de historial) parece no estar definida actualmente, y el estilo no se vuelve a calcular en el reemplazo de historial por la mayoría / todos los navegadores.
morphles

@Luxiyalu, ¿en qué se history.replaceStatediferencia de location.replace?
Pacerier

99
location.replace("#hash_value_here"); 

Lo anterior parece hacer lo que buscas.


4
Eso es todo. Y si tiene segmentos uri, location.replace (window.location + "#hash") los conservará.
Henificadoras

7
Secundando este método, mucho más limpio, desearía que estuviera marcado como la respuesta correcta.
joeellis

14
window.location.replace(('' + window.location).split('#')[0] + '#' + hash);para actualizar el hash
johnstorm

1
Lo estoy probando en Chrome 30 en Windows 8, si voy al Historial de Chrome y selecciono "Más de este sitio" en mi URL de prueba, puedo ver todos los hash que se agregaron con este método.
Alex Vang

1
Tenga en cuenta que location.replace ('# hash_value_here') solo cambia el fragmento hash y no la ruta, por lo que no desencadena la carga de una página ... Excepto cuando el documento contiene una etiqueta base: <base href ="http://example.com/" /> si contiene una etiqueta base , entonces, cuando use el método de reemplazo con solo un principio "#hash_value_here", será como si dijera `location.replace (' example.com/#hash_value_here' ). Esto parece obvio cuando lo lee aquí, pero es un problema cuando está en una página con un fragmento de ruta y no se da cuenta de que la base está configurada.
Tyler Kasten

6

Editar: Han pasado un par de años y los navegadores han evolucionado.

La respuesta de @ Luxiyalu es el camino a seguir

- Respuesta anterior -

Yo también creo que es imposible (en este momento). Pero, ¿por qué necesita cambiar el valor hash si no lo va a utilizar?

Creo que la razón principal por la que usamos el valor hash como programadores es para permitir que el usuario marque nuestras páginas o para guardar un estado en el historial del navegador. Si no desea hacer nada de esto, simplemente guarde el estado en una variable y trabaje desde allí.

Creo que la razón para usar un hash es trabajar con un valor que está fuera de nuestro control. Si no lo necesita, probablemente significa que tiene todo bajo su control, así que simplemente almacene el estado en una variable y trabaje con él. (Me gusta repetirme)

Espero que esto te ayude. Quizás haya una solución más fácil para su problema.

ACTUALIZACIÓN: ¿Qué tal esto?

  1. Configure un primer hash y asegúrese de que se guarde en el historial del navegador.
  2. Cuando se selecciona una nueva pestaña, hazlo window.history.back(1), eso hará que el historial retroceda desde tu primer hash de inicio.
  3. Ahora configura el nuevo hash, por lo tanto, la tabulación solo hará una entrada en el historial.

Probablemente tendrá que usar algunas banderas para saber si la entrada actual se puede "eliminar" volviendo atrás, o si simplemente se salta el primer paso. Y para asegurarse de que su método de carga para el "hash" no se ejecute, cuando fuerce el history.back.


Es muy posible que me falte algo básico (el agotamiento es una buena excusa, lo aceptaré), pero ¿estás diciendo que puedo establecer una variable que retendrá su valor modificado en la recarga? ¿Además de una galleta? (Las cookies parecen exageradas, de alguna manera ...) Quizás eso es lo que no estaba claro. Usaré el valor hash, particularmente en la recarga. ¡Gracias por responder!

Para aclarar mi aclaración: si el usuario presiona recargar. Para eso es el hachís. Todavía estoy tratando de evitar la recarga en su uso normal (cambiar / hacer clic en las pestañas).

Ok, entonces usarás algunos valores para información después de recargar. Bueno, desafortunadamente, el valor hash será elegido por el historial de algunos navegadores. Lamento decir esto, pero desde mi experiencia, las cookies son su mejor opción. Si desea algo que el historial del navegador no detecta, pero que se conserva después de la recarga, desafortunadamente, las cookies. Si el usuario estaba haciendo clic en un enlace, entonces puede configurar el enlace para que sea una consulta ( ?mystate=greatness), aunque no necesita ser ajax, puede guardar información para que el javascript la lea al inicializar la solicitud.
Guzart

Sí, el hash es para guardar la información del usuario después de presionar recargar, pero el problema para su situación es que algunos navegadores guardarán esos cambios en el historial, así es como funcionan ... :(
guzart

Sí, creo que tienes razón. Ah bueno. (Me encantaría que se demuestre que está equivocado con algún otro método o algo así.)

-1

Siempre puede crear un detector de eventos para detectar eventos de clic en el hipervínculo y en la función de devolución de llamada poner e.preventDefault (), que debería evitar que el navegador lo inserte en el historial.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.