saut d'ancre en utilisant javascript

129

J'ai une question que l'on retrouve très souvent. Le problème est que nulle part ne peut être trouvée une solution explicite.

J'ai deux problèmes concernant les ancres.

L'objectif principal devrait être d'obtenir une belle URL propre sans aucun hachage tout en utilisant des ancres pour sauter sur une page.

La structure des ancres est donc:

<ul>
    <li><a href="#one">One</a></li>
    <li><a href="#two">Two</a></li>
    <li><a href="#three">Three</a></li>
</ul>

<div class="wrap">
    <a name="one">text 1</a>
    <a name="two">text 2</a>
    <a name="three" class="box">text 3</a>
</div>

D'accord, si vous cliquez sur l'un des liens, l'URL deviendra automatiquement

www.domain.com/page#1

À la fin, cela devrait être juste:

www.domaine.com/page

Jusqu'ici tout va bien. Maintenant, la deuxième chose est que lorsque vous recherchez sur Internet ce problème, vous trouverez javascriptune solution.

J'ai trouvé cette fonction:

function jumpto(anchor){
    window.location.href = "#"+anchor;
}

et appeler cette fonction avec:

<a onclick="jumpto('one');">One</a>

ce qui sera pareil avant. Il ajoutera le hachage à l'url. J'ai aussi ajouté

<a onclick="jumpto('one'); return false;">

sans succès. Donc, s'il y a quelqu'un qui pourrait me dire comment résoudre ce problème, j'apprécierais vraiment.

Merci beaucoup.

beau
la source
Vous n'êtes pas sûr de cela, mais vous pouvez essayer d'écrire manuellement dans la propriété de hachage après le saut. Par exemple, définissez un délai d'expiration dans le gestionnaire onclick qui définit window.location.hash=''.
Jeff
Voulez-vous dire que vous ne voulez pas que le # apparaisse dans l'URL lorsque vous passez à une autre section de la même page Web?
Roger Ng
2
Dans ce cas, vous devrez soit manipuler le scrollTop de la fenêtre, généralement par window.scrollToou l'aide jQuery correspondante: stackoverflow.com/questions/6677035/jquery-scroll-to-element ou stackoverflow.com/questions/500336/…
Frank van Puffelen
@Jeff - Si vous le faites location.hash='', le #reste là.
Derek 朕 會 功夫
Ne fais pas ça, s'il te plaît. Les hachages sont utiles lors de l'enregistrement de la page dans vos signets.
Marco Sulla

Réponses:

204

Vous pouvez obtenir les coordonnées de l'élément cible et lui définir la position de défilement. Mais c'est tellement compliqué.

Voici une façon plus paresseuse de le faire:

function jump(h){
    var url = location.href;               //Save down the URL without hash.
    location.href = "#"+h;                 //Go to the target element.
    history.replaceState(null,null,url);   //Don't like hashes. Changing it back.
}

Cela utilise replaceStatepour manipuler l'url. Si vous souhaitez également prendre en charge IE , vous devrez le faire de manière compliquée :

function jump(h){
    var top = document.getElementById(h).offsetTop; //Getting Y of target element
    window.scrollTo(0, top);                        //Go there directly or some transition
}​

Démo: http://jsfiddle.net/DerekL/rEpPA/
Une autre avec transition: http://jsfiddle.net/DerekL/x3edvp4t/

Vous pouvez également utiliser .scrollIntoView:

document.getElementById(h).scrollIntoView();   //Even IE6 supports this

(Eh bien, j'ai menti. Ce n'est pas du tout compliqué.)

