Mamy kilka stron korzystających z technologii AJAX do wczytywania zawartości i jest kilka sytuacji, w których potrzebujemy głębokiego linku do strony. Zamiast mieć link do „Użytkownicy” i mówić ludziom, aby kliknęli „ustawienia”, warto mieć możliwość powiązania ludzi z user.aspx # settings
Aby umożliwić ludziom dostarczanie nam poprawnych linków do sekcji (w celu uzyskania pomocy technicznej itp.), Skonfigurowałem automatyczne modyfikowanie skrótu w adresie URL po każdym kliknięciu przycisku. Jedynym problemem jest oczywiście to, że kiedy tak się dzieje, przewija się również stronę do tego elementu.
Czy jest sposób, aby to wyłączyć? Poniżej znajduje się, jak dotychczas to robię.
$(function(){
//This emulates a click on the correct button on page load
if(document.location.hash){
$("#buttons li a").removeClass('selected');
s=$(document.location.hash).addClass('selected').attr("href").replace("javascript:","");
eval(s);
}
//Click a button to change the hash
$("#buttons li a").click(function(){
$("#buttons li a").removeClass('selected');
$(this).addClass('selected');
document.location.hash=$(this).attr("id")
//return false;
});
});
Miałem nadzieję, return false;
że zatrzyma przewijanie strony - ale to po prostu sprawia, że link w ogóle nie działa. Więc to na razie tylko zakomentowane, abym mógł nawigować.
Jakieś pomysły?
Użyj
history.replaceState
lubhistory.pushState
*, aby zmienić skrót. Nie spowoduje to przejścia do skojarzonego elementu.Przykład
Demo na JSFiddle
* Jeśli chcesz obsługiwać historię do przodu i do tyłu
Zachowanie historyczne
Jeśli używasz
history.pushState
i nie chcesz przewijać strony, gdy użytkownik korzysta z przycisków historii przeglądarki (do przodu / do tyłu), sprawdźscrollRestoration
ustawienie eksperymentalne (tylko Chrome 46+) .Wsparcie przeglądarki
źródło
replaceState
jest prawdopodobnie lepszym sposobem, aby się tu dostać. Różnica polega na tym, żepushState
dodaje element do historii, areplaceState
nie.body
co się przewija, czasami jest todocumentElement
. Zobacz tę istotę Diego PeriniMyślę, że mogłem znaleźć dość proste rozwiązanie. Problem polega na tym, że hash w adresie URL jest również elementem na stronie, do której zostanie przewinięty. jeśli po prostu dodam jakiś tekst do skrótu, teraz nie będzie on już odnosił się do istniejącego elementu!
Teraz adres URL wygląda tak, jakby
page.aspx#btn_elementID
nie był prawdziwym identyfikatorem na stronie. Po prostu usuwam „btn_” i otrzymuję rzeczywisty identyfikator elementuźródło
/
wydaje się logiczne.Fragment oryginalnego kodu:
Zmień to na:
źródło
hash
właściwości spowoduje przewijanie strony i tak.Niedawno
window.location.hash
budowałem karuzelę, która opiera się na utrzymywaniu stanu, i odkryłem, że przeglądarki Chrome i webkit wymuszą przewijanie (nawet do niewidocznego celu) z niezręcznym szarpnięciem, gdywindow.onhashchange
zdarzenie zostanie uruchomione .Nawet próba zarejestrowania programu obsługi, który zatrzymuje propagację:
Nie zrobił nic, aby zatrzymać domyślne zachowanie przeglądarki. Rozwiązanie, które znalazłem, służyło
window.history.pushState
do zmiany skrótu bez wywoływania niepożądanych skutków ubocznych.Następnie możesz nasłuchiwać zarówno normalnego zdarzenia hashchange, jak i
my.hashchange
:źródło
my.hashchange
to tylko przykładowa nazwa wydarzeniaOkej, to dość stary temat, ale pomyślałem, że mogę się do niego włączyć, ponieważ „poprawna” odpowiedź nie działa dobrze z CSS.
To rozwiązanie w zasadzie zapobiega przesunięciu strony przez zdarzenie click, dzięki czemu możemy najpierw uzyskać pozycję przewijania. Następnie ręcznie dodajemy hash, a przeglądarka automatycznie wyzwala zdarzenie hashchange . Przechwytujemy zdarzenie hashchange i przewijamy z powrotem do właściwej pozycji. Wywołanie zwrotne oddziela i zapobiega opóźnieniu kodu przez trzymanie hakowania w jednym miejscu.
źródło
Erm, mam nieco prymitywną, ale zdecydowanie działającą metodę.
Po prostu zapisz bieżącą pozycję przewijania w zmiennej tymczasowej, a następnie zresetuj ją po zmianie hasha. :)
Więc dla oryginalnego przykładu:
źródło
Nie sądzę, żeby to było możliwe. O ile wiem, jedyną sytuacją, w której przeglądarka nie przewija do zmiany,
document.location.hash
jest brak hasha na stronie.Ten artykuł nie jest bezpośrednio związany z Twoim pytaniem, ale omawia typowe zmiany zachowań przeglądarek
document.location.hash
źródło
jeśli używasz zdarzenia hashchange z parserem hash, możesz zapobiec domyślnej akcji na linkach i zmienić lokalizację. hash dodawanie jednego znaku, aby mieć różnicę z właściwością id elementu
źródło
Dodaję to tutaj, ponieważ wszystkie bardziej trafne pytania zostały oznaczone jako duplikaty wskazujące tutaj…
Moja sytuacja jest prostsza:
a[href='#something']
)e.preventDefault()
$("html,body").stop(true,true).animate({ "scrollTop": linkoffset.top }, scrollspeed, "swing" );
window.location = link;
W ten sposób następuje przewijanie i nie ma przeskoku, gdy lokalizacja jest aktualizowana.
źródło
Innym sposobem na zrobienie tego jest dodanie elementu div, który jest ukryty w górnej części widoku. Ten element div jest następnie przypisywany do identyfikatora skrótu przed dodaniem go do adresu URL ... więc nie otrzymasz przewijania.
źródło
Oto moje rozwiązanie dla kart z włączoną historią:
I aby pokazać ostatnio wybraną zakładkę:
Zwróć uwagę
*=
nafilter
rozmowę. Jest to rzecz specyficzna dla jQuery i bez niej karty z włączoną historią zawiodą.źródło
To rozwiązanie tworzy element div w rzeczywistym scrollTop i usuwa go po zmianie hasha:
opcjonalne, wyzwalające zdarzenie zakotwiczenia przy wczytywaniu strony:
źródło
Mam prostszą metodę, która działa dla mnie. Zasadniczo pamiętaj, czym właściwie jest hash w HTML. To link do zakotwiczenia tagu nazwy. Dlatego się przewija ... przeglądarka próbuje przewinąć do linku zakotwiczenia. Więc daj mu jeden!
Nazwij elementy div sekcji za pomocą klas zamiast identyfikatorów.
W kodzie przetwarzania usuń znak krzyżyka i zastąp kropką:
Na koniec usuń element.preventDefault lub return: false i pozwól na uruchomienie nawigacji. Okno pozostanie na górze, skrót zostanie dołączony do adresu URL paska adresu i otworzy się właściwy panel.
źródło
Myślę, że musisz zresetować przewijanie do jego pozycji przed zmianą hash.
źródło
Jeśli na swojej stronie używasz identyfikatora jako pewnego rodzaju punktu zakotwiczenia i masz scenariusze, w których chcesz, aby użytkownicy dopisywali # coś na końcu adresu URL i przewijali stronę do tej sekcji # coś, używając własnej zdefiniowanej animacji funkcja javascript, detektor zdarzeń zmiany skrótu nie będzie w stanie tego zrobić.
Jeśli po prostu umieścisz debugger bezpośrednio po zdarzeniu hashchange, na przykład coś takiego (cóż, używam jquery, ale rozumiesz):
Zauważysz, że jak tylko zmienisz adres URL i naciśniesz przycisk Enter, strona natychmiast zatrzyma się w odpowiedniej sekcji, dopiero potem uruchomiona zostanie Twoja własna zdefiniowana funkcja przewijania i przewija się do tej sekcji, która wygląda bardzo źle.
Moja sugestia to:
nie używaj id jako punktu zakotwiczenia do sekcji, do której chcesz przewinąć.
Jeśli musisz użyć ID, tak jak ja. Zamiast tego użyj detektora zdarzeń „popstate”, nie będzie on automatycznie przewijał do tej samej sekcji, którą dołączasz do adresu URL, zamiast tego możesz wywołać własną zdefiniowaną funkcję wewnątrz zdarzenia popstate.
$(window).on('popstate', function(){myscrollfunction()});
Na koniec musisz zrobić małą sztuczkę we własnej zdefiniowanej funkcji przewijania:
usuń identyfikator ze swojego tagu i zresetuj go.
To powinno załatwić sprawę.
źródło
Dodaj ten kod do jQuery tylko wtedy, gdy dokument jest gotowy
Ref: http://css-tricks.com/snippets/jquery/smooth-scrolling/
źródło