简体   繁体   中英

Setting window.location.hash does not work with back button as of Chrome 47

I have a standalone HTML file (not hosted) which uses UI Layout and Fancytree . I have tried hosting using Python's SimpleHTTPServer and I have the same problem. The tree is used for navigation, so its nodes are all anchor links. When an anchor link is clicked the goToLink function is called and the main UI Layout pane does an animated scroll to the correct anchor and the link that was clicked is added to the browser's history so the user can make use of the back button. This worked as desired until Chrome version 47. I have tried several variations of the code below, but I always get the same result when the back button is pressed. That is, the URL changes in the address bar, but the page does not jump back to the correct anchor. This is also a problem in Firefox but I'm not sure what version of Firefox it got broken in. I don't care about IE.

function goToLink(link) {
    if(link.slice(0, 1) != "#") {
        link = "#" + link;
    }

    var a = $('[name="' + link.slice(1) + '"]');
    var parent = a.parent();
    var pane = a.closest('.ui-layout-center');
    var aTop = a.offset().top;
    var paneTop = pane.offset().top;

    pane.animate({scrollTop: '+=' + (aTop - paneTop) + "px"}, 1000, "linear");
    var currentLocation = pane.scrollTop();
    window.location.hash = link;
    pane.scrollTop(currentLocation);
}

It looks like this problem is related to Chrome's recently introduced Scroll Restoration . I got around the problem by detecting that feature and tracking hash changes. This also fixes the issue in Firefox:

var hashAlreadyChanged = false;
var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
var goToLinkOnHashChange = 'scrollRestoration' in history || isFirefox;

$(window).on('hashchange', function() {
    if(goToLinkOnHashChange) {
        goToLink(window.location.hash);
        hashAlreadyChanged = false;
    }
});

function goToLink(link) {
    if(link.slice(0, 1) != "#") {
        link = "#" + link;
    }

    if(!hashAlreadyChanged) {
        hashAlreadyChanged = goToLinkOnHashChange;

        var aName = isFirefox ? decodeURI(link) : link; // Firefox auto encodes the URL so I decode to get the correct "a" tag name
        var a = $('[name="' + aName.slice(1) + '"]');
        var pane = a.closest('.ui-layout-center');
        var aTop = a.offset().top;
        var paneTop = pane.offset().top;

        pane.animate({scrollTop: '+=' + (aTop - paneTop) + "px"}, 1000, "linear");

        var currentLocation = pane.scrollTop();
        window.location.hash = link;
        pane.scrollTop(currentLocation);
    }
}

他们是这样实现的,这很奇怪,但解决方案很简单,只需在初始负载中添加它即可。

window.history.replaceState({}, document.title, window.location.href);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM