之前我们学了各种事件,除了这些事件之外,还有一种非常重要的事件:页面事件。页面事件通常绑定到 window 或 document 对象上。
在 JavaScript 中,常用的页面事件有以下 2 个。
- load
- DOMContentLoaded
JavaScript load 事件
在 JavaScript 中,load 表示页面全部加载完成后触发的一个事件。需要注意的是,只有整个页面(包括所有图片、CSS 文件、JavaScript 文件等外部资源)都已完成加载,才会触发 load 事件。
语法:
window.addEventListener("load", function () {
……
});说明:
load 事件一般绑定到 window 对象 上,而不是 document 对象。
如果你需要获取图片的大小,或者保证所有资源都可用,就需要使用 load 事件。
示例 1:没有为 window 绑定 load 事件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script>
const oImg = document.getElementById("bird");
console.log("图片宽度:", oImg.clientWidth);
console.log("图片高度:", oImg.clientHeight);
</script>
</head>
<body>
<img id="bird" src="imgs/bird.jpg" alt="">
</body>
</html>页面效果如下图 1 所示,浏览器控制台效果如下图 2 所示。


分析:
为什么控制台会报错呢?这是因为浏览器是从上到下来解析一个页面的。当解析到const oImg = document.getElementsByTagName("img")[0]; 这一句代码时,浏览器找不到 id 为 "bird" 的元素,然后就会感到很疑惑: “怎么半路杀出个不认识的程咬金来呢?”
正确的解决方法就是为 window 对象绑定一个 load 事件,请看下面例子。
示例 2:为 window 绑定 load 事件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script>
window.addEventListener("load", function () {
const oImg = document.getElementById("bird");
console.log("图片宽度:", oImg.clientWidth);
console.log("图片高度:", oImg.clientHeight);
});
</script>
</head>
<body>
<img id="bird" src="imgs/bird.jpg" alt="">
</body>
</html>页面效果如下图 1 所示,浏览器控制台效果如下图 2 所示。


分析:
在这个例子中,浏览器从上到下解析到 window.addEventListener("load", function () {}) 时,就不会去解析里面的代码,而是继续往下解析,直到把整个 HTML 文档解析完了之后才会回去执行 window.addEventListener("load", function () {}) 里面的代码。这个时候,就算程咬金不报上名号,人家都知道是他来了。
有小伙伴就会问了:“在下面这个例子中,为什么不需要为 window 对象绑定 load 事件,也可以获取到元素呢?”
示例 3:没有使用 load 的特殊情况
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script>
function getMes() {
const oImg = document.getElementById("bird");
console.log("图片宽度:", oImg.clientWidth);
console.log("图片高度:", oImg.clientHeight);
}
</script>
</head>
<body>
<img id="bird" src="imgs/bird.jpg" alt=""><br>
<button id="btn" onclick="getMes()">获取</button>
</body>
</html>页面效果如下图所示。

分析:
对于函数来说,有一句非常重要的话,不知道小伙伴还记得没有,那就是:如果一个函数仅仅是定义而没有被调用的话,则函数本身是不会执行的。
从上面我们可以知道,浏览器从上到下解析 HTML 文档,当它解析到函数的定义部分时,它也会直接跳过。如果浏览器立刻解析的话,那函数岂不是自动执行了?那这还是函数么?
这里的函数是在用户点击这个按钮的时候执行的,那时候文档已经加载好了,此时使用 const oImg = document.getElementById("bird"); 获取 DOM 元素就不会报错了。
JavaScript DOMContentLoaded 事件
在 JavaScript 中,DOMContentLoaded 表示在 DOM 内容加载完成后触发的事件。它不需要等外部资源(如图片、样式表等)加载完成,只需要所有 DOM 节点准备就绪,就会触发。
也就是说,DOMContentLoaded 执行的时机比 load 的更早一些。
语法:
document.addEventListener("DOMContentLoaded", function () {
……
});说明:
DOMContentLoaded 事件是在 document 对象 上触发的,因此我们一般都是将 DOMContentLoaded 事件绑定到 document 对象上,而不是 window 对象。
如果你不需要等待外部资源(如图片、样式表)的加载,此时使用 DOMContentLoaded 事件会比 load 事件更合适。
示例 4:DOMContentLoaded 事件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script>
document.addEventListener("DOMContentLoaded", function () {
const oP = document.getElementsByTagName("p")[0];
console.log(oP.innerHTML);
});
</script>
</head>
<body>
<p><strong>绿叶网</strong></p>
</body>
</html>页面效果如下图 1 所示,控制台输出如下图 2 所示。


