Jak usunąć skrót z window.location (URL) z JavaScript bez odświeżania strony?


332

Mam adres URL typu: http://example.com#somethingjak usunąć #something, nie powodując odświeżenia strony?

Próbowałem następującego rozwiązania:

window.location.hash = '';

Nie usuwa to jednak symbolu skrótu #z adresu URL.


3
Czy naprawdę chcesz to zrobić? Spowoduje to odświeżenie strony.
seth

9
Czy można obejść się bez odświeżania strony?
Tom Lehman,

1
Jest to możliwe Zajmują się tym biblioteki historyczne AJAX. Ale to nie jest łatwe i należy to zrobić inaczej dla prawie każdej przeglądarki. Nie coś, w co chcesz się dostać.
Gabriel Hurley

Czy są jakieś konsekwencje pozostawienia znaku „#” poza obrazem?
user29660,

Odpowiedzi:


210

Wstępne pytanie:

window.location.href.substr(0, window.location.href.indexOf('#'))

lub

window.location.href.split('#')[0]

oba zwrócą adres URL bez skrótu lub cokolwiek po nim.

W odniesieniu do Twojej edycji:

Każda zmiana window.locationspowoduje wywołanie odświeżenia strony. Możesz zmienić window.location.hashbez uruchamiania odświeżania (chociaż okno przeskoczy, jeśli Twój skrót pasuje do identyfikatora na stronie), ale nie możesz pozbyć się znaku skrótu. Wybierz coś, co jest gorsze ...

NAJBARDZIEJ AKTUALNA ODPOWIEDŹ

Prawidłowa odpowiedź na temat tego, jak to zrobić bez poświęcenia (pełne przeładowanie lub pozostawienie tam znaku skrótu) znajduje się tutaj . Pozostawiając tę ​​odpowiedź tutaj, ponieważ jest oryginalna w 2009 roku, a poprawna, która wykorzystuje nowe interfejsy API przeglądarki została podana 1,5 roku później.


22
Jest to po prostu błędne, możesz zmienić window.location.hash i nie spowoduje to odświeżenia.
Evgeny

61
@Evgeny - Tak mówi moja odpowiedź. Mówię wprost, że zmiana window.location.hash nie spowoduje odświeżenia. „Możesz zmienić window.location.hash bez uruchamiania odświeżania (chociaż okno podskoczy, jeśli twój skrót pasuje do identyfikatora na stronie)”.
Gabriel Hurley

3
Brak przeładowania strony - to jest pytanie. To nie jest odpowiedź, ponieważ wymaga / wymusza przeładowanie strony!
Ed_

10
również uważam, że nie powinien to być ✓answer
abernier

4
To nie jest odpowiedź na pytanie PO.
Bryce

586

Rozwiązanie tego problemu jest obecnie znacznie bardziej dostępne. HTML5 History API pozwala nam manipulować pasek lokalizacji, aby wyświetlić dowolny adres URL w bieżącej domenie.

function removeHash () { 
    history.pushState("", document.title, window.location.pathname
                                                       + window.location.search);
}

Działające demo: http://jsfiddle.net/AndyE/ycmPt/show/

Działa to w Chrome 9, Firefox 4, Safari 5, Opera 11.50 i IE 10. W nieobsługiwanych przeglądarkach zawsze możesz napisać wdzięcznie poniżający skrypt, który korzysta z niego, jeśli jest dostępny:

function removeHash () { 
    var scrollV, scrollH, loc = window.location;
    if ("pushState" in history)
        history.pushState("", document.title, loc.pathname + loc.search);
    else {
        // Prevent scrolling by storing the page's current scroll offset
        scrollV = document.body.scrollTop;
        scrollH = document.body.scrollLeft;

        loc.hash = "";

        // Restore the scroll offset, should be flicker free
        document.body.scrollTop = scrollV;
        document.body.scrollLeft = scrollH;
    }
}

Możesz więc pozbyć się symbolu skrótu, ale nie we wszystkich przeglądarkach - jeszcze.

Uwaga: jeśli chcesz zastąpić bieżącą stronę w historii przeglądarki, użyj replaceState()zamiast pushState().


