历史记录API pushState()创建两个条目

3
正如标题所述,当我使用pushState()改变历史记录时,由于某些原因它会将我的条目两次添加到栈中,即使只点击了一次。因此,当我尝试使用后退按钮遍历时,每按一次按钮就只获得一个popstate。而且当我将状态记录到控制台时,每次获取“pop”时都显示“null”。
历史记录如下:
http://example.com/foo/bar/question/8/
http://example.com/foo/bar/question/8/
http://example.com/foo/bar/question/3/
http://example.com/foo/bar/question/3/
http://example.com/foo/bar/question/27/
http://example.com/foo/bar/question/27/
我想做的是在链接点击时重新加载iframe(并更改h1文本),而不重新加载整个页面,但仍然可以遍历和添加书签(这是一个词吗?)...看起来应该很简单,但我已经查看了MDN和其他教程的示例,但没有成功。
我的代码如下。我肯定做错了什么,但任何帮助/见解都将不胜感激!
$(".vidlinks a").on('click', function(e) {
    var frsrc = 'https://player.vimeo.com'+$(this).attr('data-iframe')+'?title=0&byline=0&portrait=0&badge=0&autopause=0&player_id=0&autoplay=1',
        targetUrl = $(this).attr('href'),
        pgtitle = $(this).attr('title'),
        obj = {url:targetUrl,ttl:pgtitle};
        $("iframe").attr('src', frsrc );
        $(".vidtitle h1").fadeOut("fast", function() {
            $(this).text(pgtitle);
        });
        $(".vidtitle h1").fadeIn("fast");

        window.history.pushState(obj, document.title, targetUrl);
        return false;
    });

   window.onpopstate = function(e) {
        $(".vidtitle h1").fadeOut("fast", function() {
            $(this).text(e.state.ttl);
        });
        $(".vidtitle h1").fadeIn("fast");
   }

编辑: 我还尝试使用replaceState()而不是pushState()。这在某种程度上解决了双重输入的问题,但使用后退按钮不会通过此方法更改浏览器中的状态。这已在Chrome、Safari和FF上进行了测试。

编辑 编辑: 奇怪的是,如果我完全注释掉pushState()语句,并单击返回按钮,则iframe将重新加载到以前的视频,但其他内容没有更改。


3(编辑): 下面是iframe代码...

<iframe src="https://player.vimeo.com/video/VIDEOID?title=0&amp;byline=0&amp;portrait=0&amp;badge=0&amp;autopause=0&amp;player_id=0&amp;autoplay=1" width="1920" height="1080" frameborder="0" title="THETITLE" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>

VIDEOIDTHETITLE最初是从PHP传递的字符串。

这次我运行了一个console.log,以下是它的操作过程。我点击链接(一次)将新的iframe src传递给iframe,但这会创建两个历史记录条目。第一次单击“返回”按钮时,iframe重新加载到上一个视频而没有popstate。第二次单击“返回”按钮时,我得到了所有属性的popstate。


你尝试过使用 e.preventDefault() 吗?return false 做的事情几乎相同,但还是值得问一下。 - charlietfl
是的。那是我做的第一件事,然后改成了 return false - Spartacus
你的代码在我这里似乎是有效的。你能否在window.history.pushState下面放置一个debuggerconsole.log,以确认每次单击只调用一次push。如果可能的话,您可以发布更大部分的代码以及HTML。 - Gokhan Kurt
1
@Spartacus,你可以添加你正在使用的HTML代码吗?或者如果可能的话 - 添加一个完整的工作jsfiddle以演示问题。 - Dekel
也许与DOM或鼠标有关! - vijayst
我编辑了我的回答并添加了新信息。谢谢! - Spartacus
2个回答

5

1
就是这样...该死,我一直在想我可能在编程上出了什么问题。谢谢! - Spartacus
是的,第一句话真是救命稻草。移除 iframe 可以解决我遇到的与此相关的双状态问题! - Scott Byers

0

我认为我遇到了同样或非常相似的问题。在使用history.pushState()之后,必须点击两次后退按钮才能发生任何事情。而且我正在使用iFrames。

解决方案是不要分配给iFrame.src,而是使用'location.replace()'代替:

   // BAD: iFrame.src   = href;

   iFrame.contentDocument.location.replace (href);    // GOOD

一般而言,不管是否与 iFrames 一起使用,location.replace() 都不会创建历史记录条目。
我花了太长时间才弄清楚这个问题的解决方法,因为我以为问题可能是由于我不正确使用 history.pushState() 导致的。
所以请注意,我的问题并不是 history.pushState() "创建了两个条目"。它只创建了一个。问题在于我还给 iFrame.src 赋值,这就创建了第二个条目。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接