document.write 的惊人行为

Surprising behavior of document.write

在我的页面上,我正在使用 document.write 编写外部 JS 和 iframe,如下所示

document.write("<sc" + "ript src=\"http://d2hzts1b0z7hqh.cloudfront.net/arb.js\"></script>");
document.write("<iframe id='mytestframe'></iframe>");
document.close();
var frame = document.getElementById("mytestframe");
console.log(frame);

最后一个console.log语句打印的frame值是'null'。但是如果我注释掉第一行 document.write("<sc" + "ript src=\"http://d2hzts1b0z7hqh.cloudfront.net/arb.js\"></sc" + "ript>"); 日志语句会打印一个节点实例。

谁能解释一下这种令人惊讶的行为背后的原因。

您可以使用 JSFiddle here

您调用 getElementById 的时间过早,请延迟它直到加载事件发生,或者将其放在调用 [=24= 的脚本元素下方的另一个脚本元素中].

以下对我来说很好用:

document.write('Hello World');
document.write('<script src="http://d2hzts1b0z7hqh.cloudfront.net/arb.js"><\/script>');
document.write('<iframe id="mytestframe"><\/iframe>');
document.close();

// Delay looking for iframe until page is loaded
window.onload = function() {
  var frame = document.getElementById("mytestframe");
  console.log(frame);
};

请注意,您需要在脚本元素内的所有结束标记中引用“/”,因此 <\/ 所有这些(例如 <\/iframe>),而不仅仅是 <\/script>

这是我的理论: 当你添加带有 src 的 Script 标签时,浏览器会先加载 js 文件,然后继续解析后面的 HTML 标签。否则,它将立即解析它们。 这是我的测试代码。仅在 Firefox 上测试过。 HTML 文件 t1.htm:

<html >
<head>

</head>
<body >
    <script >
        console.log("start");
        document.write("Hello World");
        document.write("<style src='t1.css' ><\/style>");//external css file, works fine
        document.write("<input id='ibefore' />");//element added before external js file, works
        document.write('<script src=\"\"><\/script>');//with a src, null
        document.write('<script ><\/script>');//without a valid src, works
        document.write("<img src='t1.jpg' ><\/img>");//external img, works
        document.write('<script src="http://d2hzts1b0z7hqh.cloudfront.net/arb.js"  defer><\/script>');//defer, works
        document.write('<script src="http://d2hzts1b0z7hqh.cloudfront.net/arb.js" async><\/script>');//async works
        console.log("before write script");
        document.write("<script src='t1.js' ><\/script>");//external js, be load and executed after this script tag
        console.log("after write script");
        document.write("<iframe id='mytestframe'>test</iframe>");//add the iframe
        console.log("after write iframe");
        document.close();
        console.log("before get iframe");
        var frame = document.getElementById("mytestframe");
        var ib = document.getElementById('ibefore');
        console.log(frame);
        console.log('input ibefore');
        console.log(ib);
        console.log('end of script');
    </script>
    <script>
        console.log('after script page.');
        console.log(document.getElementById("mytestframe"));
    </script>
    <input type="button" value="call"  />
    <script>
        console.log('End of source page.');
    </script>
</body>
</html>

外部js文件t1.js:

console.log("in writed script");
console.log(document.getElementById("mytestframe"));