DOM全称是Document Object Model(文档对象模型), 它是HTML和XML文档的编程接口. 简单来说, DOM就是把我们的网页文档转换成了一个对象模型, 这样我们就可以用JavaScript来操作网页了.
想象一下: 你写了一个HTML文件, 浏览器加载这个文件后, 会把它解析成一个树状结构, 这个结构就是DOM. 通过DOM, 我们可以:
改变网页的内容.
修改元素的样式.
添加或删除元素.
响应用户的交互.
示例代码:
document.getElementById('myButton').addEventListener('click', function() {
alert('按钮被点击了!');
});
DOM的核心概念是"树结构", 让我们用一个简单的HTML例子来说明:<!DOCTYPE html>
<html>
<head>
<title>我的网页</title>
</head>
<body>
<h1>欢迎来到我的网站</h1>
<div class="content">
<p>这是一个段落</p>
<p>这是另一个段落</p>
</div>
</body>
</html>
文档 (Document)
└── html (根元素)
├── head
│ └── title
│ └── "我的网页" (文本节点)
└── body
├── h1
│ └── "欢迎来到我的网站" (文本节点)
└── div (class="content")
├── p
│ └── "这是一个段落" (文本节点)
└── p
└── "这是另一个段落" (文本节点)
这个树状结构有几个关键点:
文档节点(Document): 这是整个DOM树的根节点,代表整个文档.
元素节点(Element): 如<html>
, <head>
, <body>
, <div>
等.
文本节点(Text): 如标签内的文字内容.
属性节点(Attribute): 如class="content".
三、节点类型详解
1) 元素节点:
这是最常见的节点类型, 对应HTML标签. 比如<div>
, <p>
, <a>
等.
const divElement = document.createElement('div');
console.log(divElement.nodeType);
console.log(divElement.nodeType === Node.ELEMENT_NODE);
const textNode = document.createTextNode('你好,世界!');
console.log(textNode.nodeType);
const comment = document.createComment('这是一个注释');
console.log(comment.nodeType);
console.log(document.nodeType);
DOM节点之间有多种关系:
parentNode: 父节点.
childNodes: 所有子节点的列表(包括文本节点等).
children: 仅元素子节点.
firstChild/lastChild: 第一个/最后一个子节点.
nextSibling/previousSibling: 下一个/上一个兄弟节点.
我们来看个示例:
<div id="container">
<p>段落1</p>
<p>段落2</p>
</div>
const container = document.getElementById('container');
console.log(container.childNodes.length);
console.log(container.children.length);
四、DOM操作基础
1) 查询元素:
const element = document.getElementById('myId');
const elements = document.getElementsByClassName('myClass');
const divs = document.getElementsByTagName('div');
const item = document.querySelector('.menu-item');
const items = document.querySelectorAll('.menu-item');
2)创建与添加元素:
const newDiv = document.createElement('div');
newDiv.textContent = '我是新创建的div';
document.body.appendChild(newDiv);
const container = document.getElementById('container');
const firstChild = container.firstChild;
container.insertBefore(newDiv, firstChild);
3) 修改元素:
element.textContent = '新文本内容';
element.innerHTML = '<strong>加粗文本</strong>';
element.style.color = 'red';
element.style.backgroundColor = '#f0f0f0';
element.classList.add('new-class');
element.classList.remove('old-class');
element.classList.toggle('active');
4)删除元素:
const parent = document.getElementById('parent');
const child = document.getElementById('child');
parent.removeChild(child);
child.remove();
五、DOM事件处理
基本事件处理:
const button = document.getElementById('myButton');
button.onclick = function() {
console.log('按钮被点击了!');
};
button.addEventListener('click', function(event) {
console.log('按钮被点击了!', event);
});
事件冒泡和捕获, DOM事件有三个阶段:
捕获阶段(从window向下到目标元素).
目标阶段(到达目标元素).
冒泡阶段(从目标元素向上冒泡).
document.getElementById('outer').addEventListener('click', function() {
console.log('外层div - 冒泡阶段');
}, false);
document.getElementById('inner').addEventListener('click', function() {
console.log('内层div - 捕获阶段');
}, true);
利用事件冒泡机制,可以在父元素上处理子元素的事件.
<ul id="myList">
<li>项目1</li>
<li>项目2</li>
<li>项目3</li>
</ul>
document.getElementById('myList').addEventListener('click', function(event) {
if (event.target.tagName === 'LI') {
console.log('点击了:', event.target.textContent);
}
});
DOM级别:
DOM Level 1 (1998): 定义了核心DOM和HTML DOM.
DOM Level 2 (2000): 添加了事件模型、样式访问等.
DOM Level 3 (2004): 扩展了DOM核心,添加了XPath等.
DOM Level 4 (2015): 也称为DOM Living Standard,现代浏览器主要实现.
兼容性问题, 虽然现代浏览器对DOM的支持已经很好,但仍有一些需要注意的差异:
IE的差异:
IE8及以下不支持addEventListener,
需要使用attachEvent.
IE对某些CSS属性的访问方式不同.
方法可用性:
remove()
方法在旧浏览器中不可用.
classList
在IE9及以下不支持.
事件对象:
在IE中, 事件对象是全局的window.event.
在其他浏览器中, 事件对象作为参数传递.
兼容性的操作示例:
function addEvent(element, eventName, handler) {
if (element.addEventListener) {
element.addEventListener(eventName, handler);
} else if (element.attachEvent) {
element.attachEvent('on' + eventName, handler);
} else {
element['on' + eventName] = handler;
}
}
element.onclick = function(event) {
event = event || window.event;
const target = event.target || event.srcElement;
};
综合示例, 构建一个简单的待办事项列表:
<!DOCTYPE html>
<html>
<head>
<title>待办事项</title>
<style>
.completed {
text-decoration: line-through;
color: #999;
}
</style>
</head>
<body>
<h1>我的待办事项</h1>
<input type="text" id="newTodo" placeholder="输入新任务">
<button id="addBtn">添加</button>
<ul id="todoList"></ul>
<script>
document.addEventListener('DOMContentLoaded', function() {
const newTodoInput = document.getElementById('newTodo');
const addBtn = document.getElementById('addBtn');
const todoList = document.getElementById('todoList');
function addTodo() {
const text = newTodoInput.value.trim();
if (text) {
const li = document.createElement('li');
const span = document.createElement('span');
span.textContent = text;
const deleteBtn = document.createElement('button');
deleteBtn.textContent = '删除';
li.appendChild(span);
li.appendChild(deleteBtn);
todoList.appendChild(li);
newTodoInput.value = '';
span.addEventListener('click', function() {
span.classList.toggle('completed');
});
deleteBtn.addEventListener('click', function() {
li.remove();
});
}
}
addBtn.addEventListener('click', addTodo);
newTodoInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
addTodo();
}
});
});
</script>
</body>
</html>
这个例子展示了:
动态创建DOM元素
事件监听
类名切换
元素删除
表单处理
阅读原文:原文链接
该文章在 2025/7/17 10:07:20 编辑过