本篇博客简单介绍一下DOM的基本概念、事件和文档的加载。
什么是DOM?
在前面的JS介绍中,我们知道JS中的对象分为三种:
- 内建对象,如:Array、Function、Object、Date等;
- 自定义对象;
- 宿主对象(DOM、BOM)。
DOM(Document Object Model,文档对象模型):
- 文档:整个HTML网页就是一个文档;
- 对象:网页中每一个部分都会被转换为一个对象;
- 模型:表示对象与对象之间的关系,这样方便获取对象。
我们来看一个简单的例子,来理解一下模型:
<html>
<head>
<title>这是一个标题</title>
</head>
<body>
<a href="#">这是一个超链接</a>
</body>
</html>
DOM就是用来操作网页的。
节点
节点是构成HTML文档最基本的单元,常用的节点分为四类:
- 文档节点:整个HTML文档;
- 元素节点:HTML文档中的HTML标签;
- 属性节点:元素的属性;
- 文本节点:HTML标签中的文本内容。
节点的属性:
nodeName | nodeType | nodeValue | |
文档节点 | #document | 9 | null |
元素节点 | 标签名 | 1 | null |
属性节点 | 属性名 | 2 | 属性值 |
文本节点 | #text | 3 | 文本内容 |
浏览器已经为我们提供了文档节点对象,这个对象是window的属性,可以在页面中直接使用,文档节点代表的是整个网页。
我们来看一个例子来理解一下文档节点的基本使用:
<!--
创建一个按钮,使用文档节点对象获取到这个按钮对象,修改按钮对象上的文字。
-->
<button id="btn">我是一个按钮</btn>
<script type="text/javascript">
// 使用文档节点对象获取到button对象
var btn = document.getElementById("btn");
// 修改按钮上的文字
btn.innerHTML = "按钮";
</script>
事件
事件就是用户和浏览器之间的交互行为。如:点击按钮、鼠标移动、关闭窗口等。
我们可以在事件对应的属性中设置一些JS代码,这样当事件触发时,这些代码将会执行。
我们来看一个例子,我们写一个代码实现点击按钮打印hello, world!
:
<!--
点击按钮打印hello, world!
-->
<button id="btn" onclick="alert('hello, world!');">我是一个按钮</button>
但是我们知道这样写是不合适的,这种写法结构和行为耦合度高,不方便维护。
我们可以为按钮的对应事件绑定处理函数的形式来响应事件,这样当事件触发时,其对应的函数将会被调用:
<button id="btn">我是一个按钮</button>
<script type="text/javascript">
// 获取按钮对象
var btn = document.getElementById("btn");
// 为按钮绑定点击事件
btn.onclick = function(){
alert("hello, world!");
};
</script>
文档的加载
我们发现,前面演示的代码JS代码是写在body中,也就是button标签的下面。在前面关于JS的介绍中,我们演示的所有的JS代码都是写在head中的,如果我们将button下面的JS代码写到head中会怎么样呢?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DOM简介</title>
<script type="text/javascript">
// 获取按钮对象
var btn = document.getElementById("btn");
// 为按钮对象绑定响应事件
btn.onclick = function(){
alert("hello, world!");
};
</script>
</head>
<body>
<button id="btn">我是一个按钮</button>
</body>
</html>
可以看到,这里报错了,找不到onclick。这是为什么呢?
这是因为浏览器在加载页面时,是按照自上向下的顺序加载的,读取到一行就运行一行。如果将script标签写在页面的上面,在代码执行时,页面还没有加载,DOM对象也没有加载,会导致无法获取到DOM对象。
解决方法有两种:
方案一:将script代码写到body的下面。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DOM简介</title>
</head>
<body>
<button id="btn">我是一个按钮</button>
</body>
<!--
JS代码写到body标签下,会在DOM对象加载完毕后再执行JS代码
-->
<script type="text/javascript">
var btn = document.getElementById("btn");
btn.onclick = function(){
alert("hello, world!");
};
</script>
</html>
方法二:借助window的onload事件,onload事件会在整个页面加载完成后立即发生。所以也可以保证在DOM对象加载完成后,再执行JS代码。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DOM简介</title>
<!--
JS代码写到head标签中,借助window的onload事件
-->
<script type="text/javascript">
window.onload = function(){
var btn = document.getElementById("btn");
btn.onclick = function(){
alert("hello, world!");
};
};
</script>
</head>
<body>
<button id="btn">我是一个按钮</button>
</body>
</html>
两种方法各有优势:
- 方法一将JS代码写到后面比将代码写到前面效率较高;
- 但是方法二将JS代码写到头部可以方便管理。