Як видалити хеш з window.location (URL) за допомогою JavaScript без оновлення сторінки?


332

У мене є така URL-адреса: http://example.com#somethingяк видалити #something, не викликаючи оновлення сторінки?

Я спробував таке рішення:

window.location.hash = '';

Однак це не видаляє хеш-символ #із URL-адреси.


3
Ви справді хочете це зробити? Це призведе до оновлення сторінки.
Seth

9
Чи можна обійтися без оновлення сторінки?
Том Леман

1
Це є можливим. Бібліотеки історії AJAX займаються цим. Але це непросто, і це потрібно робити по-різному майже для кожного браузера. Не те, в що ти хочеш потрапляти.
Габріель Херлі

Чи є якісь міркування щодо того, щоб залишити "#" поза візуальним?
користувач29660

Відповіді:


210

Початкове запитання:

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

або

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

обидва повернуть URL-адресу без хешу чи нічого після нього.

Що стосується вашої редакції:

Будь-яка зміна window.locationпризведе до оновлення сторінки. Ви можете змінити, window.location.hashне запускаючи оновлення (хоча вікно перескочить, якщо ваш хеш відповідає ідентифікатору на сторінці), але ви не можете позбутися знаку хешу. Виберіть свій вибір, який гірший ...

НАЙБІЛЬШИЙ ДОГОВІР ВІДПОВІДЬ

Правильна відповідь про те, як це зробити, не жертвуючи (або повним перезавантаженням, або залишаючи хеш-знак там), знаходиться тут . Залишаючи цю відповідь тут, хоча щодо оригіналу у 2009 році, тоді як правильний, що використовує нові API браузера, був наданий 1,5 року пізніше.


22
Це просто неправильно, ви можете змінити window.location.hash, і оновлення не спричинить оновлення.
Євген

61
@Evgeny - ось що говорить моя відповідь. Я чітко кажу, що зміна window.location.hash не спровокує оновлення. "Ви можете змінити window.location.hash, не запускаючи оновлення (хоча вікно скаче, якщо ваш хеш відповідає ідентифікатору на сторінці)".
Габріель Херлі

3
Немає перезавантаження сторінок - це питання. Це не відповідь, оскільки це вимагає / змушує перезавантажувати сторінку!
Ed_

10
також думають, що це не повинно бути ✓answer
аберньє

4
Це не відповідь на питання ОП.
Брайс

586

Вирішення цієї проблеми сьогодні набагато доступніше. HTML5 History API дозволяє маніпулювати адресний рядок для відображення будь-якого URL в межах поточного домену.

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

Робоча демонстрація: http://jsfiddle.net/AndyE/ycmPt/show/

Це працює в Chrome 9, Firefox 4, Safari 5, Opera 11.50 та IE 10. Для непідтримуваних веб-переглядачів ви завжди можете написати скрипт, що принижує приниження, який використовує його, коли це можливо:

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

Таким чином, ви можете позбутися хеш-символу, тільки не у всіх браузерах - поки.

Примітка. Якщо ви хочете замінити поточну сторінку в історії браузера, використовуйте replaceState()замість pushState().


9
Використовуйте цей рядок, щоб не втратити рядок запиту: history.pushState ("", document.title, window.location.pathname + window.location.search);
Філ Кулак

6
@Phil: дякую, що вказав на це, я відповідним чином оновив відповідь. Я занадто звик використовувати гарні URL-адреси.
Енді Е

1
Для старих версій IE, здається, вам потрібно використовувати document.documentElement замість document.body. Дивіться цей відповідь stackoverflow.com/a/2717272/359048
jasonmcclurg

29
Я пропоную використовувати замість pushState замість pushState, щоб не створювати додаткових записів в історії браузера.
Ніко

1
@santiagoarizti: ти маєш рацію, я просто прийшов до такого ж висновку. Я не перевірив належним чином код, який я написав (7 років тому!), І пропустив, що я також перемикав стан кнопки під час видалення хеша. Оскільки ви змінюєте хеш вручну, ви, мабуть, завжди можете самі викликати подію.
Енді Е

85

(Занадто багато відповідей є зайвими та застарілими.) Найкращим рішенням зараз є таке:

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

5
використовуйте history.pushState(null, null, ' ')натомість, якщо ви хочете зберегти історію.
nichijou

9
Це може бути корисно , щоб пояснити , що проходження nullдля stateі titleпараметрів , в кінцевому рахунку робить.
В.

