Pouvez-vous utiliser la navigation par hachage sans affecter l'historique?

100

J'ai bien peur que cela soit impossible, mais y a-t-il un moyen de modifier la valeur de hachage d'une URL sans laisser une entrée dans l'historique du navigateur et sans recharger ? Ou faire l'équivalent?

En ce qui concerne les détails, je développais une navigation de hachage de base comme:

//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);
    }

En utilisant jQuery, évidemment. L'idée est que dans ce cas précis 1) faire revenir l'utilisateur sur chaque changement d'onglet pourrait effectivement `` casser le bouton de retour '' en empilant des références inutiles, et 2) ne pas conserver l'onglet sur lequel il se trouve actuellement s'il appuie sur Actualiser est un ennui.


la source
Pourquoi voulez-vous changer le hachage si vous ne voulez pas garder l'historique? : |
Ionuț Staicu
10
Parce que lors de l'actualisation, il serait préférable de présenter à l'utilisateur l'onglet sur lequel il se trouvait, mais comme ils peuvent basculer entre les onglets, cela surchargerait inutilement leur historique d'entrées, ce qui rendrait le bouton de retour moins utile. Ceci n'est qu'un exemple, cependant - cela peut être pour chaque fois que vous devez enregistrer un état temporaire mais que vous ne voulez pas compter sur les cookies ou remplir le fichier temporaire de l'utilisateur avec eux. Lorsque vous actualisez, le contenu js est tel que vous l'avez laissé - vous n'avez pas quitté la page, et ce n'est pas un point de saut ou une page psuedo, donc l'entrée d'historique ne peut interférer qu'avec la navigation standard.

Réponses:

95

location.replace("#hash_value_here");a bien fonctionné pour moi jusqu'à ce que je trouve que cela ne fonctionne pas sur IOS Chrome. Dans ce cas, utilisez:

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

history.replaceState () fonctionne exactement comme history.pushState () sauf que replaceState () modifie l'entrée d'historique actuelle au lieu d'en créer une nouvelle.

N'oubliez pas de conserver la #ou la dernière partie de l'url sera modifiée.

Lucie
la source
3
Totalement la voie à suivre pour les navigateurs modernes; soyez cependant conscient de la gestion partielle de l' historique des sessions d' assistance .
Matt
Je ne sais pas comment utiliser cela. Dois-je toujours utiliser window.location.hash = 'my-hash';suivi de history.replaceState(undefined, undefined, "#my-hash")?
Bram Vanroy
2
@BramVanroy Non, utiliser ce dernier est suffisant.
Lucia
2
À moins que vous n'utilisiez: sélecteurs de cible ... alors les fonctions d'historique sont inutiles, car cette partie de la spécification (interaction css avec les opérations d'historique) semble ne pas être définie actuellement, et le style n'est pas recalculé sur l'historique remplacé par la plupart / tous les navigateurs.
morphles
@Luxiyalu, en quoi history.replaceStatediffère- location.replacet-il de ?
Pacerier
99
location.replace("#hash_value_here"); 

Ce qui précède semble faire ce que vous recherchez.

Mat
la source
4
Ça y est. Et si vous avez des segments uri, location.replace (window.location + "#hash") les conservera.
faneuses le
7
En appuyant cette méthode, beaucoup plus propre, j'aurais aimé qu'elle soit marquée comme la bonne réponse.
joeellis
14
window.location.replace(('' + window.location).split('#')[0] + '#' + hash);pour simplement mettre à jour le hachage
johnstorm
1
Je le teste dans Chrome 30 sous Windows 8, si je vais dans l'historique Chrome et que je sélectionne "Plus sur ce site" sous mon url de test, je peux voir tous les hachages qui ont été ajoutés avec cette méthode.
Alex Vang
1
Attention, location.replace ('# hash_value_here') ne change que le fragment de hachage et non le chemin, donc il ne déclenche pas de chargement de page .... Sauf lorsque le document contient une balise de base: <base href ="http://example.com/" /> s'il contient une balise de base , alors lorsque vous utilisez la méthode replace avec juste un début, "#hash_value_here"ce sera comme si vous aviez dit `location.replace (' example.com/#hash_value_here' ). Cela semble évident lorsque vous le lisez ici, mais c'est un piège lorsque vous êtes sur une page avec un fragment de chemin et que vous ne réalisez pas que la base est définie.
Tyler Kasten
6

Edit: Cela fait maintenant quelques années, et les navigateurs ont évolué.

La réponse de @ Luxiyalu est la voie à suivre

- Ancienne réponse -

Je pense aussi que c'est impossible (pour le moment). Mais pourquoi avez-vous besoin de changer la valeur de hachage si vous n'allez pas l'utiliser?

Je pense que la principale raison pour laquelle nous utilisons la valeur de hachage en tant que programmeurs est de laisser l'utilisateur mettre nos pages en favori ou d'enregistrer un état dans l'historique du navigateur. Si vous ne voulez rien faire de cela, enregistrez simplement l'état dans une variable et travaillez à partir de là.

Je pense que la raison d'utiliser un hachage est de travailler avec une valeur qui est hors de notre contrôle. Si vous n'en avez pas besoin, cela signifie probablement que vous avez tout sous votre contrôle, alors stockez simplement l'état dans une variable et travaillez avec. (J'aime me répéter)

