How to detect if URL has changed after hash in JavaScript

后端 未结 17 1434
無奈伤痛
無奈伤痛 2020-11-22 17:02

How can I check if a URL has changed in JavaScript? For example, websites like GitHub, which use AJAX, will append page information after a # symbol to create a unique URL w

相关标签:
17条回答
  • 2020-11-22 17:32

    EDIT after a bit of researching:

    It somehow seems that I have been fooled by the documentation present on Mozilla docs. The popstate event (and its callback function onpopstate) are not triggered whenever the pushState() or replaceState() are called in code. Therefore the original answer does not apply in all cases.

    However there is a way to circumvent this by monkey-patching the functions according to @alpha123:

    var pushState = history.pushState;
    history.pushState = function () {
        pushState.apply(history, arguments);
        fireEvents('pushState', arguments);  // Some event-handling function
    };
    

    Original answer

    Given that the title of this question is "How to detect URL change" the answer, when you want to know when the full path changes (and not just the hash anchor), is that you can listen for the popstate event:

    window.onpopstate = function(event) {
      console.log("location: " + document.location + ", state: " + JSON.stringify(event.state));
    };
    

    Reference for popstate in Mozilla Docs

    Currently (Jan 2017) there is support for popstate from 92% of browsers worldwide.

    0 讨论(0)
  • 2020-11-22 17:39

    I created this, just add the function as an argument and whenever the link has any changes it will run the function returning the old and new url

    I created this, just add the function as an argument and whenever the link has any changes it will run the function returning the old and new url

    // on-url-change.js v1 (manual verification)
    let onUrlChangeCallbacks = [];
    let onUrlChangeTimestamp = new Date() * 1;
    function onUrlChange(callback){
        onUrlChangeCallbacks.push(callback);
    };
    onUrlChangeAutorun();
    function onUrlChangeAutorun(){
        let oldURL = window.location.href;
        setInterval(function(){
            let newURL = window.location.href;
            if(oldURL !== newURL){
                let event = {
                    oldURL: oldURL,
                    newURL: newURL,
                    type: 'urlchange',
                    timestamp: new Date() * 1 - onUrlChangeTimestamp
                };
                oldURL = newURL;
                for(let i = 0; i < onUrlChangeCallbacks.length; i++){
                    onUrlChangeCallbacks[i](event);
                };
            };
        }, 25);
    };
    
    0 讨论(0)
  • 2020-11-22 17:40

    Add a hash change event listener!

    window.addEventListener('hashchange', function(e){console.log('hash changed')});
    

    Or, to listen to all URL changes:

    window.addEventListener('popstate', function(e){console.log('url changed')});
    

    This is better than something like the code below because only one thing can exist in window.onhashchange and you'll possibly be overwriting someone else's code.

    // Bad code example
    
    window.onhashchange = function() { 
         // Code that overwrites whatever was previously in window.onhashchange  
    }
    
    0 讨论(0)
  • 2020-11-22 17:42

    use this code

    window.onhashchange = function() { 
         //code  
    }
    

    with jQuery

    $(window).bind('hashchange', function() {
         //code
    });
    
    0 讨论(0)
  • 2020-11-22 17:42

    To listen to url changes, see below:

    window.onpopstate = function(event) {
      console.log("location: " + document.location + ", state: " + JSON.stringify(event.state));
    };
    

    Use this style if you intend to stop/remove listener after some certain condition.

    window.addEventListener('popstate', function(e) {
       console.log('url changed')
    });
    
    0 讨论(0)
  • 2020-11-22 17:43

    I wanted to be able to add locationchange event listeners. After the modification below, we'll be able to do it, like this

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

    In contrast, window.addEventListener('hashchange',()=>{}) would only fire if the part after a hashtag in a url changes, and window.addEventListener('popstate',()=>{}) doesn't always work.

    This modification, similar to Christian's answer, modifies the history object to add some functionality.

    By default, there's a popstate event, but there are no events for pushstate, and replacestate.

    This modifies these three functions so that all fire a custom locationchange event for you to use, and also pushstate and replacestate events if you want to use those:

    /* These are the modifications: */
    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'))
    });
    
    0 讨论(0)
提交回复
热议问题