Javascript – add hash in URL with "onscroll" to create browser history (works with Firefox, not with Chrome)

huangapple go评论67阅读模式
英文:

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 == &quot;#loaded&quot;)
{
window.addEventListener(&quot;scroll&quot;, checkScroll);
}
function checkScroll() 
{
original_url = window.location.href;
clean_url = original_url.split(&#39;?&#39;)[0];
clean_url = clean_url.split(&#39;#&#39;)[0];
var stateObj = { page: &quot;scrolled&quot; };
var newUrl = clean_url + &quot;#reading&quot;;
history.pushState(stateObj, &quot;&quot;, newUrl);
window.removeEventListener(&quot;scroll&quot;, checkScroll);
}

I have added a hash listener in the body tag:

&lt;body onhashchange=&quot;manageHash()&quot;&gt;

and here is the function:

function manageHash()
{
switch(window.location.hash)
{
case &quot;#reading&quot;:
console.log(&quot;started reading&quot;);
// do something
break;
case &quot;#loaded&quot;:
console.log(&quot;back to loaded&quot;);
// 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(&#39;hashchanged&#39;, manageHash);

https://developer.mozilla.org/en-US/docs/Web/API/Window/hashchange_event

huangapple
  • 本文由 发表于 2023年5月23日 00:42:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/76308318.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定