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 编辑过