在document
对象中有个write()
方法可以用于往页面写入内容。
document.write("替换内容!");
document.write("<p>这是p标签</p>"); // 浏览器会把p标签解析
目前,document.write()
有两个现象:
1、直接在文档后面追加内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<h1>这是H1</h1>
<p>这是H1</p>
</body>
</html>
<script>
document.write("替换");
</script>
💡 这是因为script
也属于标签,故也会被renderTree
进行渲染,当renderTree
渲染的时候遇到document.write()
,由于页面还没有渲染完成,所以无法写入只能在文档后面进行追加。
2、将body
里的内容全部替换,重写整个文档
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<h1>这是H1</h1>
<p>这是H1</p>
</body>
</html>
<script>
window.onload = function () {
document.write("替换");
};
</script>
💡 window.onload
在renderTree
渲染完成且资源(如img
)全部加载完成后才会触发该事件,这个时候document.write()
就会把body
内全部内容重写
这个时候就要引出「时间线」的概念啦。
时间线
:::info 浏览器开始加载页面的那一刻开始,到页面加载完毕,整个过程中按顺序发生的每件事情就叫时间线。 :::
📌 script 标签 defer 和 async 属性的区别:
defer
只加载js
脚本但是只在文档加载完毕后执行async
加载js
脚步后立即执行(不能确定执行顺序)所以这两个属性适用没有
DOM
依赖和没有先后执行顺序要求的时候。
DOMContentLoaded
和load
事件
可以看到在「时间线」中会触发两个事件:DOMContentLoaded
和load
**DOMContentLoaded**
等文档解析完成后触发,我们可以在该事件内判断文档解析的状态,该事件没有具柄的写法(例如**onclick**
、**onload**
):
console.log(document.readyState);
document.addEventListener("DOMContentLoaded",function(){
console.log(document.readyState);
},flase)
// loading
// interactive
// complete
load
事件等文档解析完成+资源加载完成后才会触发(浪费时间):
该事件也可以用在
img
标签上,表示img
加载完成后触发!!!
window.onload = function(){
//...
}