В одностраничном приложении, как элегантно отслеживать изменения URL-адреса

React.js

Принцип   Одностраничного приложения основан на смене хэша url ранним утром, на ререндеринг страницы при условии отсутствия обновления по изменению истории H5. Итак, как отслеживать изменения URL-адресов в одностраничных приложениях?

  • Принцип одностраничного приложения
  • Слушайте изменения хэша в URL
  • Слушайте события, которые изменяют URL-адрес в истории
  • Мониторинг поведения replaceState и pushState

Оригинальный текст в моем блоге:GitHub.com/fort и все…

приветственная звезда

Во-первых, принцип одностраничного приложения

   Принципы одностраничных приложений в нашей последней статье.Чтение исходного кода React-RouterЭто было описано очень подробно, так что вот краткое введение. Одностраничные приложения позволяют повторно отображать страницу без обновления. URL-адрес можно изменить с помощью хэша или истории в объекте html5 Bom, но страница не обновляется.

(1) Реализация одностраничной маршрутизации с помощью хеширования

   Ранняя внешняя маршрутизация была реализована с помощью хеширования:

   Изменение хеш-значения URL-адреса не приведет к обновлению страницы.

Таким образом, внешний интерфейс может быть реализован путем маршрутизации хэша, что не приводит к эффекту обновления. хеш-свойство, расположенное в объекте местоположения, на текущей странице, вы можете:

window.location.hash='edit'

Чтобы изменить хэш-значение текущего URL-адреса. После выполнения вышеуказанного назначения хэша URL-адрес страницы изменяется.

Перед назначением:http://localhost:3000После назначения:http://localhost:3000/#edit

Значений хеша, оканчивающихся на #, в url больше, но до и после присваивания, хотя хэш-значение страницы меняется, меняется полный url страницы, но страница не будет обновляться.

Кроме того, помимо изменения значения хеш-функции текущей страницы через window.location.hash, это также может быть достигнуто через тег a html:

<a href="#edit">edit</a>

(2) Реализовать интерфейсную маршрутизацию по истории

  Интерфейс History HTML5, объект History является низкоуровневым интерфейсом и не наследуется ни от какого интерфейса. Интерфейс History позволяет нам манипулировать историей сеансов браузера.

История предоставляет некоторые свойства и методы.

Свойства истории:

  • History.length: возвращает количество записей в истории сеанса, включая текущую страницу сеанса. Кроме того, если открывается новая вкладка, то значение этой длины равно 1.
  • История.состояние: Сохраняет метод, который вызовет событие popState, и переданный объект атрибута (будет подробно описано в методах pushState и replaceState позже).

Метод истории:

  • History.back(): вернуться на предыдущую страницу в истории сеансов браузера, так же, как кнопка «Назад» в браузере.

  • History.forward(): указывает на следующую страницу в истории сеансов браузера, так же, как кнопка браузера вперед.

  • History.go(): вы можете перейти к указанной странице записи в истории сеансов браузера.

  • History.pushState(): pushState может поместить данные в стек истории сеансов браузера.Этот метод принимает 3 параметра, объект, заголовок и строку URL-адресов. После pushState URL-адрес текущей страницы будет изменен, но не будет обновлен

  • History.replaceState(): replaceState заменяет url страницы текущей сессии на указанные данные, после replaceState url текущей страницы тоже будет изменен, но страница не будет обновляться.

В приведенном выше методе одна и та же точка pushState и ответа:

То есть URL-адрес, отображаемый на текущей странице, будет изменен, но страница не будет обновлена.

разница:

pushState вдавливается в стек истории сессий браузера, сделает History.length плюс 1, а replaceState это замена текущей истории сессий, мы не будем увеличивать History.length.

(3) Резюме

   Изменяя хеш-значение или статус ответа и состояние отправки истории, вы можете изменить URL-адрес без обновления. Остается решить одну проблему:

   Как отслеживать изменения URL

   Потому что нам нужно не только изменить URL-адрес без обновления, но и отслеживать поведение изменения URL-адреса и повторно отображать представление в соответствии с поведением. В следующих нескольких главах мы сосредоточимся на прослушивании изменений URL.

Во-вторых, следите за изменениями хеша в URL-адресе.

   Если URL-адрес изменяется с помощью хэша, будет инициировано событие изменения хэша. Пока событие хеш-изменения отслеживается, поведение изменения URL-адреса с помощью хэша может быть зафиксировано.

window.onhashchange=function(event){
  console.log(event);
}
//或者
window.addEventListener('hashchange',function(event){
   console.log(event);
})

Когда значение хеша изменится, выведите HashChangeEvent. Конкретное значение HashChangeEvent:

{isTrusted: true, oldURL: "http://localhost:3000/", newURL:   "http://localhost:3000/#teg", type: "hashchange".....}

С событием прослушивателя и изменением хэш-страницы не обновляется, мы можем выполнять функцию отображения и скрытия различных отображений пользовательского интерфейса в функции обратного вызова события прослушивателя, тем самым реализуя маршрутизацию внешнего интерфейса.

3. Следите за событиями, которые изменяют URL-адрес в истории.

В предыдущей главе было несколько способов изменить URL-адрес через History: History.back(), History.forward(), History.go(), History.pushState() и History.replaceState().

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

События History.back(), History.forward(), History.go() вызовут события popstate, но History.pushState() и History.replaceState() не вызовут события popstate.

Если это History.back(), History.forward(), History.go(), то будет запущено событие popstate, нам нужно только:

window.addEventListener('popstate', function(event) {
     console.log(event);
})

Вы можете отслеживать соответствующее поведение и вызывать его вручную:

window.history.go();
window.history.back();
window.history.forward();

Это событие будет запущено. Кроме того, нажатие кнопок «Назад» и «Вперед» в браузере также вызовет событие popstate. Содержание этого события:

PopStateEvent {isTrusted: true, state: null, type: "popstate", target: Window, currentTarget: Window, …}

Однако History.pushState() и History.replaceState() не запускают события popstate, например:

window.addEventListener('popstate', function(event) {
     console.log(event);
})
window.history.pushState({first:'first'}, "page 2", "/first"})

В приведенном выше примере не будет вывода, потому что нет события popstate для прослушивания.

Однако, хотя History.go и History.back() могут инициировать событие popstate, они обновят страницу Мы используем replaceState и pushState в одностраничном приложении, так что остается проблема, которую нужно решить:

Как слушать поведение replaceState и pushState

В-четвертых, мониторинг поведения replaceState и pushState

   В приведенном выше примере мы обнаружили, что History.replaceState и pushState не запускают события popstate, поэтому как отслеживать эти два поведения. Вы можете активировать событие popState в методе. Другой способ — создать новое глобальное событие в методе.

Конкретный метод:

var _wr = function(type) {
   var orig = history[type];
   return function() {
       var rv = orig.apply(this, arguments);
      var e = new Event(type);
       e.arguments = arguments;
       window.dispatchEvent(e);
       return rv;
   };
};
 history.pushState = _wr('pushState');
 history.replaceState = _wr('replaceState');

Это создает 2 совершенно новых события с именами pushState и replaceState, которые мы можем прослушивать глобально:

window.addEventListener('replaceState', function(e) {
  console.log('THEY DID IT AGAIN! replaceState 111111');
});
window.addEventListener('pushState', function(e) {
  console.log('THEY DID IT AGAIN! pushState 2222222');
});

Таким образом можно контролировать поведение pushState и replaceState.

Справочная статья:stackoverflow.com/questions/4…