你有所不知的<script>元素
向html页面中插入javascript的主要方法,就是使用<script>元素。
<script>定义了下列6个属性:
- async:可选。表示应该立即下载脚本,但不应妨碍页面中的其他操作,比如下载其他资源或等待加载其他脚本。只对外部脚本文件有效。
- charset:可选。表示通过src属性指定代码的字符集。由于大多数浏览器会忽略它的值,因此这个属性很少人使用。
- defer:可选。表示脚本可以延迟到文档完全被解析和显示之后再执行。只对外部脚本文件有效。IE7及更早版本对嵌入脚本也支持这个属性。
- language:已废弃。原来用于表示编写代码使用的脚本语言。大多数浏览器会忽略这个属性,因此也就没有必要再用了。
- src:可选。表示包含要执行的代码的外部文件。
- type:可选。可以看成事language的替代属性;表示编写代码使用的脚本语言的内容类型。虽然text/javascript和text/ecmascript都已经不被推荐使用,但人们一直以来使用的都还是text/javascript。实际上,服务器在传送javascript文件时使用的MIME类型通常都是application/x-javascript,但在type中设置这个值却可能导致脚本被忽略。另外,在非IE浏览器中还可以使用以下值:application/javascript和application/ecmascript。考虑到约定成俗和最大限度的浏览器兼容性,目前type属性的值依旧是text/javascript。不过,这个属性并不是必须的,如果没有指定这个属性,则其默认值仍为text/javascript。
在使用<script>嵌入javascript代码时,记住不要再代码中的任何地方出现"</script>"字符串。例如:在浏览器中加载下面所示的代码时就会产生一个错误:
<script type="text/javascript"> function Hi() { alert("</script>"); } </script>
因为按照解析嵌入代码的规则,当浏览器遇到字符串“</script>”时,就会认为那是结束的</script>标签。而通过转义字符“\”解决这个问题。
<script type="text/javascript"> function Hi() { alert("<\/script>"); } </script>
这样写的代码浏览器可以接受,因而也就不会导致错误了。
注意:带有src属性的<script>元素不应该在其<script>和</script>标签之间再包含额外的javascript代码。如果包含了嵌入的代码,则只会下载并执行外部脚本,嵌入的代码会被忽略。
延迟脚本:defer
defer属性,用于表明脚本在执行时不会影响页面的构造。也就是说,脚本会被延迟到整个页面都解析完毕后在运行。因此,在<script>元素中设置defer属性,相当于告诉浏览器立即下载,但延迟执行。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script type="text/javascript" defer="defer" src="a.js"></script> <script type="text/javascript" defer="defer" src="b.js"></script> </head> <body> <!--内容--> </body> </html>
在这个例子中,虽然我们吧<script>元素放在了文档的<head>元素中,但其中包含的脚本将延迟到浏览器遇到</html>标签后再执行,html5规范要求脚本按照他们出现的先后顺序执行,因此第一个延迟脚本会先于第二个延迟脚本执行,而这两个脚本会先于DOMContentLoaded事件执行。在现实当中,延迟脚本并不一定会按照顺序执行,也不一定会在DOMContentLoaded事件触发前执行,因此最好只包含一个延迟脚本。
前面提到过,defer属性只适用于外部脚本文件。这点在html5中已经明确规定,因此支持html5的实现会忽略给嵌入脚本设置defer属性。延迟脚本最好还是放在页面底部。
异步脚本 :async
html5为<script>元素定义了async属性。这个属性和defer属性类似,都用于改变处理脚本的行为。同样与defer类似,async只适用于外部脚本文件,并告诉浏览器立即下载文件。但与defer不同的是,标记为async的脚本并不保证按照指定他们的先后顺序执行,例如:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script type="text/javascript" defer="defer" src="a.js"></script> <script type="text/javascript" defer="defer" src="b.js"></script> </head> <body> <!--内容--> </body> </html>
在以上代码中,第二个脚本文件可能会在第一个脚本文件之前执行。因此,确保两者之间互不依赖非常重要。指定async属性的目的是不让页面等待两个脚本下载和执行,从而异步加载页面的其他内容。为此,建议异步脚本不要在加载期间修改dom。
异步脚本一定会在页面的load事件前执行,但可能会在DOMContentLoaded事件触发之前或之后执行。支持异步脚本的浏览器有Firefox3.6,Safari5和Chrome。