anchor jumping za pomocą javascript


130

Mam pytanie, które będzie się pojawiać bardzo często. Problem w tym, że nigdzie nie można znaleźć jednoznacznego rozwiązania.

Mam dwa problemy dotyczące kotwic.

Głównym celem powinno być uzyskanie ładnego, czystego adresu URL bez żadnych skrótów podczas korzystania z kotwic do przeskakiwania strony.

Zatem struktura kotwic jest następująca:

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

OK, jeśli klikniesz jeden z linków, na który zostanie automatycznie zmieniony adres URL

www.domena.com/page#1

Na koniec powinno to być po prostu:

www.domena.com/page

Na razie w porządku. Po drugie, kiedy przeszukasz Internet w poszukiwaniu tego problemu, znajdziesz javascriptrozwiązanie.

Znalazłem tę funkcję:

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

i wywołując tę ​​funkcję za pomocą:

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

co będzie takie samo jak wcześniej. Doda hash do adresu URL. Dodałem też

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

bezskutecznie. Więc jeśli jest ktoś, kto mógłby mi powiedzieć, jak to rozwiązać, byłbym wdzięczny.

Wielkie dzięki.


Nie jestem pewien, ale możesz spróbować ręcznie zapisać właściwość hash po skoku. Na przykład ustaw limit czasu w programie obsługi onclick, który ustawia window.location.hash=''.
Jeff,

Czy to znaczy, że nie chcesz, aby znak # był wyświetlany w adresie URL podczas przechodzenia do innej sekcji na tej samej stronie internetowej?
Roger Ng

2
W takim przypadku będziesz musiał albo manipulować scrollTopem okna, zwykle przez window.scrollTolub odpowiedniego pomocnika jQuery: stackoverflow.com/questions/6677035/jquery-scroll-to-element lub stackoverflow.com/questions/500336/ ...
Frank van Puffelen

@Jeff - Jeśli to zrobisz location.hash='', #pozostanie tam.
Derek 朕 會 功夫

1
Nie rób tego, proszę. Hashe są dobre podczas zapisywania strony w zakładkach.
Marco Sulla

Odpowiedzi:


209

Możesz uzyskać współrzędne elementu docelowego i ustawić na niego pozycję przewijania. Ale to jest takie skomplikowane.

Oto bardziej leniwy sposób na zrobienie tego:

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

Służy replaceStatedo manipulowania adresem URL. Jeśli chcesz również obsługiwać IE , będziesz musiał to zrobić w skomplikowany sposób :

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/
Kolejny z przejściem: http://jsfiddle.net/DerekL/x3edvp4t/

Możesz również użyć .scrollIntoView:

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

(Cóż, skłamałem. To wcale nie jest skomplikowane.)


1
Szczury !! Link jest uszkodzony :-( Myślałem, że JS Fiddles został tam na zawsze
Mawg mówi, że przywróć Monikę

1
@Mawg Najwyraźniej usunęli możliwość dodawania /showna końcu adresu URL.
Derek 朕 會 功夫

12
„Nawet IE6 to obsługuje” to najlepszy komentarz, jaki kiedykolwiek widziałem.
Josh,

3
@Black Nie ma czegoś takiego jak element „jQuery”. Jeśli chcesz uzyskać pierwszy element z zapytania, zrób $(mySelector)[0].scrollIntoView().
Derek 朕 會 功夫

4
1+ za scrollIntoView. 1- za wspomnienie o tym na końcu.
Yay295

13

Myślę, że jest to znacznie prostsze rozwiązanie:

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

Ta metoda nie powoduje ponownego załadowania witryny sieci Web i ustawia fokus na zakotwiczeniach, które są potrzebne dla czytnika ekranu.


A co rzadko działa na IE, działa to na wszystkich IE;)
Adam111p

5
Skończyło się nawindow.location = window.location.origin + window.location.pathname + '#hash';
Alex

To dla mnie przeładowało stronę. Zaakceptowana odpowiedź jednak działała, chciałbym, żeby była krótsza.
HoldOffHunger

3

Za mało przedstawiciela na komentarz.

Metoda getElementById()oparta na wybranej odpowiedzi nie zadziała, jeśli kotwica została ustawiona, nameale nie została idustawiona (co nie jest zalecane, ale zdarza się w środowisku naturalnym).

Coś, o czym należy pamiętać, jeśli nie masz kontroli nad znacznikami dokumentu (np. Rozszerzenie internetowe).

locationMetoda oparta na wybranej odpowiedź może być uproszczone location.replace:

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

1

Ponieważ kiedy to robisz

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

Załadujesz nową stronę, możesz zrobić:

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

3
Nie sądzę, aby dodanie skrótów spowodowało, że stała się nową stroną.
Derek 朕 會 功夫

5
Nie ładuje ponownie strony.
Derek 朕 會 功夫

Masz rację, nie ładuje ponownie strony. Próbuję w konsoli z chrome i favicon jest przeładowywany.
Jonathan Vukovich-Tribouharet

W najnowszym Firefoksie wydaje się, że zmiany hash wymuszają ponowne załadowanie elementów iFrame (w atrybucie src). Uważam to za błąd przeglądarki, ale coś, o czym należy pamiętać.
Beejor

1

Mam przycisk z monitem, który po kliknięciu otwiera okno dialogowe, a następnie mogę napisać, co chcę wyszukać, i przechodzi do tego miejsca na stronie. Używa javascript, aby odpowiedzieć na nagłówek.

W pliku .html mam:

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

W pliku .js, który mam

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

Kiedy napiszę test100 w monicie, przejdzie do miejsca, w którym umieściłem span id = "test100" w pliku html.

Używam Google Chrome.

Uwaga: ten pomysł pochodzi z linków na tej samej stronie przy użyciu

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

który po kliknięciu wyśle ​​do kotwicy. Aby to działało wiele razy, z doświadczenia trzeba przeładować stronę.

Podziękowania dla ludzi z stackoverflow (i prawdopodobnie również stackexchange) nie pamiętają, jak zebrałem wszystkie bity i elementy. ☺

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.