带有iframe的历史对象后退按钮

时间:2013-02-06 05:16:14

标签: javascript html5

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

http://dktest.evermight.com/

这是一个包含iframe和下一个按钮的页面。每次单击下一步,它都会加载一个带有递增计数器的新页面。但是,单击浏览器后退按钮不会执行我想要的操作。让我通过将这篇文章分解为以下部分来解释这个问题:

  1. 我想要实现的目标
  2. 当前项目中不受欢迎的结果
  3. 发布我的所有代码
  4. 1。我想要实现的目标

    我希望用户:

    1. 打开一个新窗口并转到http://dktest.evermight.com/
    2. 点击下一页,看到红框淡入,并看到网址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/并看到红框淡出
    6. 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的结果吗?

      更新 好的,基于我正在做的一些实验,我对这个问题有点了解。

      实验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作为单独的堆栈溢出问题。

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

我知道这是一个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')