浏览器环境概述
JavaScript 是浏览器的内置脚本语言。也就是说,浏览器内置了 JavaScript 引擎,并且提供各种接口,让 JavaScript 脚本可以控制浏览器的各种功能。一旦网页内嵌了 JavaScript 脚本,浏览器加载网页,就会去执行脚本,从而达到操作浏览器的目的,实现网页的各种动态效果。
本章开始介绍浏览器提供的各种 JavaScript 接口。首先,介绍 JavaScript 代码嵌入网页的方法。
代码嵌入网页的方法
网页中嵌入 JavaScript 代码,主要有四种方法。
<script>
元素直接嵌入代码。<script>
标签加载外部脚本- 事件属性
- URL 协议
script 元素嵌入代码
<script>
元素内部可以直接写入 JavaScript 代码。
<script>
var x = 1 + 5;
console.log(x);
</script>
<script>
标签有一个type
属性,用来指定脚本类型。对 JavaScript 脚本来说,type
属性可以设为两种值。
text/javascript
:这是默认值,也是历史上一贯设定的值。如果你省略type
属性,默认就是这个值。对于老式浏览器,设为这个值比较好。application/javascript
:对于较新的浏览器,建议设为这个值。
<script type="application/javascript">
console.log('Hello World');
</script>
由于<script>
标签默认就是 JavaScript 代码。所以,嵌入 JavaScript 脚本时,type
属性可以省略。
如果type
属性的值,浏览器不认识,那么它不会执行其中的代码。利用这一点,可以在<script>
标签之中嵌入任意的文本内容,只要加上一个浏览器不认识的type
属性即可。
<script id="mydata" type="x-custom-data">
console.log('Hello World');
</script>
上面的代码, 浏览器不会执行,也不会显示它的内容,因为不认识它的type
属性。但是,这个<script>
节点依然存在于 DOM 之中,可以使用<script>
节点的text
属性读出它的内容。
document.getElementById('mydata').text
// console.log('Hello World');
script 元素加载外部脚本
<script>
标签也可以指定加载外部的脚本文件。
<script src="https://www.example.com/script.js"></script>
如果脚本文件使用了非英语字符,还应该注明字符的编码。
<script charset="utf-8" src="https://www.example.com/script.js"></script>
所加载的脚本必须是纯的 JavaScript 代码,不能有HTML
代码和<script>
标签。
加载外部脚本和直接添加代码块,这两种方法不能混用。下面代码的console.log
语句直接被忽略。
<script charset="utf-8" src="example.js">
console.log('Hello World!');
</script>
为了防止攻击者篡改外部脚本,script
标签允许设置一个integrity
属性,写入该外部脚本的 Hash 签名,用来验证脚本的一致性。
<script src="/assets/application.js"
integrity="sha256-TvVUHzSfftWg1rcfL6TIJ0XKEGrgLyEq6lEpcmrG9qs=">
</script>
上面代码中,script
标签有一个integrity
属性,指定了外部脚本/assets/application.js
的 SHA256 签名。一旦有人改了这个脚本,导致 SHA256 签名不匹配,浏览器就会拒绝加载。
事件属性
网页元素的事件属性(比如onclick
和onmouseover
),可以写入 JavaScript 代码。当指定事件发生时,就会调用这些代码。
<button id="myBtn" onclick="console.log(this.id)">点击</button>
上面的事件属性代码只有一个语句。如果有多个语句,使用分号分隔即可。
URL 协议
URL 支持javascript:
协议,即在 URL 的位置写入代码,使用这个 URL 的时候就会执行 JavaScript 代码。
<a href="javascript:console.log('Hello')">点击</a>
浏览器的地址栏也可以执行javascript:
协议。将javascript:console.log('Hello')
放入地址栏,按回车键也会执行这段代码。
如果 JavaScript 代码返回一个字符串,浏览器就会新建一个文档,展示这个字符串的内容,原有文档的内容都会消失。
<a href="javascript: new Date().toLocaleTimeString();">点击</a>
上面代码中,用户点击链接以后,会打开一个新文档,里面有当前时间。
如果返回的不是字符串,那么浏览器不会新建文档,也不会跳转。
<a href="javascript: console.log(new Date().toLocaleTimeString())">点击</a>
上面代码中,用户点击链接后,网页不 会跳转,只会在控制台显示当前时间。
javascript:
协议的常见用途是书签脚本 Bookmarklet。由于浏览器的书签保存的是一个网址,所以javascript:
网址也可以保存在里面,用户选择这个书签的时候,就会在当前页面执行这个脚本。为了防止书签替换掉当前文档,可以在脚本前加上void
,或者在脚本最后加上void 0
。
<a href="javascript: void new Date().toLocaleTimeString();">点击</a>
<a href="javascript: new Date().toLocaleTimeString();void 0;">点击</a>
上面这两种写法,点击链接后,执行代码都不会网页跳转。