J'espère que cela vous aidera. Il existe peut-être une solution plus simple à votre problème.

MISE À JOUR: Que diriez-vous de ceci:

  1. Configurez un premier hachage et assurez-vous qu'il est enregistré dans l'historique du navigateur.
  2. Lorsqu'un nouvel onglet est sélectionné, faites window.history.back(1), cela fera revenir l'historique de votre premier hachage init.
  3. Maintenant que vous définissez le nouveau hachage, la tabulation ne fera qu'une entrée dans l'historique.

Vous devrez probablement utiliser quelques indicateurs, pour savoir si l'entrée courante peut être "supprimée" en revenant, ou si vous sautez simplement la première étape. Et pour vous assurer que votre méthode de chargement pour le "hachage" ne s'exécute pas, lorsque vous forcez le history.back.

guzart
la source
Il est très possible qu'il me manque quelque chose de basique (l'épuisement est une bonne excuse, je vais y aller) mais vous dites que je peux définir une variable qui conservera sa valeur modifiée lors du rechargement? D'ailleurs avec un cookie? (Les cookies semblent exagérés, d'une manière ou d'une autre.) C'est peut-être ce qui n'était pas clair. J'utiliserai la valeur de hachage - en particulier lors du rechargement. Merci d'avoir répondu!
Pour clarifier ma clarification: si l'utilisateur frappe recharger. C'est à cela que sert le hachage. J'essaye toujours d'éviter de recharger dans leur utilisation normale (changer / cliquer des onglets).
Ok, vous utiliserez donc certaines valeurs pour les informations après le rechargement. Malheureusement, la valeur de hachage sera choisie par l'historique de certains navigateurs. Désolé de le dire, mais d'après mon exp, les cookies sont votre meilleur choix. Si vous voulez quelque chose que l'historique du navigateur ne détecte pas, mais qu'il conserve après le rechargement, malheureusement, des cookies. Si l'utilisateur cliquait sur un lien, vous pouvez configurer le lien pour qu'il soit une requête ( ?mystate=greatness), même s'il n'a pas besoin d'être ajax, vous pouvez enregistrer les informations que le javascript lira lors de l'initialisation de la requête.
guzart
Oui, le hachage sert à enregistrer les informations de l'utilisateur après avoir appuyé sur le rechargement, mais le problème pour votre situation, c'est que certains navigateurs enregistreront ces modifications dans l'historique, c'est juste la façon dont ils fonctionnent ... :(
guzart
Oui, pensez que vous avez raison. Et bien. (
-1

Vous pouvez toujours créer un écouteur d'événements pour capturer les événements de clic sur le lien hypertexte et dans la fonction de rappel mettre e.preventDefault (), ce qui devrait empêcher le navigateur de l'insérer dans l'historique.

Ayman Farhat
la source