Как отличить изменение URL хеша (#) от других изменений URL? - PullRequest
0 голосов
/ 12 октября 2019

Я пытаюсь различить два типа изменений URL.

В основном с pushstate можно перейти с http://example.com на http://example.com/account без перезагрузки страницы (здесь ипример ).

Эти изменения можно обнаружить с помощью следующего трюка (взято из [здесь] ( Как обнаружить изменение URL в JavaScript )):

/* Add a locationstorage event in the window */
history.pushState = ( f => function pushState(){
    var ret = f.apply(this, arguments);
    window.dispatchEvent(new Event('pushState'));
    window.dispatchEvent(new Event('locationchange'));
    return ret;
})(history.pushState);

history.replaceState = ( f => function replaceState(){
    var ret = f.apply(this, arguments);
    window.dispatchEvent(new Event('replaceState'));
    window.dispatchEvent(new Event('locationchange'));
    return ret;
})(history.replaceState);

window.addEventListener('popstate',()=>{
    window.dispatchEvent(new Event('locationchange'))
});

// Capture the locationchange event
window.addEventListener('locationchange', function(){
    console.log('location changed!');
});

ХотяЯ понял, что он также фиксирует изменения Hash URL, например http://example.com#about. Я знаю, что изменения хеш-URL могут быть зафиксированы следующим образом:

$(window).bind('hashchange', function() {
 /* things */
});

Моя проблема в том, что изменения хеша также вызывают popstate (в истории) ( см. Здесь ).

Как мне провести различие между этими двумя типами событий?

1 Ответ

0 голосов
/ 12 октября 2019

Я беспокоился о том, что для получения хеша мне нужно зависеть от регулярного выражения, но я только что понял, что объект Location уже анализирует хеш из URL.

Все, что мне нужно было сделать, этоизвлекать хеш из местоположения до и после события (и поддерживать его в актуальном состоянии);

Итак, введите переменную с текущим местоположением:

current_hash = window.location.hash;

и используйте ее для различения типаизменения URL (держите его в курсе):

window.addEventListener('popstate', (ev) => {
    if (ev.target.location.hash == current_hash){
       window.dispatchEvent(new Event('locationchange'));
    } else {
      current_hash = ev.target.location.hash;
    }
});

Полный пример

# variable that keeps the current hash
current_hash = window.location.hash;

history.pushState = ( f => function pushState(){
    var ret = f.apply(this, arguments);
    window.dispatchEvent(new Event('pushState'));
    window.dispatchEvent(new Event('locationchange'));
    return ret;
})(history.pushState);

history.replaceState = ( f => function replaceState(){
    var ret = f.apply(this, arguments);
    window.dispatchEvent(new Event('replaceState'));
    window.dispatchEvent(new Event('locationchange'));
    return ret;
})(history.replaceState);

window.addEventListener('popstate', (ev) => {
    # use it to distinguish the event
    if (ev.target.location.hash == current_hash){
       window.dispatchEvent(new Event('locationchange'));
    } else {
      # keep current hash updated
      current_hash = ev.target.location.hash;
    }
 });

 window.addEventListener('locationchange', function(event){
   console.log('location changed!');
 })
...