IE在后退/前进键后丢失iframe内容

时间:2012-02-12 16:18:14

标签: javascript internet-explorer dom iframe back

此问题仅发生在IE中(至少8和9)。将元素动态添加到DOM后,当使用BACK / FORWARD键重新输入页面时,嵌入式iframe的内容将丢失。只有两个小的HTML文件会重现这个问题。


第一个文件是iframe.htm:

<!DOCTYPE html>
<html>
<head>
    <title>IE iframe bug</title>
    <script type="text/javascript">
        function mytrace(msg) {
            var t = document.createTextNode(msg);
            var b = document.createElement('br');
            var d = document.getElementById("trace_output")
            d.appendChild(t);
            d.appendChild(b); /// will work if commented
        }
        function submitListing() {
            mytrace('submitListing()');
            var doc = document.getElementById("output_iframe")
                .contentWindow.document;
            var d = new Date;
            doc.location.replace('report.htm?invalidateCache=' + d.getTime());
            //mytrace('submitListing(): out');
        }
    </script>
</head>
<body>
    <div id="trace_output"><br /></div>
    <input type="button" onclick="submitListing();" value="Run" /><br />
    <iframe id="output_iframe" src=""></iframe>
</body>
</html>


第二个文件是report.htm:

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
    <a href="http://google.com" target="_top">LINK</a>
</body>
</html>


