一, JS程序执行的两个阶段
第一阶段(载入阶段)
载入文档内容,并根据他们在文档里出现的顺序从上往下依次执行引入j的s代码(包括内联与外部脚本),当html解析器遇到<script>元素时,默认必须先执行脚本,然后再恢复文档的解析和渲染,该阶段通常只持续1-2s;
第二阶段(事件驱动)
是事件驱动的异步处理阶段,根据用户的操作来进行异步响应,即事件处理函数。该阶段的第一个事件是load事件,表示文档已经完全载入,可以操作,该阶段在文档载入完成,只要浏览器显示文档,就会一直持续下去,可能会长时间处于不活动的状态;
二,同步,异步,延迟脚本
脚本执行在默认情况下是同步和阻塞的,比如当html解析器在解析时遇见外部脚本,此时,程序的运行流程会先阻塞html页面的渲染,去执行js代码,此时,文档的文本内容虽然已经载入,但是未被浏览器引擎解析问dom树,这意味脚本后面的文档部分在下载和执行脚本之前,在dom树上是不存在的,浏览器里你是看不到的。
defer 和 async 属性 会暗示浏览器链接进来的脚本不会使用 document.write(),也不会生成文档内容,因此浏览器可以在下载脚本时继续解析和渲染文档。
同步(defer)
定义方式 <script defer src="deferr.js"></script>
执行流程 浏览器会延时脚本的执行,直到文档的载入和解析完成,并可以操作后才开始执行脚本,
该脚本会按照他们在文档里出现的顺序执行。
经常用来定义函数和注册后面使用的注册事件处理程序
可以遍历和操作文档树, 可以看到自己的 js 元素 和她们之前的文档
浏览器支持 所有的 IE,其他待定
异步(async )
定义方式 <script async src="deferr.js"></script>
执行流程 浏览器会尽快执行脚本,不会在下载脚本时阻塞文档的解析,
可能会无序执行
禁止使用 document.write() 方法
可以看到自己的 js 元素,和他之前的所有的文档元素,
可能或干脆不可能访问其他的文档内容
若两个属性同时存在,则async优先
若两个属性都不存在时,他会将这些 js 元素加载到文档中,然后同步执行这些脚本,并且在脚本下载和执行时解析器就会暂停,这样脚本就可以吧 document.write()来把文本插入到输入流中,解析器回复时这些文本就会成为文档的一部分,
三,客户端JS时间线
readyState 属性返回当前文档的状态
1.最初 web 浏览器还未开始创建 document 对象,未开始解析web页面 ,此时 document.readyState == “uninitialized“ ---还未开始载入;
2.当 web 浏览器开始创建 document 对象,并开始解析 web 页面, 解析 html 元素和她们的文本内容后添加的 element 对象和 text 节点到文件,解析 js 元素, 此时 document.readyState == “loading “ ---载入中;
3. 当文档解析完成时, 此时 document.readyState == “interactive “ ---已加载,文档与用户可以开始交互;
4.文档解析完成后,可能会等待其他内容载入,比如图片之类的,放所有这些内容都载入完成,所有的异步脚本完成载入和执行, 此时 document.readyState == “complete “ --载入完成;