0前言
javascript:协议的常见用途是书签脚本 Bookmarklet。由于浏览器的书签保存的是一个网址,所以javascript:网址也可以保存在里面,用户选择这个书签的时候,就会在当前页面执行这个脚本。为了防止书签替换掉当前文档,可以在脚本前加上void,或者在脚本最后加上void 0。
<a href="javascript: void new Date().toLocaleTimeString();">点击</a>
<a href="javascript: new Date().toLocaleTimeString();void 0;">点击</a>
以上两种方法,都可以点击链接之后,不跳转。
1.script
原理:浏览器加载 JavaScript 脚本,主要通过<script>
元素完成。正常的网页加载流程是这样的。
1.浏览器一边下载 HTML 网页,一边开始解析。也就是说,不等到下载完,就开始解析。
2.解析过程中,浏览器发现<script>
元素,就暂停解析,把网页渲染的控制权转交给 JavaScript 引擎。
3.如果<script>
标签元素引用了外部脚本,就下载该脚本再执行,否则就直接执行代码。
4.JavaScript 引擎执行完毕,控制权交还渲染引擎,恢复往下解析 HTML 网页。
如果外部脚本加载时间很长(一直无法完成下载),那么浏览器就会一直等待脚本下载完成,造成网页长时间失去响应,浏览器就会呈现“假死”状态,这被称为“阻塞效应”。
为了避免这种情况,较好的做法是将<script>
标签都放在页面底部,而不是头部。
如果某些脚本代码非常重要,一定要放在页面头部的话,最好直接将代码写入页面,而不是连接外部脚本文件,这样能缩短加载时间。
解析和执行 CSS,也会产生阻塞。
但是CSS加载不会造成阻塞。
- CSS不会阻塞DOM解析,但会阻塞DOM渲染。
- CSS会阻塞JS执行,但不会阻塞JS文件下载。
为了解决脚本文件下载阻塞网页渲染问题,有两个方法:
- 在script中加入defer属性
- 在script中加入async属性
两者都是异步加载外部js文件,不会阻塞DOM解析。
2.defer属性
在script中加入defer属性。它的作用是延迟脚本的执行,等待DOM加载生成后,再执行脚本。
<script src="a.js" defer></script>
<script src=