HTML中的JavaScript
1. <script>元素
通过<script>元素将JavaScript源代码插入到HTML文档中。该元素由网景公司创建,以下为几个常用属性:
属性 | 描述 |
---|---|
src | 可选。外部脚本文件url,指向JavaScript代码文件 |
type | 可选。表示代码块中脚本语言的内容类型,该值始终是"text/javascript" |
async | 可选。立即下载脚本,但不阻止其他页面动作,即异步加载。只对外部脚本文件有效 |
defer | 可选。脚本延迟到文档完全被解析和显示后执行,只对外部脚本文件有效 |
intergrity | 可选。确保内容分发网络(CDN)不会提供恶意内容 |
1.1 行内嵌入JavaScript代码
要在行内嵌入JavaScript代码,只需要将代码放在<script>元素中即可
<script>
console.log("hello world");
</script>
包含在<script>元素中的JS代码会被从上到下解释执行,在<script>元素中的代码被执行完成之前,页面的其余内容不会被加载和显示。
需要注意代码中不能出现字符串’</script>’,因为浏览器执行行内脚本的方式决定了会将其看作是<script>元素的闭合标签。如果要用的话加上转义字符,即’<\/script>’。外部脚本中就不会存在该问题。
1.2 包含外部JavaScript代码
要包含外部JavaScript代码,必须使用src属性,如
<script src = 'test.js'></script>
与解释行内JavaScript代码一样,解释外部JavaScript文件时,页面其余内容不会被加载和显示(即被阻塞)。
需要注意,使用了src属性的<script>元素不应该在<script>和</script>标签中间包含其他JavaScript代码。如果在元素中写了其他代码,浏览器也只会包含外部脚本文件而忽略行内代码。
1. 3 <script>元素位置
不管是行内嵌入JS代码还是包含外部JS文件,浏览器都会按照<script>在页面中出现的顺序依次解释它们,前提是该<script>元素没有使用defer和async属性。即第二个<script>元素的JS代码必须在第一个<script>元素的JS代码解释执行完毕后才能执行。
现在的Web应用程序常常将<script>标签放在<body>元素中的页面内容后面(如下所示),这样就会在处理JS代码之前完全渲染页面,用户体验更好。
<!DOCTYPE html>
<html>
<head>
<title>test</title>
</head>
<body>
<div>some words</div>
<script>
console.log("hello worlds");
</script>
</body>
</html>
1.4 defer与async属性
-
defer属性:推迟执行脚本
<script>元素拥有一个defer属性,表示脚本在执行的时候不会改变页面结构。也就是说,脚本会被延迟到整个页面都解析完毕后再运行(告诉浏览器立即下载JS代码,但是延迟执行)。只对外部脚本文件有效,对于行内脚本会直接忽略其defer属性。
<script defer src = 'test.js'></script>
使用defer属性的<script>元素包含的代码会在浏览器解析到</html>之后执行。各个通过defer属性推迟执行的脚本之间按照次序执行,即第一个推迟的脚本会在第二个推迟的脚本之前执行,并且二者都会在DOMContentLoaded事件之前执行(但是实际中不一定会这样,因此建议只包含一个这样的脚本)
-
async属性:异步执行脚本,HTML5中定义
与defer属性类似,都只适用于外部脚本。区别在于,标记为async的脚本不能保证按照他们出现的次序执行,即第二个脚本可能先于第一个脚本执行。async属性告诉浏览器不必等异步脚本下载和执行完再加载页面,也不必等该异步脚本下载和执行完后再加载其他脚本,即异步加载。
异步脚本保证在页面load事件前执行,但可能在DOMContentLoaded事件之前或之后。
1.5 动态加载脚本
因为JavaScript可以使用DOM API来访问页面内容,因此可以通过向DOM中动态添加script元素来加载指定脚本。只需创建一个<script>元素并将其添加到DOM树中即可。
let script = document.createElement('script');
script.src = 'test.js';
document.head.appendChild(script);
以这种方式创建的<script>元素默认以异步方式加载(相当于添加了async属性)。但是可能有的浏览器不支持async属性(因为async属性是HTML5中定义的新属性),因此可以将该<script>元素明确设置为同步加载
let script = document.createElement('script');
script.src = 'test.js';
script.async = false;
document.head.appendChild(script);
以这种方式获取的资源对浏览器预加载器不可见,因此可能会严重影响性能。因此需要让预加载器知道这些动态请求文件的存在,可以在<head>元素中显式声明
<link rel="preload" href="test.js">
2. 推荐使用外部脚本文件
对比在HTML中直接嵌入JavaScript代码和包含外部JavaScript文件,通常认为尽可能将JavaScript代码放在外部文件中。
-
可维护性
如果JS代码分散到很多HTML页面中将会导致维护困难。而用一个目录保存所有JavaScript文件,则更容易维护。开发者可以独立于HTML页面来编辑JS代码
-
缓存
浏览器会缓存所有外部链接的JavaScript文件,这意味着如果两个HTML页面用到了同一个JavaScript文件,该文件只需要被下载一次。这会使得页面加载速度更块
3. <noscript>元素
<script>元素用于指定浏览器不支持JavaScript脚本时显示的内容。如果浏览器支持并启用JavaScript脚本,那么<noscript>元素中的任何内容都不会被渲染显示。当浏览器不支持JS脚本或者禁用JS脚本,就渲染显示<noscript>元素中的内容
<noscript>
<p>如果不支持JavaScript就显示这段话</p>
</noscript>