有时我们需要在javascript脚本中创建js文件,那么在javascript脚本中创建的js文件又是如何执行的呢?和我们直接在HTML页面种写一个script标签的效果是一样的吗?(关于页面script脚本的执行可看webkit技术内幕读书笔记 (四)中的资源加载一节)这是今天我要研究的对象。
为了测试,我分别创建了一个html页面,和两个js文件,具体如下
index.html
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <h2>h2</h2> <script> var script1 = document.createElement("script"); script1.src = "http://127.0.0.1:8081/index.js"; document.body.appendChild(script1); var script2 = document.createElement("script"); script2.src = "index2.js"; document.body.appendChild(script2); console.log("script ok"); </script> <h3>h3</h3> </body> </html>
index.js
var http = require("http"); http.createServer(function(req,res){ }).listen(8081);
index2.js
console.log("index2.js");
其中index.js的作用是,拖住浏览器的执行,始终不给浏览器响应,以上代码的执行效果如下图
可以看到它并没有按照我编写代码的顺序来执行,也就是说通过这种方式创建的script脚本是异步执行的,准确的说是appendChild方法导致script脚本是异步的,因为如果只是去创建script文件,浏览器是不会去加载js文件的。如下我将appendChild注释掉
var script1 = document.createElement("script"); script1.src = "http://127.0.0.1:8081/index.js"; // document.body.appendChild(script1); var script2 = document.createElement("script"); script2.src = "index2.js"; // document.body.appendChild(script2); console.log("script ok");
效果如下图
可以看到并没有发送下载js文件请求,对于appendChild为什么要弄成异步的,暂时不得而知。
我们再来看看innerHTML的方式添加script脚本
index.html
<h2>h2</h2> <script> document.body.innerHTML += "<script src='http://127.0.0.1:8081/index.js'><\/script>"; document.body.innerHTML += "<script src='index2.js'><\/script>"; </script> <h3>h3</h3>
经过测试,发现以上两个js文件并没有被执行,甚至连下载的请求都没有,如下图
难道是因为innerHTML只是把内容当成HTML来解析?这个目前还不得而知,只是我奇怪的是,innerHTML对style标签又会进行解析,效果如下
代码为
<h2>h2</h2> <script> document.body.innerHTML += "<script src='http://127.0.0.1:8081/index.js'><\/script>"; document.body.innerHTML += "<style>h2{color:red}<\/style>"; </script> <h3>h3</h3>
然后我再想,难道是不能写外部脚本?于是我将代码换成如下
<h2>h2</h2> <script> document.body.innerHTML += "<script src='http://127.0.0.1:8081/index.js'><\/script>"; document.body.innerHTML += "<script>alert('script')<\/script>"; </script> <h3>h3</h3>
其结果依然没有被执行,如图
听网上说“script标签中的脚本仅在浏览器第一次加载页面时对其进行解析并执行”,如果按照这样说的话,那么为什么appendChild却可以?郁闷
推荐阅读:
IE 和 Firefox 可以通过特定方法使 innerHTML 方法载入的 SCRIPT 标签中的 JavaScript 代码在页面加载后也可以执行
看看document.write是如何执行的
代码如下
<h2>h2</h2> <script> document.write("<script src='http://127.0.0.1:8081/index.js'><\/script>"); document.write("<script src='index2.js'><\/script>"); </script> <h3>h3</h3>
执行后,结果代码被堵塞了,如下图
通过document.write的方式来加载script和直接在页面中写script标签的执行过程基本相同。