2

我在 javascript/html5 中遇到历史对象和 iframe 的问题。我写了一个简单的项目来描述我的问题:

http://dktest.evermight.com/

这是一个带有 iframe 和下一步按钮的页面。每次单击下一步时,它都会加载一个带有递增计数器的新页面。但是,单击浏览器后退按钮并没有做我想做的事情。让我通过将这篇文章分成以下几个部分来解释这个问题:

  1. 我想达到什么
  2. 当前项目中的不良结果
  3. 发布我所有的代码

1. 我想要达到的目标

我希望用户:

  1. 打开一个新窗口并转到http://dktest.evermight.com/
  2. 单击下一页并看到一个红框淡入,并看到 urlhttp://dktest.evermight.com/count.html?count=0同时出现在 iframe 和浏览器的地址栏中
  3. 再次单击下一页并http://dktest.evermight.com/count.html?count=1在 iframe 和浏览器的地址栏中查看
  4. 单击浏览器的后退按钮一次http://dktest.evermight.com/count.html?count=0,并在 iframe 和浏览器的地址栏中查看
  5. 单击浏览器的后退按钮一次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/上查看源代码。为了方便起见,我也会在这里发布。

索引.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>

关闭.html

<!DOCTYPE html>
<html>
        <script type="text/javascript">
                parent.hideContainer();
        </script>
</html>

计数.html

我不能修改 count.html 的内容。在我的真实项目中,count.html 实际上是一个 youtube 视频,它位于我无法直接访问的服务器上。

<html>
        <body>Youtube video at url <script type="text/javascript">document.write(location.href);</script></body>
</html>

初始化.html

Perform application specific functionality

任何人都可以更正我的代码以达到第 1 部分所述的第 4 步和第 5 步的结果吗?

更新 好的,根据我正在做的一些实验,我对这个问题有了更多的了解。

实验1:我尝试改变线路:

$('#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 作为一个单独的堆栈溢出问题。

4

2 回答 2

2

我创建一个新的 iframe 并在加载新内容时销毁 iframe。这解决了历史问题。

于 2013-03-07T14:06:17.453 回答
0

我知道这是一个history问题,但如果您仍然对其他可能性持开放态度,我认为jquery-pjax实际上更适合您正在尝试做的事情。

更新我认为这应该可行。

计数.html

 <div id="pjax-container">
    <a id="pjax" data-pjax href="#">Next Page</a>
 </div>

javascript

 // get URL parameter (count): http://stackoverflow.com/questions/1403888/get-url-parameter-with-jquery
 function getURLParameter(name) {
     return decodeURI(
        (RegExp(name + '=' + '(.+?)(&|$)').exec(location.search)||[,null])[1]
     );
 }

 $(document).on('pjax:beforeSend', function() {
     // your fading code goes here
 })

 $(document).on('pjax:complete', function() {
     // fade out
     // and then modify the anchor's href with something like   
     var new_count = getURLParameter('count') + 1;          
     $('a#pjax').attr('href', 'count.html?count=?' + new_count); 
 })

 // where the pjaxed content should go
 $(document).pjax('a[data-pjax]', '#pjax-container')
于 2013-02-06T05:18:51.703 回答