【问题标题】:History object back button with iframes带有 iframe 的历史对象后退按钮
【发布时间】:2013-02-06 05:16:14
【问题描述】:

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

http://dktest.evermight.com/

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

  1. 我想要实现的目标
  2. 当前项目中出现不良结果
  3. 发布我的所有代码

1.我想要达到的目标

我希望用户:

  1. 打开一个新窗口并转到http://dktest.evermight.com/
  2. 点击下一页并看到一个红色框淡入,并看到 url http://dktest.evermight.com/count.html?count=0 出现在 iframe 和浏览器的地址栏中
  3. 再次点击下一页,在 iframe 和浏览器地址栏中看到http://dktest.evermight.com/count.html?count=1
  4. 点击浏览器的返回按钮ONCE,在 iframe 和浏览器的地址栏中看到http://dktest.evermight.com/count.html?count=0
  5. 点击浏览器的返回按钮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


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      更新我认为这应该可行。

      count.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')
      

      【讨论】:

      • 我愿意使用 jquery-pjax。您使用 jquery-pjax 发布上述问题的示例解决方案是否容易?
      • 当然。给我一点时间,我会打一个例子。
      • 我已经更新了我的答案。这是非常基本的,但这就是我解决 pjax 问题的方式。
      • 好的,我必须做更多的研究,因为我不确定发生了什么。我也不能修改 count.html,因为那是在第 3 方服务器上。
      • 嗯,也许您可​​以在某处添加数据属性并将其存储在那里,例如在
        内部
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-31
      • 2015-10-11
      • 2011-05-25
      • 1970-01-01
      • 2018-10-02
      相关资源
      最近更新 更多