历史 API pushState() 创建两个条目
Posted
技术标签:
【中文标题】历史 API pushState() 创建两个条目【英文标题】:History API pushState() creating two entries 【发布时间】:2017-02-06 17:33:43 【问题描述】:正如标题所述,当我使用 pushState() 更改历史记录时,它会出于某种原因将我的条目两次添加到堆栈中,即使它只单击了一次。因此,当我尝试使用后退按钮返回时,每隔一次按下按钮,我就会得到一个弹出状态。当我将状态记录到控制台时,每当我收到“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&byline=0&portrait=0&badge=0&autopause=0&player_id=0&autoplay=1" frameborder="0" title="THETITLE" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>
VIDEOID
和 THETITLE
只是最初从 php 传入的字符串。
这次我运行了一个console.log,这就是它的作用。我单击将新 iframe src 传递给 iframe 的链接(一次),但这会创建两个历史记录条目。第一次单击后退按钮时,iframe 会重新加载到上一个视频并且没有弹出状态。第二次单击“返回”时,我得到了包含所有属性的弹出状态。
【问题讨论】:
你用e.preventDefault()
试过了吗..return false
做的差不多,但值得一问
是的。这是我做的第一件事,然后改成return false
您的代码似乎对我有用。您能否在window.history.pushState
下放置debugger
或console.log
以确认每次点击只调用一次推送。如果可能的话,您能否将大部分代码与 html 一起发布。
@Spartacus,你能添加你正在使用的 html 吗?或者如果可能的话 - 添加一个完整的工作 jsfiddle 来演示问题。
可能与 DOM 或鼠标有关!
【参考方案1】:
我相信我遇到了相同或非常相似的问题。使用 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,它创建了第二个条目。
【讨论】:
【参考方案2】:更改 iframe 的 src 会添加两个 pushState。技巧/黑客/解决方法是删除当前的 iframe,构建一个新的 iframe 片段并插入它。然后,调用你的 pushState。
来源: Updating an iframe, history and URL. Then making it work with back button
【讨论】:
就是这样......该死的,我正在拔头发,以为我编程出了问题。谢谢! 是的,第一句话;救生员。删除 iframe 可以停止我遇到的与此相关的双重状态问题!以上是关于历史 API pushState() 创建两个条目的主要内容,如果未能解决你的问题,请参考以下文章
H5,API的pushState(),replaceState()和popstate()用法
HTML5历史状态管理history API-pushState/replaceState与popstate事件
HTML5历史状态管理history API-pushState/replaceState与popstate事件