英文:
Javascript - add hash in URL with "onscroll" to create browser history (works with Firefox, not with Chrome)
问题
I'm providing the translated code and relevant information as requested:
我正试图实现以下内容:
- 加载一个带有哈希标记的页面(例如:#loaded)
- 当用户开始滚动页面(在滚动事件上)时,会创建一个带有另一个哈希的新条目(例如:#reading)
- 当用户返回浏览历史记录时,应该看到 #loaded 哈希
这似乎很简单,但在 Chrome 中有一个我不理解的技巧。
以下是代码:
current_hash = window.location.hash;
if (current_hash == "#loaded")
{
window.addEventListener("scroll", checkScroll);
}
function checkScroll()
{
original_url = window.location.href;
clean_url = original_url.split('?')[0];
clean_url = clean_url.split('#')[0];
var stateObj = { page: "scrolled" };
var newUrl = clean_url + "#reading";
history.pushState(stateObj, "", newUrl);
window.removeEventListener("scroll", checkScroll);
}
我在 body 标签中添加了一个哈希监听器:
<body onhashchange="manageHash()">
以下是函数:
function manageHash()
{
switch(window.location.hash)
{
case "#reading":
console.log("started reading");
// 做一些事情
break;
case "#loaded":
console.log("back to loaded");
// 做一些其他事情
break;
}
}
请注意,我只提供了代码的翻译,没有包含其他内容。
英文:
I'm trying to achieve the following thing:
- a page is loaded with a hashtag (ex: #loaded)
- when the user start to scroll (on scroll event) that page, a new entry with another hash is created (ex: #reading)
- when the user goes back in history, it should see the #loaded hash
This seems pretty simple to do but there is a trick with Chrome that I don't understand.
Here is the code:
current_hash = window.location.hash;
if (current_hash == "#loaded")
{
window.addEventListener("scroll", checkScroll);
}
function checkScroll()
{
original_url = window.location.href;
clean_url = original_url.split('?')[0];
clean_url = clean_url.split('#')[0];
var stateObj = { page: "scrolled" };
var newUrl = clean_url + "#reading";
history.pushState(stateObj, "", newUrl);
window.removeEventListener("scroll", checkScroll);
}
I have added a hash listener in the body tag:
<body onhashchange="manageHash()">
and here is the function:
function manageHash()
{
switch(window.location.hash)
{
case "#reading":
console.log("started reading");
// do something
break;
case "#loaded":
console.log("back to loaded");
// do something else
break;
}
}
When I access the page with #loaded and if I scroll, I see the #reading in the URL but in Firefox I can hit the back button but not with Chrome. The first time I fired the code in Chrome it worked and the second time I fired it without changing anything to the code, it didn't work anymore. Chrome detects the scroll, changes the hash but does not create a new entry in the history anymore.
I'm a bit puzzled because I can run the code as many times I want on Firefox and it works. With Chrome it worked only once and I don't see any error in the console.
I know that user interaction is required to be able to create a browser entry but in my case, I have the onscroll behaviour that should do this.
Thanks
答案1
得分: 2
你应该使用pushState()
来更改你的哈希值,因此当你点击浏览器返回按钮时,应使用相应的popstate
事件进行处理:
https://developer.mozilla.org/en-US/docs/Web/API/Window/popstate_event
此外,hashchanged
事件可在window
上使用。因此,可能在Chrome中将事件绑定到window上会起作用:
window.addEventListener('hashchanged', manageHash);
https://developer.mozilla.org/en-US/docs/Web/API/Window/hashchange_event
英文:
Since you use pushState()
to change your hash you should use the corresponding popstate
event that emitted when you hit the browser back button:
https://developer.mozilla.org/en-US/docs/Web/API/Window/popstate_event
Also the hashchanged
event is available on window
. So maybe binding the event on window would work in Chrome:
window.addEventListener('hashchanged', manageHash);
https://developer.mozilla.org/en-US/docs/Web/API/Window/hashchange_event
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论