为什么替换iframe中的标记会导致添加其他标记?

时间:2015-01-09 03:37:08

标签: javascript html dom iframe

我遇到了一个我无法找到解释的有趣问题。使用<body>替换iframe(同源)中的iframe.document.body.outerHTML = content;标记时,会向iframe添加一个额外的空<head>标记。这种行为在Chrome和Firefox中都是相同的(我还没有测试过Safari或IE。)以下示例显示了问题,只需检查iframe以查看添加的<head>标记。

http://jsfiddle.net/8huj4fxs/

<!doctype html>
<html>
  <head>
    <title>iframe problem</title>
  </head>
  <body>
    <iframe id="iframe"></iframe>

    <script type="text/javascript">
      var html = '';
      html += '<!doctype html>';
      html += '<html>';
      html += '<head><style type="text/css">h1 { color: red; }</style></head>';
      html += '<body><h1>Title</h1></body>';
      html += '</html>';

      var iframe = document.getElementById('iframe').contentWindow.document;
      iframe.open();
      iframe.write(html);
      iframe.close();

      for(var i = 0; i < 5; i++) {
        content = '<body><h1>Title '+ i +'</h1></body>';

        document.getElementById('iframe').contentWindow.document.body.outerHTML = content;
      }
    </script>
  </body>
</html>

1 个答案:

答案 0 :(得分:4)

我会把这个备份,至少是为了进一步讨论,因为我认为我的初步推理可能是正确的。我认为在3的16.1中引用的 head元素指针在这种情况下可能总是为null,从而导致添加<head>元素。

原始答案

这似乎是一个有趣的研究问题......如果我正确地解释了规范,这就是正在发生的事情:

tl; dr:在解析上下文为<html>(父级为<body>)的片段时,如果片段不包含{{1} },自动包含一个空的。

相关规格:

  1. outerHTML
  2. Parsing HTML fragments
  3. Reset the insertion mode appropriately
  4. Before Head insertion mode
  5. 根据outerHTML规范,当您设置此属性时,您将在片段中启动浏览器解析。解析片段可以传递上下文元素。在outerHTML的情况下,上下文被设置为具有其outerHTML集的元素的父元素,在这种情况下,它是<head>的{​​{1}}元素的父元素,其{{ 1}}元素。

    在解析输入时,在您的情况<body>中,片段解析器首先创建一个新文档,并将<iframe>元素作为根元素附加到它。然后,解析器的插入模式获得set according to the context。上下文是<html>元素,因此根据3的步骤16.1,插入模式在head'之前设置为'。然后根据2的步骤6,使用您的outerHTML输入运行解析器。它遇到的第一件事是'<body><h1>Title '+ i +'</h1></body>'标记,根据4表示将<html>标记插入到文档中,然后继续解析其余输入。

    完成后,根据2,将返回根节点的所有子节点,除了您的输入外,还包含一个空的<html>标记,并插入到文档中代替<body>更改了<head>的{​​{1}}元素。

    希望这有帮助!