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

History API pushState() creating two entries

如标题所述,当我使用 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/

我想做的是在点击 link 时重新加载 iframe(并更改 h1 文本)而不重新加载整个页面,但仍然具有可遍历和可收藏的历史记录(这是一个词?)...看起来应该很简单,我已经浏览了 MDN 上的示例和其他教程,但无济于事。

我的代码如下。我确定我做错了什么,但任何 help/insight 将不胜感激!

$(".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(EDIT): 所以这是 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 的 link(一次),但这是创建了两个历史条目。第一次单击后退按钮时,iframe 重新加载到上一个视频并且没有 popstate。第二次点击 'back' 时,我得到了包含所有属性的 popstate。

更改 iframe 的 src 会添加两个 pushState。 trick/hack/workaround是移除当前的iframe,构建一个新的iframe片段并插入。然后,调用你的 pushState。

来源:

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

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

   // BAD: iFrame.src   = href;

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

一般来说 location.replace() 无论是否与 iFrame 一起使用都不会创建历史条目。

我花了很长时间才弄清楚这个修复,因为我认为这个问题可能是由于我不正确地使用 history.pushState() 造成的。

请注意,我的问题不是 history.pushState()“创建两个条目”。它只创造了一个。问题是我还分配给 iFrame.src,它创建了第二个条目。