【发布时间】:2013-02-06 05:16:14
【问题描述】:
我在使用 javascript/html5 中的历史对象和 iframe 时遇到问题。我写了一个简单的项目来描述我的问题:
这是一个带有 iframe 和下一步按钮的页面。每次单击下一步时,它都会加载一个带有递增计数器的新页面。但是,单击浏览器后退按钮并没有做我想做的事情。让我把这篇文章分成以下几个部分来解释这个问题:
- 我想要实现的目标
- 当前项目中出现不良结果
- 发布我的所有代码
1.我想要达到的目标
我希望用户:
- 打开一个新窗口并转到http://dktest.evermight.com/
- 点击下一页并看到一个红色框淡入,并看到 url
http://dktest.evermight.com/count.html?count=0出现在 iframe 和浏览器的地址栏中 - 再次点击下一页,在 iframe 和浏览器地址栏中看到
http://dktest.evermight.com/count.html?count=1 - 点击浏览器的返回按钮ONCE,在 iframe 和浏览器的地址栏中看到
http://dktest.evermight.com/count.html?count=0 - 点击浏览器的返回按钮ONCE,在浏览器的地址栏中看到
http://dktest.evermight.com/,然后看到红色框淡出
2。当前项目中的不良结果
我的代码位于http://dktest.evermight.com/,它目前无法正确执行第 4 步和第 5 步。当我执行第 4 步时,iframe 显示http://dktest.evermight.com/count.html?count=0,但浏览器地址栏显示http://dktest.evermight.com/count.html?count=1。我必须再次按下浏览器的返回按钮才能使浏览器地址栏显示http://dktest.evermight.com/count.html?count=0。当我执行第 5 步时,红色框消失了,这很好,但地址栏仍然显示 http://dktest.evermight.com/count.html?count=0。我必须再次按回以使地址栏显示http://dktest.evermight.com/。
3.发布我所有的代码
我的代码非常简单。您可以在http://dktest.evermight.com/ 上查看源代码。为了方便,我也会在这里发帖。
index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
var count=0;
function clicknext()
{
$('#container').fadeIn();
$('#iframe').attr('src','count.html?count='+count.toString());
$('html title').html(count);
history.pushState({blahblah:'whatgoeshere?'},'i dont know what goes here either','http://dktest.evermight.com/count.html?count='+count);
count++;
}
function hideContainer()
{
$('#container').fadeOut();
var closeurl = 'close.html';
if($('#iframe').attr('src') != closeurl )
$('#iframe').attr('src', closeurl);
}
$(document).ready(function(){
hideContainer();
});
</script>
</head>
<body>
<div id="container" style="display:none; background:red;">
<!-- IMPORTANT
When DOM first created, the iframe.src MUST BE initialize.html
I have some code that I need to fire on that page before the rest
of this document starts
-->
<iframe id="iframe" src="initialize.html"></iframe>
</div>
<input type="button" onclick="clicknext()"; value="next page" />
</body>
</html>
close.html
<!DOCTYPE html>
<html>
<script type="text/javascript">
parent.hideContainer();
</script>
</html>
count.html
我不能修改 count.html 的内容。在我的实际项目中,count.html 实际上是一个 youtube 视频,它在我无法直接访问的服务器上。
<html>
<body>Youtube video at url <script type="text/javascript">document.write(location.href);</script></body>
</html>
initialize.html
Perform application specific functionality
谁能更正我的代码以达到第 1 部分所述的第 4 步和第 5 步的结果?
更新 好的,根据我正在做的一些实验,我对这个问题有了更多的了解。
实验一:我尝试换行:
$('#iframe').attr('src','count.html?count='+count.toString());
到
$('#iframe')[0].contentWindow.location.replace('count.html?count='+count.toString());
这使我能够正确执行第 4 步。显然, contentWindow.location.replace() 不会在历史对象中创建条目。但是,这导致了与 count.html 的内容相关的一些其他问题,该内容实际上是 youtube/vimeo 内容的页面。 youtube/vimeo 内容要求您通过 attr('src') 方法而不是 .contentWindow.location.replace() 加载信息。所以也许解决方案是找到一种方法让 attr('src') 不使用历史对象创建条目?
实验 2 我尝试的另一个可能的解决方案是更改 attr('src') 和 history.pushState() 调用的顺序。我尝试先调用 attr('src'),然后再调用 history.pushState(),然后先调用 history.pushState(),然后再调用 attr('src')。但在这两种情况下,当我按下浏览器的后退按钮时,首先返回的是 iframe 内容。因此,我无法通过历史对象捕获传递给自己的消息以执行“双重返回”,因为历史对象中的信息在事件序列中最后可用。
实验 3 我也尝试使用 History.js。它没有做任何事情来解决我上面的问题。据我所知,它的工作方式与常规历史对象完全一样。
还有什么我可以尝试的吗?或者建议对上述任何实验进行修改?我将进一步探讨实验 1 作为一个单独的堆栈溢出问题。
【问题讨论】:
标签: javascript html