重新创建问题的步骤(BACK KEY)

  1. 将上述内容放在两个文件中
  2. 浏览iframe.htm文件
  3. 按“运行”按钮在iframe中加载report.htm
  4. 点击LINK链接以加载其他页面
  5. 按浏览器BACK按钮返回“缓存”(lmao)页面
  6. iframe内容已经消失!!!! (仅限IE-- safari,chrome,firefox保留内容)
  7. 另外..(前进钥匙)

    1. 浏览到任意页面(对于历史记录,http://www.google.com有效)
    2. 将iframe.htm加载到同一个标签
    3. 按“运行”按钮在iframe中加载report.htm
    4. 按浏览器BACK按钮返回第一页
    5. 按浏览器FORWARD按钮返回iframe.htm
    6. iframe内容再次消失!!

    7. 现在注释掉这一行:

      d.appendChild(b)
      

      一个更改允许一切在IE中工作。但是,我的解决方案需要进行那些DOM操作(重型jQuery / AJAX应用程序)并能够跨浏览器BACK / FORWARD操作恢复iframe。

      似乎我必须记住iframe的内容,以便在使用BACK / FORWARD键访问页面时可以恢复它。我对此并不感到兴奋,因为有时iframe内容会非常大,它可能会占用一些内存和时间来制作用于还原的嵌入式文档的另一个副本。我很想听听关于如何处理这个问题的一些其他想法。提前致谢。

      修改

      iframe.htm的以下替换将解决IE的问题。我将使用jQuery重写它,并添加一些逻辑来恢复滚动位置。我曾希望有更优雅的东西,但这是在做这项工作。

      <!DOCTYPE html>
      <html>
      <head>
          <title>IE iframe bug</title>
          <script type="text/javascript">
              function myTrace(msg) {
                  var t = document.createTextNode(msg);
                  var b = document.createElement('br');
                  var d = document.getElementById("trace_output")
                  d.appendChild(t);
                  d.appendChild(b); 
              }
              var make_backup ="false";
              function submitListing() {
                  make_backup = "true";
                  myTrace('submitListing()');
                  var doc = document.getElementById("output_iframe").contentWindow.document;
                  var d = new Date;
                  doc.location.replace('report.htm?invalidateCache=' + d.getTime());
                  //myTrace('submitListing(): out');
              }
              function iframe_load() {
                  myTrace("iframe loaded, is_cached=" + document.getElementById("is_cached").value);
                  if (make_backup == "true") { // only when submitting
                      var htm, doc;
                      make_backup = "false"
                      doc = document.getElementById("output_iframe").contentWindow.document;
                      htm = doc.documentElement.innerHTML;
                      document.getElementById("iframe_backup").value = htmlEscape(htm);
                  }
              }
              function bodyLoaded() {
                  var is_cached = document.getElementById("is_cached");
                  if (is_cached.value == "false") {  // initial page load 
                      is_cached.value = "true";
                  }
                  else { // BACK or FORWARD,  restore DOM where needed 
                      var htm;
                      htm = htmlUnescape(document.getElementById("iframe_backup").value);
                      var doc;
                      doc = document.getElementById("output_iframe").contentWindow.document;
                      doc.open();
                      doc.writeln(htm);
                      doc.close();
                  }
              }
              function htmlEscape(str) {
                  return String(str).replace(/&/g, '&amp;').replace(/"/g, '&quot;')
                  .replace(/'/g, '&#39;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
              }
              function htmlUnescape(str) {
                  return String(str).replace(/&amp;/g,'&').replace(/&quot;/g,'"')
                  .replace(/&#39;/g,"'").replace(/&lt;/g,'<').replace(/&gt;/g,'>');
              }
          </script>
      </head>
      <body onload="bodyLoaded();">
          <div id="trace_output" style="height: 300px; border-width:1; background-color: Silver"><br></div>
          <input id="is_cached" type="hidden" value="false">
          <input id="iframe_backup" type="hidden">
          <input type="button" onclick="submitListing();" value="Run"><br>
          <iframe id="output_iframe" src="" onload="iframe_load();"></iframe>
      </body>
      </html>
      

      编辑2

      用jQuery重写:

      <!DOCTYPE html>
      <html>
      <head>
          <title>IE iframe workaround2</title>
          <script type="text/javascript" src="Scripts/jquery-1.7.1.js"></script>
          <script type="text/javascript">
      
              var make_backup = "false";
      
              $(document).ready(function () {
                  myTrace('document ready()');
                  var is_cached = $("#is_cached");
                  if (is_cached.val() == "false") {  // initial page load 
                      is_cached.val("true");
                  }
                  else { // BACK or FORWARD,  restore DOM where needed 
                      if ($.browser.msie) { // IE loses iframe content; restore 
                          var htm = htmlUnescape($("#iframe_backup").val());
                          var doc = $("#output_iframe")[0].contentWindow.document;
                          doc.open();
                          doc.writeln(htm);
                          doc.close();
                          myTrace('iframe contents restored');
                      }
                  }
                  $('#output_iframe').load(function () {
                      myTrace("iframe_loaded");
                      if (make_backup == "true") { // only when submitting
                          make_backup = "false"
                          if ($.browser.msie) {
                              var doc = $("#output_iframe")[0].contentWindow.document;
                              var htm = doc.documentElement.innerHTML;
                              $("#iframe_backup").val(htmlEscape(htm));
                              myTrace('iframe contents backed up');
                          }
                      }
                  });
                  $('#submit_listing').click(function () {
                      make_backup = "true";
                      myTrace('submitListing()');
                      var doc = $("#output_iframe")[0].contentWindow.document;
                      var d = new Date;
                      doc.location.replace('report.htm?invalidateCache='+d.getTime());
                  });
              });
              function myTrace(msg) {
                  $('#trace_output').append(msg + '<br>'); 
              }
              function htmlEscape(str) {
                  return String(str).replace(/&/g, '&amp;').replace(/"/g, '&quot;')
                  .replace(/'/g, '&#39;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
              }
              function htmlUnescape(str) {
                  return String(str).replace(/&amp;/g,'&').replace(/&quot;/g,'"')
                  .replace(/&#39;/g,"'").replace(/&lt;/g,'<').replace(/&gt;/g,'>');
              }
          </script>
      </head>
      <body>
          <div id="trace_output" 
               style="height: 300px; border-width:1; background-color: Silver">
               <br></div>
          <div style="display: block;">
              <input id="is_cached" type="text" value="false">
              <input id="iframe_backup" type="text" type="hidden"></div>
          <input id="submit_listing" type="button" value="Run"><br>
          <iframe id="output_iframe" src=""></iframe>
      </body>
      </html>
      

0 个答案:

没有答案