如何区分哈希(#)URL更改与其他URL更改?

问题描述 投票:0回答:1

我正在尝试区分两种类型的URL更改。

基本使用pushstate,可以从http://example.com移至http://example.com/account,而无需重新加载页面(此处为an example)。

可以通过以下技巧来检测这些变化(摘自[here](How to detect URL change in 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(在历史记录中)(see here)。

我将如何区分这两种类型的事件?

javascript pushstate
1个回答
0
投票

[我担心必须依靠正则表达式来获取哈希,但是我刚刚意识到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!');
 })
© www.soinside.com 2019 - 2024. All rights reserved.