9
Użyj tej linii, aby upewnić się, że nie stracisz ciągu zapytania: history.pushState ("", document.title, window.location.pathname + window.location.search);
Phil Kulak,

6
@Phil: dziękuję za zwrócenie na to uwagi, odpowiednio zaktualizowałem odpowiedź. Jestem zbyt przyzwyczajony do używania ładnych adresów URL.
Andy E

1
W starszych wersjach IE wydaje się, że musisz użyć document.documentElement zamiast document.body. Zobacz tę odpowiedź stackoverflow.com/a/2717272/359048
jasonmcclurg

29
Sugeruję użycie replaceState zamiast pushState, aby nie tworzyć dodatkowego wpisu w historii przeglądarki.
Nico,

1
@santiagoarizti: masz rację, właśnie doszedłem do tego samego wniosku. Nie sprawdziłem poprawnie kodu, który napisałem (7 lat temu!) I przegapiłem, że przełączałem również stan przycisku podczas usuwania skrótu. Ponieważ zmieniacie skrót ręcznie, przypuszczam, że zawsze możecie samodzielnie wywołać zdarzenie.
Andy E,

85

(Zbyt wiele odpowiedzi jest zbędnych i nieaktualnych). Najlepszym rozwiązaniem jest teraz:

history.replaceState(null, null, ' ');

5
użyj history.pushState(null, null, ' ')zamiast tego, jeśli chcesz zachować historię.
nichijou

9
To może być przydatne, aby wyjaśnić, co przechodząc nulldo statei titleparametrach ostatecznie robi.
V. Rubinetti,

Problem z tym i resztą polega na tym, że nie uruchamia onhashchange, nawet jeśli skrót jest teraz pusty, gdy nie był wcześniej.
Curtis,

1
W TypeScript wartość null jest niedozwolona dla drugiego parametru, ponieważ polecenie pobiera ciąg. Mozilla zaleca pusty ciąg.
Curtis,

41

Prosty i elegancki:

history.replaceState({}, document.title, ".");  // replace / with . to keep url

3
użyj kropki zamiast ukośnika, jeśli chcesz pozostać w tym samym katalogu
vahanpwns

1
Zaktualizuj odpowiedź w odniesieniu do notatki @vahanpwns, aby użyć .zamiast /. Użycie /zmienia adres URL do ścieżki głównej.
Isaac Gregson

5
Dzięki za tę odpowiedź, zmieniłem na history.replaceState({}, document.title, location.href.substr(0, location.href.length-location.hash.length));dla mojego przypadku użycia.
Scott Jungwirth

5
To nie zachowuje zapytania adresu URL.
Vladislav Kostenko

2
Mój przypadek użycia to również zamiana zamiast wypychania, ale to ma dla mnie większy sens:history.replaceState(null, document.title, location.pathname + location.search);
MDMower

16

Aby usunąć skrót, możesz spróbować użyć tej funkcji

function remove_hash_from_url()
{
    var uri = window.location.toString();
    if (uri.indexOf("#") > 0) {
        var clean_uri = uri.substring(0, uri.indexOf("#"));
        window.history.replaceState({}, document.title, clean_uri);
    }
}

13

Spowoduje to również usunięcie końcowego skrótu. np .: http://test.com/123#abc -> http://test.com/123

if(window.history.pushState) {
    window.history.pushState('', '/', window.location.pathname)
} else {
    window.location.hash = '';
}

Usuwa to wszelkie parametry zapytania obecne w adresie URL :(
kevgathuku

1
@kevgathuku możesz dodać je z powrotem za pomocą location.search, np .: `window.history.pushState ('', '/', window.location.pathname + window.location.search)`
Chris Gunawardena

6

Co powiesz na następujące?

window.location.hash=' '

Pamiętaj, że ustawiam skrót w pojedynczej spacji, a nie w pustym ciągu.


Ustawienie skrótu na niepoprawną kotwicę również nie powoduje odświeżenia. Jak na przykład,

window.location.hash='invalidtag'

Ale powyższe rozwiązanie jest mylące. To wydaje się wskazywać, że na danym stanowisku znajduje się kotwica o podanym imieniu, chociaż nie ma takiego. Jednocześnie użycie pustego ciągu powoduje przejście strony na górę, co czasami może być nie do przyjęcia. Korzystanie ze spacji zapewnia również, że za każdym razem, gdy adres URL zostanie skopiowany, dodany do zakładek i ponownie odwiedzony, strona zwykle będzie na górze, a spacja zostanie zignorowana.

I, hej, to moja pierwsza odpowiedź na StackOverflow. Mam nadzieję, że ktoś uzna to za przydatne i zgodne ze standardami społeczności.


7
Ustawienie skrótu na spacje nadal utrzymuje # na końcu adresu URL, myślę, że celem jest całkowite usunięcie go.
mahemoff

1
Śledzi skrót na końcu adresu URL. Pytanie brzmi, jak to usunąć.
Gurmeet Singh,

Tak, w jaki sposób możemy usunąć # za pomocą ciągu mieszającego.
Bhavin Thummar

6

Możesz to zrobić jak poniżej:

history.replaceState({}, document.title, window.location.href.split('#')[0]);


1
W obu przypadkach odpowiedź oznaczona gwiazdką nie zadziałała, ale ta zadziałała. Dzięki!
Dev

5
const url = new URL(window.location);
url.hash = '';
history.replaceState(null, document.title, url);

2
Chociaż ten kod może odpowiedzieć na pytanie, zapewnienie dodatkowego kontekstu dotyczącego tego, dlaczego i / lub jak ten kod odpowiada na pytanie, poprawia jego długoterminową wartość.
rollstuhlfahrer

3
<script type="text/javascript">
var uri = window.location.toString();
if (uri.indexOf("?") > 0) {
    var clean_uri = uri.substring(0, uri.indexOf("?"));
    window.history.replaceState({}, document.title, clean_uri);
}
</script>

umieść ten kod w sekcji nagłówka


3
function removeLocationHash(){
    var noHashURL = window.location.href.replace(/#.*$/, '');
    window.history.replaceState('', document.title, noHashURL) 
}

window.addEventListener("load", function(){
    removeLocationHash();
});

2

Myślę, że byłoby bezpieczniej

if (window.history) {
    window.history.pushState('', document.title, window.location.href.replace(window.location.hash, ''));
} else {
    window.location.hash = '';
}

0

Spróbuj wykonać następujące czynności:

window.history.back(1);

23
To nie odpowiada na pytanie, czy użytkownik podszedł bezpośrednio do adresu URL, w tym skrótu.
nickb.

Ta sztuczka jest bardzo przydatna, gdy chcesz utworzyć link do poprzedniej strony, ale link jest ukryty w wiązce plików js.
ValidfroM

Dokładnie tego szukałem. Działa to doskonale, aby usunąć hashtag właśnie utworzony przez moją aplikację internetową w celu wykorzystania wartości zwracanej przez funkcję javasript.
user278859

0

Oto inne rozwiązanie, aby zmienić lokalizację za pomocą href i wyczyścić skrót bez przewijania.

Magiczne rozwiązanie wyjaśniono tutaj . Specyfikacje tutaj .

const hash = window.location.hash;
history.scrollRestoration = 'manual';
window.location.href = hash;    
history.pushState('', document.title, window.location.pathname);

UWAGA: Proponowany interfejs API jest teraz częścią WhatWG HTML Living Standard


0
  $(window).on('hashchange', function (e) {
        history.replaceState("", document.title, e.originalEvent.oldURL);
    });

-1

Możesz zastąpić hash wartością null

var urlWithoutHash = document.location.href.replace(location.hash , "" );

1
Pytanie brzmi „bez powodowania odświeżenia strony”, ale ta metoda powoduje odświeżenie strony. Powinieneś zwrócić uwagę na ten fakt w swojej odpowiedzi, więc nie wszyscy musimy marnować czas na dowiadywanie się z pierwszej ręki, że odpowiadasz na inne pytanie niż to, na które tak naprawdę staramy się tutaj uzyskać odpowiedź.
Vladimir Kornea

Nie odświeża strony.
Ciprian
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.