Ankerspringen mit Javascript

129

Ich habe eine Frage, die sehr oft gestellt wird. Das Problem ist, dass nirgends eine explizite Lösung gefunden werden kann.

Ich habe zwei Probleme mit Ankern.

Das Hauptziel sollte sein, eine schöne, saubere URL ohne Hashes zu erhalten, während Anker verwendet werden, um auf eine Seite zu springen.

Die Struktur der Anker ist also:

<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>

Okay, wenn Sie auf einen der Links klicken, ändert sich die URL automatisch

www.domain.com/page#1

Am Ende sollte dies nur sein:

www.domain.com/page

So weit, ist es gut. Das zweite ist, wenn Sie im Internet nach diesem Problem suchen, werden Sie javascripteine Lösung finden.

Ich habe diese Funktion gefunden:

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

und Aufrufen dieser Funktion mit:

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

wie wird das gleiche sein wie vorher. Der Hash wird der URL hinzugefügt. Ich habe auch hinzugefügt

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

ohne Erfolg. Wenn es also jemanden gibt, der mir sagen könnte, wie ich das lösen kann, wäre ich wirklich dankbar.

Vielen Dank.

schön
quelle
Ich bin mir nicht sicher, aber Sie können versuchen, nach dem Sprung manuell in die Hash-Eigenschaft zu schreiben. Legen Sie beispielsweise im Onclick-Handler ein Timeout fest, das festgelegt wird window.location.hash=''.
Jeff
Meinen Sie damit, dass das # nicht in der URL angezeigt werden soll, wenn Sie zu einem anderen Abschnitt auf derselben Webseite springen?
Roger Ng
2
In diesem Fall müssen Sie entweder das scrollTop des Fensters bearbeiten, normalerweise von window.scrollTooder dem entsprechenden jQuery-Helfer: stackoverflow.com/questions/6677035/jquery-scroll-to-element oder stackoverflow.com/questions/500336/…
Frank van Puffelen
@ Jeff - Wenn du das tust location.hash='', #bleibt das da.
Derek 6 會 功夫
Bitte mach das nicht. Hashes sind gut, wenn Sie die Seite in Ihren Lesezeichen speichern.
Marco Sulla

Antworten:

204

Sie können die Koordinate des Zielelements abrufen und die Bildlaufposition darauf einstellen. Das ist aber so kompliziert.

Hier ist ein fauler Weg, dies zu tun:

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.
}

Dies wird verwendet replaceState, um die URL zu manipulieren. Wenn Sie auch Unterstützung für IE wünschen , müssen Sie dies auf komplizierte Weise tun :

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

Demo: http://jsfiddle.net/DerekL/rEpPA/
Eine weitere mit Übergang: http://jsfiddle.net/DerekL/x3edvp4t/

Sie können auch verwenden .scrollIntoView:

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

(Nun, ich habe gelogen. Es ist überhaupt nicht kompliziert.)

Derek 朕 會 功夫
quelle
1
Ratten !! Die Verbindung ist unterbrochen :-( Ich dachte, dass JS Fiddles für immer dort geblieben ist
Mawg sagt, Monica
1
@Mawg Anscheinend haben sie die Möglichkeit entfernt, add /showam Ende der URL zu verwenden.
Derek 24 會 功夫
11
"Sogar IE6 unterstützt dies" ist der beste Kommentar, den ich je gesehen habe.
Josh
3
@Black Es gibt kein "jQuery" -Element. Wenn Sie das erste Element aus Ihrer Abfrage herausholen möchten, tun Sie dies $(mySelector)[0].scrollIntoView().
Derek 8 會 功夫
4
1+ für scrollIntoView. 1- für die letzte Erwähnung.
Yay295
12

Ich denke, es ist eine viel einfachere Lösung:

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

Diese Methode lädt die Website nicht neu und legt den Fokus auf die Anker, die für den Bildschirmleser benötigt werden.

Adam111p
quelle
Und was im IE selten funktioniert, funktioniert im gesamten IE;)
Adam111p
5
Ich endete mitwindow.location = window.location.origin + window.location.pathname + '#hash';
Alex
Dadurch wurde die Seite für mich neu geladen. Die akzeptierte Antwort funktionierte jedoch, ich wünschte, sie wäre kürzer.
HoldOffHunger
3

Nicht genug Vertreter für einen Kommentar.

Die auf getElementById () basierende Methode in der ausgewählten Antwort funktioniert nicht, wenn der Anker gesetzt, nameaber nicht idgesetzt wurde (was nicht empfohlen wird, aber in freier Wildbahn geschieht).

Denken Sie daran, wenn Sie keine Kontrolle über das Dokument-Markup haben (z. B. Webextension).

Die locationbasierte Methode in der ausgewählten Antwort kann auch vereinfacht werden mit location.replace:

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

Denn wenn du es tust

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

Sie laden eine neue Seite, Sie können:

<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
quelle
3
Ich glaube nicht, dass das Hinzufügen von Hashes eine neue Seite ergibt.
Derek 6 會 功夫
5
Die Seite wird nicht neu geladen.
Derek 6 會 功夫
Sie haben Recht, die Seite wird nicht neu geladen. Ich versuche es in der Konsole mit Chrom und das Favicon wird neu geladen.
Jonathan Vukovich-Tribouharet
In der neuesten Version von Firefox scheinen Hash-Änderungen ein erneutes Laden von iFrames (im src-Attribut) zu erzwingen. Ich würde dies als Browser-Fehler betrachten, aber etwas, das man beachten sollte.
Beejor
1

Ich habe eine Schaltfläche für eine Eingabeaufforderung, die beim Klicken den Anzeigedialog öffnet. Dann kann ich schreiben, was ich suchen möchte, und es wird an dieser Stelle auf der Seite angezeigt. Es verwendet Javascript, um den Header zu beantworten.

In der HTML-Datei habe ich:

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

Auf der .js-Datei habe ich

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

Wenn ich test100 in die Eingabeaufforderung schreibe , wird es an die Stelle verschoben, an der ich span id = "test100" in die HTML-Datei eingefügt habe.

Ich benutze Google Chrome.

Hinweis: Diese Idee stammt aus dem Verknüpfen auf derselben Seite mit

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

was beim Klicken an den Anker gesendet wird. Damit es mehrmals funktioniert, muss die Seite aus Erfahrung neu geladen werden.

Dank an die Leute bei stackoverflow (und möglicherweise auch an stackexchange) kann ich mich nicht erinnern, wie ich all die Kleinigkeiten gesammelt habe. ☺

S.Doe_Dude
quelle