在 HTML 中使用 JavaScript

1、网页中嵌入JavaScript脚本

JavaScript 被定义为嵌入式 Web 脚本语言。在 HTML 页面中嵌入 JavaScript 脚本,需要用 <srcipt> 标签。用户可以在 <script> 标签总直接编写 JavaScript 代码,或者单独编写 JavaScript 文件,让后通过 <script> 标签导入。

1、编写脚本

使用 <script> 标签又两种方式:直接在页面中嵌入 JavaScript 代码和包含外部 JavaScript 文件。

包含在 <script> 标签内的 JavaScript 代码在浏览器总按照从上至下的顺序依次解释。

所有 <script> 标签都会按照他们在 HTML 中出现的先后顺序依次被解析。

HTML 为 <script> 定义了几个属性:

(1)async:可选。表示应该立即下载脚本,但不妨碍页面中其他操作。该功能只对外部 JavaScript 文件有效。

如果给一个外部引入的js文件设置了这个属性,那页面在解析代码的时候遇到这个<script>的时候,一边下载该脚本文件,一边异步加载页面其他内容。

(2)defer:可选。表示脚本可以延迟到整个页面完全被解析和显示之后再执行。该属性只对外部 JavaScript 文件有效。

(3)src可选。表示包含要执行代码的外部文件。

(4)type:可选。表示编写代码使用的脚本语言的内容类型,目前在客户端,type 属性值一般使用 text/javascript。不过这个属性并不是必需的,如果没有指定这个属性,则其默认值仍为text/javascript。

2、脚本标签位置

所有 <script> 标签都会按照它们在 HTML 中出现的先后顺序被解析。在不适用 defer 和 async 属性的情况下,只有在解析完前面的 <script> 标签中的代码后,才会开始解析后面的 <script> 标签中的代码。

在默认情况下,所有 <script> 标签都应该放在页面的头部 <head> 标签中。这样就可以把所有外部文件(包括CSS文件和JavaScript文件)的引用都放在相同的地方。但是,在文档的 <head> 标签中包含所有 JavaScript 文件,意味着必须等到全部JavaScript 代码都被下载、解析和执行完以后,才能开始呈现页面的内容。如果页面需要很多JavaScript代码,这样无疑会导致浏览器在呈现页面时出现明显的延迟,而延迟期间的浏览器窗口中将是一片空白。

为了避免上述操作带来的延迟问题,现在 Web 应用程序一般会把所有的 JavaScript 引用放到 <body> 标签中页面内容的后面,这样在解析包含的 JavaScript代码之前,页面的内容完全呈现在浏览器中,同时会感到打开网页的速度加快了。

2、执行 JavaScript 程序

JavaScript 解析过程包括两个阶段:预处理(也称预编译)和执行。在编译期,JavaScript 解析器将完成对 JavaScript 代码的预处理操作,把 JavaScript 代码转换成字节码;在执行期,JavaScript 解析器把字节码生成二进制机械码,并按顺序执行,完成程序设计的任务。

1、执行过程

HTML 文档在浏览器中的解析过程是:按照文档流从上到下逐步解析页面结构和信息。JavaScript 代码作为嵌入的脚本应该也算做 HTML 文档的组成部分,所以 JavaScript 代码在装载时的执行顺序也是根据 <script> 标签出现的顺序来确定。

2、预编译

当 JavaScript 引擎解析脚本时候,他会在与编译期对所有声明的变量和函数预先进行处理。当 JavaScript 解析器执行下面脚本时不会报错。

alert(a);    //返回值 undefined
var a = 1;
alert(a);    //返回值 1

由于变量声明是在预编译期被处理的,在执行期间对于所有的代码来说,都是可见的,但是执行上面代码,提示的值是 undefined 而不是 1。因为变量初始化过程发生在执行期,而不是预编译期。在执行期,JavaScript 解析器是按照代码先后顺序进行解析的,如果在前面代码行中没有为变量赋值,则 JavaScript 解析器会使用默认值 undefined 。由于第二行中为变量 a 赋值了,所以在第三行代码中会提示变量 a 的值为 1,而不是 undefined。

fun();    //调用函数,返回值1
function fun(){
    alert(1);
}

函数声明前调用函数也是合法的,并能够正确解析,所以返回值是 1。但如果是下面这种方式则 JavaScript 解释器会报错。

fun();    //调用函数,返回语法错误
var fun = function(){
    alert(1);
}

上面的这个例子中定义的函数仅作为值赋值给变量 fun 。在预编译期,JavaScript 解释器只能够为声明变量 fun 进行处理,而对于变量 fun 的值,只能等到执行期时按照顺序进行赋值,自然就会出现语法错误,提示找不到对象 fun。

总结:声明变量和函数可以在文档的任意位置,但是良好的习惯应该是在所有 JavaScript 代码之前声明全局变量和函数,并对变量进行初始化赋值。在函数内部也是先声明变量,后引用。

3、代码块

JavaScript 解释器在执行脚本时,是按块来执行的。浏览器在解析 HTML 文档流时,如果遇到一个<script> 标签,则 JavaScript 解释器会等到这个代码块都加载完后,先对代码块进行预编译,然后再执行。执行完毕后,浏览器会继续解析下面的HTML 文档流,同时 JavaScript 解释器也准备好处理下个代码块。

如果在一个 JavaScript 块中调用后面块中声明的变量或函数就会提示语法错误。比如:

<script>    //JavaScript 代码块 1
    alert(a);
    fun();
</script>
<script>    //JavaScript 代码块 2
    var a = 1;
    function fun(){
        alert(1);
    }
</script>

但是如果上面两个代码块的前后顺序颠倒以下,就不会报错,因为虽然 JavaScipt 是按块执行的,但是不同块都属于同一个全局作用域,块之间的变量和函数是可以共享的。

4、响应事件

JavaScript 响应操作是通过事件驱动的模式来实现的,由于事件发生的不确定性,所以JavaScript事件响应的顺序也是不确定的。上面的例子说两个代码块之间的先后顺序如果不对会出现问题,但是可以不用改变代码块的顺序,只需要将代码块 2 中的变量和函数的调用代码放到页面初始化函数中,就不会出现错误了。

<script>    //JavaScript 代码块 1
    window.onload = functiong(){    //页面初始化事件处理函数
        alert(a);
        fun();
    }
</script>
<script>    //JavaScript 代码块 2
    var a = 1;
    function fun(){
        alert(1);
    }
</script>

onload 事件只有在文档加载完毕才会响应。因此为了运行安全,一般都设计在页面初始化完毕之后才允许 JavasScript 代码执行,这样就可以避免因为代码加载延迟对 JavaScript 执行的影响。同时也避开了 HIML 文档流对于 JavaScript 执行的限制。

5、设置动态脚本

使用 document 对象的 write() 方法输出 JavaScript 脚本时,这些动态输出的脚本的执行顺序也不同。JavaScript脚本输出的代码字符串会在输出后马上被执行。

document. write('<script type="text/javascript">');
document. write('f(););
document. write(' function f(){');
document, write(' alert(1);');
document. write('});
document. write('<\/script>1);

运行代码,document.write() 方法先把输出的 JavaScript 字符串写入到标签所在的文档位置,浏览器在解析完document.write() 所在文档内容后,继续解析 document.write() 输出的内容,然后才按顺序解析后面的HTML文档。

使用 document.write() 方法输的 JavaScript 字符串必须放在同时被输出的 <script> 标签中,否则 JavaScript 解释器因为不能识别这些合法的 JavaScript 代码,而作为普通的字符串显示在页面文档中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值