Проблема в цьому і в іншому полягає в тому, що він не запускає onhashchange, хоча хеш тепер порожній, коли його не було раніше.
Кертіс

1
У TypeScript null заборонено для другого параметра, оскільки команда займає рядок. Mozilla рекомендує порожній рядок.
Кертіс

41

Простий і елегантний:

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

3
використовуйте крапку замість косої риси, якщо ви хочете залишитися в одному каталозі
vahanpwns

1
Будь ласка, оновіть відповідь стосовно @vahanpwns note, щоб використовувати .замість /. Використовуючи /зміни URL-адреси до кореневого шляху.
Ісаак Грегсон

5
Дякую за цю відповідь, я змінив history.replaceState({}, document.title, location.href.substr(0, location.href.length-location.hash.length));для мого випадку використання.
Скотт Юнгвірт

5
Це не зберігає URL-запит.
Владислав Костенко

2
Мій приклад використання також був замінити замість натискання, але це має більше сенсу для мене:history.replaceState(null, document.title, location.pathname + location.search);
MDMower

16

Щоб видалити хеш, ви можете спробувати скористатися цією функцією

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

Це також видалить хеш-трейлінг. наприклад: http://test.com/123#abc -> http://test.com/123

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

Це видаляє будь-які параметри запитів, наявні в URL :(
kevgathuku

1
@kevgathuku ви можете додати їх назад з location.search, наприклад: `window.history.pushState ('', '/', window.location.pathname + window.location.search)`
Кріс Гунавардена

6

Як щодо наступного?

window.location.hash=' '

Зауважте, що я встановлюю хеш на один пробіл, а не на порожню рядок.


Установлення хеша на недійсний якір також не викликає оновлення. Як от,

window.location.hash='invalidtag'

Але, я вважаю, що вищезгадане рішення є оманливим. Це, мабуть, вказує на те, що на даній позиції з даним іменем є якір, хоча його немає. У той же час, використовуючи порожній рядок, змушує сторінку переміщуватися до верхньої частини, що може бути неприйнятним часом. Використання пробілу також забезпечує те, що всякий раз, коли URL-адреса буде скопійовано та закладено в закладки та переглянуто знову, сторінка зазвичай буде вгорі, а пробіл буде проігноровано.

І, ей, це моя перша відповідь на StackOverflow. Сподіваюся, хтось вважає це корисним, і це відповідає стандартам громади.


7
Налаштування хешу для пробілів все ще зберігає # в кінці URL-адреси, я думаю, що мета - його повністю видалити.
mahemoff

1
Він відслідковує хеш у кінці URL-адреси. Питання в тому, як це зняти.
Gurmeet Singh

Так, як ми можемо видалити # також з хеш-рядком.
Bhavin Thummar

6

Ви можете зробити це як нижче:

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


1
Зірка відповіді не працювала для мене в жодному випадку, але ця все-таки була. Дякую!
Дев

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

2
Хоча цей код може відповісти на питання, надаючи додатковий контекст щодо того, чому та / або як цей код відповідає на питання, покращує його довгострокове значення.
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>

покладіть цей код на головний розділ


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

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

2

Я думаю, це було б безпечніше

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

0

Спробуйте наступне:

window.history.back(1);

23
Це не відповідає на запитання, якщо користувач перейшов безпосередньо до URL-адреси, включаючи хеш.
нік

Цей трюк дуже корисний, коли ви просто хочете створити посилання на попередню сторінку, але посилання приховано у купі js-файлів.
ValidfroM

Саме те, що я шукав. Це прекрасно працює, щоб видалити хештег, щойно створений моїм веб-додатком, щоб споживати значення, повернене функцією javasript.
користувач278859

0

Ось ще одне рішення змінити розташування за допомогою href та очистити хеш без прокрутки.

Магічне рішення пояснюється тут . Опис тут .

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

ПРИМІТКА. Пропонований API тепер є частиною WhatWG HTML Living Standard


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

-1

Ви можете замінити хеш на null

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

1
Питання задається "не змушуючи оновити сторінку", але цей метод не оновлює сторінку. Ви повинні зауважити цей факт у своїй відповіді, тому нам не доведеться витрачати час на те, щоб дізнатись з перших вуст, що ви відповідаєте на інше питання, ніж на те, на що насправді намагаються отримати відповідь.
Володимир Корнея

Це не оновлює сторінку.
Ciprian
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.