一个JavaScript的小问题

本来要在网页里写这样一段测试代码:

<script>
var canvas=document.getElementById("display");
var cxt=canvas.getContext("2d");
</script>
<canvas id="display"></canvas>
<button onclick="alert(typeof(cxt))"/>test</button>

结果一直给我报错,弄了我老半天。这才几行代码啊。

后来查到的解决办法是,把脚本放在页面元素后面,也即:

<canvas id="display"></canvas>
<button onclick="alert(typeof(cxt))"/>test</button>
<script>
var canvas=document.getElementById("display");
var cxt=canvas.getContext("2d");
</script>

这样做的解释是:“浏览器在执行JavaScript代码时,不能同时做其它事情,即<script>每次出现都会让页面等待脚本的解析和执行(不论JavaScript是内嵌的还是外链的),JavaScript代码执行完成后,才继续渲染页面。这个也就是JavaScript的阻塞特性。引用

第一段代码中执行getElementById()时,canvas元素还未渲染,当然获取到的对象只能为空。结论是:

1.为页面添加的脚本最好放在页面元素的后面(不论是内嵌脚本还是外链脚本),因为还未渲染的页面元素是无法被脚本所访问到的。HTML文档是从上到下顺序渲染的,而且每次遇到<script>都会产生阻塞效应。而<head>里面的脚本是会最先被执行,此时页面元素全部尚未渲染完毕,阻塞效应会大大影响页面的渲染速度,所以最好是将脚本放在</body>的前面,因为这时页面元素都已经渲染完毕;

2.当需要在脚本直接调用页面元素时,不要在脚本中调用处于脚本后的元素(也即未渲染的元素),或者将脚本移动到需调用的元素后(如上文的改动方式)。当然这种方式并不推荐,最好以添加响应函数的形式去调用元素。

也许是以前写MFC的时候,事件驱动的思想中毒太深,喜欢给什么页面元素都来个响应函数,所以平时还不会遇到这个问题。这次想偷懒,直接在响应函数外操作页面元素,结果反而出错了,囧。话说JavaScript的阻塞特性什么的,也太霸道了。。。

posted @ 2013-02-01 01:13  蔚_Way  阅读(192)  评论(0)    收藏  举报