Как обнаружить изменение URL в JavaScript
Как я могу проверить, если URL-адрес изменился в JavaScript? Например, такие веб-сайты, как GitHub, которые используют AJAX, будут добавлять информацию о странице после символа # для создания уникального URL-адреса без перезагрузки страницы. Каков наилучший способ определить, изменяется ли этот URL-адрес?
- - это
onload
событие называется? - есть ли обработчик событий для URL?
- или URL должен проверяться каждую секунду, чтобы обнаружить изменение?
12 ответов:
в современных браузерах (IE8+, FF3. 6+, Chrome), вы можете просто слушать
hashchange
событиеwindow
.В некоторых старых браузерах, вам нужен таймер, который постоянно проверяет
location.hash
. Если вы используете jQuery, есть плагин что делает именно это.
С помощью jquery (и плагина) вы можете сделать
$(window).bind('hashchange', function() { /* things */ });
http://benalman.com/projects/jquery-hashchange-plugin/
в противном случае да, вам придется использовать setInterval и проверить наличие изменений в хэш-событии (окно.местоположение.хэш)
обновление! Простой проект
function hashHandler(){ this.oldHash = window.location.hash; this.Check; var that = this; var detect = function(){ if(that.oldHash!=window.location.hash){ alert("HASH CHANGED - new has" + window.location.hash); that.oldHash = window.location.hash; } }; this.Check = setInterval(function(){ detect() }, 100); } var hashDetection = new hashHandler();
используйте этот код
window.onhashchange = function() { //code }
С помощью jQuery
$(window).bind('hashchange', function() { //code });
редактировать после небольшого исследования:
это как-то кажется, что я был обманут документацией, присутствующей на Mozilla docs. Элемент
popstate
событие (и его функция обратного вызоваonpopstate
) составляют не запускается, когдаpushState()
илиreplaceState()
вызываются в коде. Поэтому оригинальный ответ применяется не во всех случаях.однако есть способ обойти это обезьяна-исправлять функции согласно @alpha123:
var pushState = history.pushState; history.pushState = function () { pushState.apply(history, arguments); fireEvents('pushState', arguments); // Some event-handling function };
оригинальный ответ
учитывая, что название этого вопроса "как обнаружить изменение URL" ответ, когда вы хотите знать, когда полный путь изменяется (а не только хэш-якорь), заключается в том, что вы можете слушать
popstate
событие:window.onpopstate = function(event) { console.log("location: " + document.location + ", state: " + JSON.stringify(event.state)); };
ссылка на popstate в Mozilla Docs
в настоящее время (январь 2017) есть поддержка popstate от 92% браузеров по всему миру.
добавить прослушиватель событий изменения хэша!
window.addEventListener('hashchange', function(e){console.log('hash changed')});
или, чтобы прослушать все изменения URL:
window.addEventListener('popstate', function(e){console.log('url changed')});
Это лучше, чем что-то вроде ниже код, потому что только одна вещь может существовать в окно.onhashchange и вы, возможно, будете перезаписывать чужой код.
// Bad code example window.onhashchange = function() { // Code that overwrites whatever was previously in window.onhashchange }
это решение работает для меня:
var oldURL = ""; var currentURL = window.location.href; function checkURLchange(currentURL){ if(currentURL != oldURL){ alert("url changed!"); oldURL = currentURL; } oldURL = window.location.href; setInterval(function() { checkURLchange(window.location.href); }, 1000); } checkURLchange();
хотя старый вопрос, на Location-bar проект очень полезен.
var LocationBar = require("location-bar"); var locationBar = new LocationBar(); // listen to all changes to the location bar locationBar.onChange(function (path) { console.log("the current url is", path); }); // listen to a specific change to location bar // e.g. Backbone builds on top of this method to implement // it's simple parametrized Backbone.Router locationBar.route(/some\-regex/, function () { // only called when the current url matches the regex }); locationBar.start({ pushState: true }); // update the address bar and add a new entry in browsers history locationBar.update("/some/url?param=123"); // update the address bar but don't add the entry in history locationBar.update("/some/url", {replace: true}); // update the address bar and call the `change` callback locationBar.update("/some/url", {trigger: true});
чтобы прослушать изменения url, см. ниже:
window.onpopstate = function(event) { console.log("location: " + document.location + ", state: " + JSON.stringify(event.state)); };
используйте этот стиль, если вы собираетесь остановить/удалить прослушиватель после некоторого определенного условия.
window.addEventListener('popstate', function(e) { console.log('url changed') });
посмотрите на функцию выгрузки jQuery. Он справляется со всеми вещами.
https://api.jquery.com/unload/
выгрузка событие отправляется в элемент окна, когда пользователь переходит от страницы. Это может означать одну из многих вещей. Пользователь мог нажать на ссылку, чтобы покинуть страницу, или ввести новый URL-адрес в адресной строке. Кнопки вперед и назад вызовут событие. Закрытие окна браузера приведет к тому, что событие будет вызванный. Даже перезагрузка страницы сначала создаст событие выгрузки.
$(window).unload( function(event) { alert("navigating"); } );
вы начинаете новый
setInterval
при каждом вызове, не отменяя предыдущий - вероятно, вы только хотели иметьsetTimeout
делая небольшое расширение chrome, я столкнулся с той же проблемой с дополнительной проблемой : иногда меняется страница, но не URL.
например, просто перейдите на главную страницу Facebook и нажмите кнопку "Домой". Вы перезагрузите страницу, но URL-адрес не изменится (стиль одностраничного приложения).
99% времени мы разрабатываем веб-сайты, чтобы мы могли получать эти события из таких фреймворков, как Angular, React, Vue так далее..
но, в моем случае расширения Chrome (в Vanilla JS) мне пришлось слушать событие, которое будет запускаться для каждого "изменения страницы", которое обычно может быть поймано по URL-адресу, но иногда это не так.
мое домашнее решение было следующим:
listen(window.history.length); var oldLength = -1; function listen(currentLength) { if (currentLength != oldLength) { // Do your stuff here } oldLength = window.history.length; setInterval(function () { listen(window.history.length); }, 1000); }
таким образом, в основном решение leoneckert, примененное к истории окон, которое изменится при изменении страницы в одном приложении страницы.
не ракетостроение, но чистый решение я нашел, учитывая, что мы проверяем здесь только целочисленное равенство, а не большие объекты или весь DOM.