开发者

window.location.hash refresh in Chrome?

开发者 https://www.devze.com 2023-02-25 15:02 出处:网络
I was doing some snooping on the web and found window.location.hash = \"etc\" to be a widely adopted method to update the browser\'s location without reloading / refreshing the page. I\'ve applied tha

I was doing some snooping on the web and found window.location.hash = "etc" to be a widely adopted method to update the browser's location without reloading / refreshing the page. I've applied that to this example I've cooked up: http://dl.dropbox.com/u/1595444/locationExample/index.html

Works well in Safari, but...

What I've noticed is that in Chrome 10+ up开发者_运维知识库on changing hash:

  • There is something similar to a reload.
  • The resulting symptom is a hiccup as the user scrolls down or up.
  • My console output is preserved (if you check your console the project string's are outputted).
  • The favicon seems to be reloading.
  • Has anyone run into this problem before? Know a fix?


    There are most likely two things going on here:

    • The favicon and stop/refresh buttons flicker because of a Chrome bug (that mentions pushState, but hash changes are on the same code path).
    • The slight hiccup when scrolling is because Chrome does a full page repaint and high-quality scale to update the page thumbnail, since it's considering hash changes as generating a new URL. That's also a bug. You can see this in the inspector timeline view, most scroll events result in a repaint of window width x some small height, but occasionally there will be a full-window repaint. This blog post has a few more details.

    A workaround for both would be to defer the updating of the hash until the user is done scrolling (you can still update the white bar that appears under the current item immediately). You can do this by having something like:

    var scrollTimeout;
    window.onscroll = function() {
      // update current item display here
      if (scrollTimeout)
        clearTimeout(scrollTimeout);
      scrollTimeout = setTimeout(function() {
        scrolTimeout = undefined;
         // update hash here
      }, 100);
    };
    

    Since it looks like you're using jQuery, there are debouncing plugins that may be helpful.


    I don't have a definitive answer, but first I would try:

    1. Prepending the hash mark (#) on to the value (i.e. use window.location.hash = "#etc").
    2. Register a handler for the window.onhashchange handler.
    3. Alternatively, you might consider using history.pushState if what you are trying to accomplish is make the back button return to the previous logical location (it's not clear to me what you are trying accomplish, whether you just want to jump to a section on the page, or something more complex).


    var r='#hello';
    if(navigator.userAgent.indexOf('Chrome/')!=-1){
     top.history.pushState("", "", r);
     return;
    };
    if(r.charAt(0)=='/'){
      top.location.replace(r);
     }else{
      top.location.hash=r;
    };
    

    Worked for me. And it actually took me a long time to figure this out. Firefox also supports the history object now, so we may be able to get rid of the whole "hash" thing in a few years.

    EDIT: Yes, the reloading thing is a Chrome bug.

    0

    精彩评论

    暂无评论...
    验证码 换一张
    取 消