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.

Tom Lehman
źródło
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.

Gabriel Hurley
źródło
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().

Andy E.
źródło
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, ' ');
Pacerier
źródło
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
cprcrack
źródło
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);
    }
}
Rahul Gupta
źródło
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 = '';
}
Chris Gunawardena
źródło
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.

Nibras Reeza
źródło
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]);

METALHEAD
źródło
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);
Casey
źródło
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

Manigandan Raamanathan
źródło
3
function removeLocationHash(){
    var noHashURL = window.location.href.replace(/#.*$/, '');
    window.history.replaceState('', document.title, noHashURL) 
}

window.addEventListener("load", function(){
    removeLocationHash();
});
Vimal Kumar
źródło
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 = '';
}
Konstantin Lekh
źródło
0

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

window.history.back(1);
Vishal Sharma
źródło
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

Voscausa
źródło
0
  $(window).on('hashchange', function (e) {
        history.replaceState("", document.title, e.originalEvent.oldURL);
    });
JohnMathew
źródło
-1

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

var urlWithoutHash = document.location.href.replace(location.hash , "" );
Devang Bhagdev
źródło
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