Skip to content

DOM 操作

DOM(Document Object Model)是 HTML 文档的编程接口,JavaScript 可以通过 DOM 操作网页内容。

获取元素

传统方法

javascript
// 通过 ID 获取
const element = document.getElementById('myId');

// 通过标签名获取
const elements = document.getElementsByTagName('div');

// 通过类名获取
const elements = document.getElementsByClassName('myClass');

现代方法(推荐)

javascript
// 获取单个元素
const element = document.querySelector('#myId');
const element = document.querySelector('.myClass');
const element = document.querySelector('div.container');

// 获取多个元素
const elements = document.querySelectorAll('.myClass');
const elements = document.querySelectorAll('div > p');

// 遍历 NodeList
elements.forEach(element => {
    console.log(element);
});

特殊元素

javascript
// 获取 html 元素
const html = document.documentElement;

// 获取 head 元素
const head = document.head;

// 获取 body 元素
const body = document.body;

// 获取当前焦点元素
const active = document.activeElement;

创建元素

javascript
// 创建元素
const div = document.createElement('div');
const text = document.createTextNode('Hello');

// 创建带内容的元素
const p = document.createElement('p');
p.textContent = '段落内容';

// 使用 innerHTML
const container = document.getElementById('container');
container.innerHTML = '<p>新内容</p>';

// 使用 insertAdjacentHTML
container.insertAdjacentHTML('beforeend', '<p>追加内容</p>');
// 位置: beforebegin, afterbegin, beforeend, afterend

添加元素

javascript
const parent = document.getElementById('parent');
const child = document.createElement('div');

// 末尾添加
parent.appendChild(child);

// 指定位置添加
const reference = document.getElementById('reference');
parent.insertBefore(child, reference);

// 新方法(推荐)
parent.append(child);           // 末尾添加
parent.prepend(child);          // 开头添加
parent.before(child);           // 前面添加
parent.after(child);            // 后面添加

// 添加多个
parent.append(child1, child2, '文本');

删除元素

javascript
const element = document.getElementById('myElement');

// 删除元素
element.remove();

// 通过父元素删除
element.parentNode.removeChild(element);

// 清空内容
element.innerHTML = '';
element.textContent = '';

替换元素

javascript
const parent = document.getElementById('parent');
const oldElement = document.getElementById('old');
const newElement = document.createElement('div');

// 替换元素
parent.replaceChild(newElement, oldElement);

// 新方法(推荐)
oldElement.replaceWith(newElement);

克隆元素

javascript
const element = document.getElementById('myElement');

// 浅克隆(不包含子元素)
const clone = element.cloneNode();

// 深克隆(包含子元素)
const clone = element.cloneNode(true);

属性操作

获取和设置属性

javascript
const element = document.getElementById('myInput');

// 获取属性
element.getAttribute('type');
element.getAttribute('class');

// 设置属性
element.setAttribute('type', 'text');
element.setAttribute('placeholder', '请输入');

// 删除属性
element.removeAttribute('disabled');

// 检查属性
element.hasAttribute('disabled');

HTML5 数据属性

javascript
const element = document.querySelector('[data-id]');

// 获取 data 属性
element.dataset.id;
element.dataset.userName; // data-user-name

// 设置 data 属性
element.dataset.id = '123';
element.dataset.userName = '张三';

类名操作

javascript
const element = document.getElementById('myElement');

// className(字符串)
element.className = 'class1 class2';

// classList(推荐)
element.classList.add('newClass');
element.classList.remove('oldClass');
element.classList.toggle('active');
element.classList.contains('active'); // true/false
element.classList.replace('old', 'new');

样式操作

行内样式

javascript
const element = document.getElementById('myElement');

// 设置单个样式
element.style.color = 'red';
element.style.backgroundColor = 'blue';
element.style.fontSize = '16px';

// 设置多个样式
Object.assign(element.style, {
    color: 'red',
    backgroundColor: 'blue',
    fontSize: '16px'
});

// 获取样式
element.style.color;

计算样式

javascript
const element = document.getElementById('myElement');

// 获取计算后的样式
const styles = window.getComputedStyle(element);
console.log(styles.color);
console.log(styles.backgroundColor);

CSS 类

javascript
// 推荐:通过类名控制样式
element.classList.add('highlight');
element.classList.remove('highlight');

内容操作

javascript
const element = document.getElementById('myElement');

// innerHTML - 包含 HTML 标签
element.innerHTML = '<strong>加粗</strong>';
console.log(element.innerHTML);

// textContent - 纯文本(推荐)
element.textContent = '<strong>不会解析</strong>';
console.log(element.textContent);

// innerText - 可见文本(考虑样式)
console.log(element.innerText);

表单操作

javascript
const form = document.getElementById('myForm');
const input = document.getElementById('myInput');

