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
:
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:
- Prepending the hash mark (#) on to the value (i.e. use window.location.hash = "#etc").
- Register a handler for the window.onhashchange handler.
- 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.
精彩评论