浏览器是如何执行javascript的?

x_hola
  • 666

本来看到文章说javascript放页面哪里都可以,只是为了保证用户体验最好放后面,后来,发现有些javascript必须放html后面。比如


<input id="file" type="file" />
  <img id="preview" />

<script>
var file = document.getElementById('file');
var preview = document.getElementById('preview');

file.addEventListener('change', function() {  
  preview.src = URL.createObjectURL(this.files[0]);
}, false);
</script>

否则不能执行。

那浏览器是如何运行javascript的呢?有人说先预执行,在正式执行什么的。可是现在发现有些情况必须放到html后面,就搞不清了。

请问,javascript与html是如何在浏览器中执行的?谢谢

回复
阅读 8.5k
7 个回答
ryerh
  • 92

在《高性能JavaScript程序设计》和《WebKit技术内幕》中有比较详细的描述。

简要摘录一段《WebKit技术内幕》的内容:

  1. 当用户输入 URL 之后,WebKit 调用资源加载器下载 HTML 网页

  2. 网页交给 HTML 解释器转换成 Token

  3. 解释器根据 Token 创建节点(Node),生成 DOM 树

  4. 如果第 3 步创建的节点是一个 script 节点,就调用 JavaScript 引擎解释并执行

  5. 执行完 JavaScript 继续完成 DOM 树的创建

  6. 如果第 3 步创建的节点是其他资源,比如 CSS、图片、Web Fonts、视频、音频等等,就调用资源加载器异步加载它们,不会影响 DOM 树的创建;只有当节点是 script 时,会阻塞 DOM 树的创建

现在来回答你的疑问:

  1. Javascript 与 HTML 在浏览器中执行的流程,请自行理解上面的摘录内容

  2. JavaScript 放在页面底部是为了防止解析 JavaScript 时阻塞 DOM 树的创建

  3. 如果 JavaScript 的代码不涉及 DOM 访问和修改,放在哪里执行都没问题;但是如果 JavaScript 代码需要执行 getElementById 这种 DOM 操作,就一定要放在页面最底部,这样当解释器执行 JavaScript 时,DOM 树已经完成创建了,不存在 JavaScript 获取不到 DOM 元素的问题

  4. onLoad 和 onDOMContentLoaded 事件的重要性,请自行查阅资料吧,或者另提一个问题。

一句话: 从上至下执行

如果你放在头部,浏览器解析到js时,下面的html仍未加载,此时访问dom自然就报错了。

现在script上设置defer或者async属性,就可以任何位置随便放了。

不是js不执行,只是在js执行的时候,html元素还没有渲染,js是获取不到相应的元素的。既然获取不到元素,自然事件也就没有绑定上

了解一下DOM Ready的原理及其实现方式,你就明白了。。。

wszbdyyy
  • 1
新手上路,请多包涵

js默认是以阻塞的方式加载的,js执行之前不能操作未加载完成的DOM,不然会报错,这也是为什么推荐把js放在页面底部。

Manix
  • 5
新手上路,请多包涵

尽量放在底部,如果放在其它位置尽量检查一下是否有onload事件,加载完页面再执行js,避免js中存在错误时影响文档流加载。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