Derek 朕 會 功夫
la source
1
Les rats!! Le lien est rompu :-( Je pensais que JS Fiddles y était resté pour toujours
Mawg dit de réintégrer Monica
1
@Mawg Apparemment, ils ont supprimé la possibilité d'utiliser add /showà la fin de l'url.
Derek 朕 會 功夫
11
«Même IE6 le supporte» est le meilleur commentaire que j'aie jamais vu.
Josh
3
@Black Il n'existe pas d'élément «jQuery». Si vous souhaitez extraire le premier élément de votre requête, faites $(mySelector)[0].scrollIntoView().
Derek 朕 會 功夫
4
1+ pour scrollIntoView. 1- pour l'avoir mentionné en dernier.
Yay295
12

Je pense que c'est une solution beaucoup plus simple:

window.location = (""+window.location).replace(/#[A-Za-z0-9_]*$/,'')+"#myAnchor"

Cette méthode ne recharge pas le site Web et met l' accent sur les ancres nécessaires au lecteur d'écran.

Adam111p
la source
Et ce qui fonctionne rarement sur IE, cela fonctionne sur tous les IE;)
Adam111p
5
J'ai fini avecwindow.location = window.location.origin + window.location.pathname + '#hash';
Alex
Cela a rechargé la page pour moi. La réponse acceptée a fini par fonctionner, cependant, j'aimerais qu'elle soit plus courte.
HoldOffHunger
3

Pas assez de rep pour un commentaire.

La méthode basée sur getElementById () dans la réponse sélectionnée ne fonctionnera pas si l'ancre a nameété iddéfinie mais non définie (ce qui n'est pas recommandé, mais se produit dans la nature).

Quelque chose à garder à l'esprit si vous n'avez pas le contrôle du balisage du document (par exemple, Webextension).

La locationméthode basée sur la réponse sélectionnée peut également être simplifiée avec location.replace:

function jump(hash) { location.replace("#" + hash) }
cmc
la source
1

Parce que quand tu fais

window.location.href = "#"+anchor;

Vous chargez une nouvelle page, vous pouvez faire:

<a href="#" onclick="jumpTo('one');">One</a>
<a href="#" id="one"></a>

<script>

    function getPosition(element){
        var e = document.getElementById(element);
        var left = 0;
        var top = 0;

        do{
            left += e.offsetLeft;
            top += e.offsetTop;
        }while(e = e.offsetParent);

        return [left, top];
    }

    function jumpTo(id){    
        window.scrollTo(getPosition(id));
    }

</script>
Jonathan Vukovich-Tribouharet
la source
3
Je ne pense pas que l'ajout de hachages en fasse une nouvelle page.
Derek 朕 會 功夫
5
Il ne recharge pas la page.
Derek 朕 會 功夫
Vous avez raison, il ne recharge pas la page. J'essaye en console avec chrome et le favicon est rechargé.
Jonathan Vukovich-Tribouharet
Dans le dernier Firefox, les changements de hachage semblent forcer un rechargement pour les iFrames (dans l'attribut src). Je considérerais cela comme un bogue du navigateur, mais quelque chose dont il faut être conscient.
Beejor
1

J'ai un bouton pour une invite qui, en cliquant dessus, ouvre la boîte de dialogue d'affichage, puis je peux écrire ce que je veux rechercher et il va à cet emplacement sur la page. Il utilise javascript pour répondre à l'en-tête.

Sur le fichier .html j'ai:

<button onclick="myFunction()">Load Prompt</button>
<span id="test100"><h4>Hello</h4></span>

Sur le fichier .js que j'ai

function myFunction() {
    var input = prompt("list or new or quit");

    while(input !== "quit") {
        if(input ==="test100") {
            window.location.hash = 'test100';
            return;
// else if(input.indexOf("test100") >= 0) {
//   window.location.hash = 'test100';
//   return;
// }
        }
    }
}

Lorsque j'écris test100 dans l'invite, il ira à l'endroit où j'ai placé span id = "test100" dans le fichier html.

J'utilise Google Chrome.

Remarque: cette idée vient du lien sur la même page en utilisant

<a href="#test100">Test link</a>

qui sur clic enverra à l'ancre. Pour que cela fonctionne plusieurs fois, par expérience, il faut recharger la page.

Le crédit aux personnes de stackoverflow (et peut-être aussi de stackexchange) ne me souviens pas comment j'ai rassemblé tous les éléments. ☺

S.Doe_Dude
la source