// 获取表单值
input.value;
input.checked;  // 复选框/单选框
input.files;    // 文件上传

// 设置表单值
input.value = '新值';
input.checked = true;

// 表单验证
input.checkValidity();
input.reportValidity();

// 提交表单
form.submit();

// 重置表单
form.reset();

元素尺寸和位置

javascript
const element = document.getElementById('myElement');

// 偏移尺寸(包含边框和滚动条)
element.offsetWidth;
element.offsetHeight;

// 客户端尺寸(不包含边框和滚动条)
element.clientWidth;
element.clientHeight;

// 滚动尺寸
element.scrollWidth;
element.scrollHeight;
element.scrollTop;
element.scrollLeft;

// 相对视口位置
const rect = element.getBoundingClientRect();
rect.top;
rect.right;
rect.bottom;
rect.left;
rect.width;
rect.height;

滚动操作

javascript
// 滚动到指定位置
window.scrollTo(0, 100);
window.scrollTo({
    top: 100,
    behavior: 'smooth'
});

// 滚动到元素
element.scrollIntoView();
element.scrollIntoView({ behavior: 'smooth' });

// 滚动指定距离
window.scrollBy(0, 100);

实践示例

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>DOM 操作示例</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
        }
        
        .todo-list {
            list-style: none;
            padding: 0;
        }
        
        .todo-item {
            display: flex;
            align-items: center;
            padding: 10px;
            border-bottom: 1px solid #eee;
        }
        
        .todo-item.completed span {
            text-decoration: line-through;
            color: #999;
        }
        
        .todo-item input[type="checkbox"] {
            margin-right: 10px;
        }
        
        .todo-item button {
            margin-left: auto;
            padding: 5px 10px;
            background: #dc3545;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        
        .input-group {
            display: flex;
            gap: 10px;
            margin-bottom: 20px;
        }
        
        .input-group input {
            flex: 1;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 4px;
        }
        
        .input-group button {
            padding: 10px 20px;
            background: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        
        .stats {
            margin-top: 20px;
            padding: 10px;
            background: #f8f9fa;
            border-radius: 4px;
        }
    </style>
</head>
<body>
    <h1>待办事项列表</h1>
    
    <div class="input-group">
        <input type="text" id="todoInput" placeholder="输入待办事项...">
        <button onclick="addTodo()">添加</button>
    </div>
    
    <ul class="todo-list" id="todoList"></ul>
    
    <div class="stats" id="stats"></div>
    
    <script>
        // 待办事项数据
        let todos = [];
        
        // 获取 DOM 元素
        const todoInput = document.getElementById('todoInput');
        const todoList = document.getElementById('todoList');
        const stats = document.getElementById('stats');
        
        // 渲染待办列表
        function renderTodos() {
            // 清空列表
            todoList.innerHTML = '';
            
            // 创建列表项
            todos.forEach((todo, index) => {
                const li = document.createElement('li');
                li.className = 'todo-item' + (todo.completed ? ' completed' : '');
                
                // 复选框
                const checkbox = document.createElement('input');
                checkbox.type = 'checkbox';
                checkbox.checked = todo.completed;
                checkbox.addEventListener('change', () => toggleTodo(index));
                
                // 文本
                const span = document.createElement('span');
                span.textContent = todo.text;
                
                // 删除按钮
                const deleteBtn = document.createElement('button');
                deleteBtn.textContent = '删除';
                deleteBtn.addEventListener('click', () => deleteTodo(index));
                
                // 组装
                li.append(checkbox, span, deleteBtn);
                todoList.appendChild(li);
            });
            
            // 更新统计
            updateStats();
        }
        
        // 添加待办
        function addTodo() {
            const text = todoInput.value.trim();
            if (!text) return;
            
            todos.push({
                text: text,
                completed: false,
                createdAt: new Date()
            });
            
            todoInput.value = '';
            renderTodos();
        }
        
        // 切换完成状态
        function toggleTodo(index) {
            todos[index].completed = !todos[index].completed;
            renderTodos();
        }
        
        // 删除待办
        function deleteTodo(index) {
            todos.splice(index, 1);
            renderTodos();
        }
        
        // 更新统计
        function updateStats() {
            const total = todos.length;
            const completed = todos.filter(t => t.completed).length;
            const pending = total - completed;
            
            stats.innerHTML = `
                总计: ${total} |
                已完成: ${completed} |
                待完成: ${pending}
            `;
        }
        
        // 回车添加
        todoInput.addEventListener('keypress', (e) => {
            if (e.key === 'Enter') {
                addTodo();
            }
        });
        
        // 初始化
        todos = [
            { text: '学习 HTML', completed: true },
            { text: '学习 CSS', completed: true },
            { text: '学习 JavaScript', completed: false }
        ];
        renderTodos();
    </script>
</body>
</html>