Как удалить хеш из window.location (URL) с помощью JavaScript без обновления страницы?


332

У меня есть URL-адрес, как:, http://example.com#somethingкак удалить #something, не вызывая обновления страницы?

Я попытался следующее решение:

window.location.hash = '';

Однако это не удаляет символ хеша #из URL.


3
Вы действительно хотите это сделать? Это приведет к обновлению страницы.
Seth

9
Можно ли обойтись без обновления страницы?
Том Леман

1
Это является возможным. Библиотеки истории AJAX имеют дело с этим. Но это не легко, и это должно быть сделано по-разному почти для каждого браузера. Не то, во что ты хочешь попасть.
Габриэль Херли

Есть ли какие-либо соображения о том, чтобы оставить «#» позади, кроме визуального?
user29660

Ответы:


211

Начальный вопрос:

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
@ Евгений - это то, что говорит мой ответ. Я прямо говорю, что изменение window.location.hash не приведет к обновлению. Msgstr "Вы можете изменить window.location.hash, не вызывая обновления (хотя окно будет отображаться, если ваш хеш совпадает с идентификатором на странице)".
Габриэль Херли

3
Нет перезагрузки страницы - вот в чем вопрос. Это не ответ, так как требует / заставляет перезагрузить страницу!
Ed_

10
также думаю, что это не должно быть ✓answer
abernier

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
Я предлагаю использовать replaceState вместо pushState, чтобы не создавать дополнительную запись в истории браузера.
Нико

1
@santiagoarizti: вы правы, я просто пришел к такому же выводу. Я не проверял код, который написал (7 лет назад!) Должным образом, и пропустил, что я также переключал состояние кнопки при удалении хэша. Так как вы меняете хеш вручную, вы, наверное, всегда можете инициировать событие самостоятельно.
Энди Э

86

(Слишком много ответов излишни и устарели.) Лучшее решение сейчас таково:

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

5
используйте history.pushState(null, null, ' ')вместо этого, если вы хотите сохранить историю.
nichijou

9
Это может быть полезно , чтобы объяснить , что прохождение nullдля stateи titleпараметров , в конечном счете делает.
В. Рубинетти

Проблема с этим и остальным заключается в том, что он не вызывает переключение между хэшами, даже если хеш теперь пуст, чем раньше.
Кертис

1
В TypeScript значение null не разрешено для второго параметра, поскольку команда принимает строку. Mozilla рекомендует пустую строку.
Кертис

41

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

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

3
используйте точку вместо косой черты, если вы хотите остаться в том же каталоге
vahanpwns

1
Пожалуйста, обновите ответ относительно примечания @vahanpwns, чтобы использовать .вместо /. Использование /изменения URL-адреса для корневого пути.
Исаак Грегсон

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

5
Это не сохраняет URL-запрос.
Владислав Костенко

2
Мой вариант использования также должен был заменить вместо push, но для меня это имеет больше смысла: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. Вопрос в том, как это убрать.
Гурмит Сингх

Да, как мы можем удалить # с помощью хеш-строки.
Бхавин Туммар

6

Вы можете сделать это, как показано ниже:

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


1
Ответ, помеченный звездочкой, не работал для меня ни в одном случае, но этот работал. Спасибо!
Dev

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

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.


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

-1

Вы можете заменить хеш нулевым

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

1
Вопрос спрашивает «не вызывая обновление страницы», но этот метод обновляет страницу. Вы должны отметить этот факт в своем ответе, поэтому нам не нужно тратить свое время на то, чтобы воочию узнать, что вы отвечаете на вопрос, отличный от того, на который мы на самом деле пытаемся получить ответ.
Владимир Корнеа

Это не обновляет страницу.
Ciprian
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.