1. 完整版:DOM 操作详解技术文档

    一、DOM 概述

    • DOM(Document Object Model):浏览器将 HTML/XML 文档解析后,生成的以节点(Node)为单位的树形结构。
    • 目标:提供一组标准 API,通过脚本访问、修改、插入或删除文档内容和结构,实现页面动态互动。

    DOM 树示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    Document
    ├─ html
    ├─ head
    └─ body
    ├─ header
    ├─ main
    │ ├─ section
    │ └─ article
    └─ footer

    二、DOM 节点类型

    节点类型 常量 描述
    元素节点 Node.ELEMENT_NODE (1) <div>, <p> 等标签
    文本节点 Node.TEXT_NODE (3) 标签或属性中的文本内容
    属性节点 Node.ATTRIBUTE_NODE (2) 元素的属性,如 class="item"
    注释节点 Node.COMMENT_NODE (8)` <!-- 注释 -->
    文档节点 Node.DOCUMENT_NODE (9)` 根节点,代表整个文档

    三、节点选取(Selection)

    1. 传统方法

    1
    2
    3
    const el1 = document.getElementById('id');
    const els1 = document.getElementsByClassName('class'); // HTMLCollection,返回页面上所有 class 名为 "class" 的元素。
    const els2 = document.getElementsByTagName('div'); // HTMLCollection,返回页面上所有 <div> 标签元素

    假设你的 HTML 是这样:

    1
    2
    3
    <div class="class">A</div>
    <div class="class">B</div>
    <div>C</div>

    你可以这样选取:

    1
    2
    3
    4
    5
    6
    const els1 = document.getEleme	ntsByClassName('class'); // 包含 A 和 B
    const els2 = document.getElementsByTagName('div'); // 包含 A、B 和 C

    console.log(els1.length); // 输出 2
    console.log(els2.length); // 输出 3
    console.log(els1[0].textContent); // 输出 A

    2. CSS 选择器(推荐)

    1
    2
    const el2 = document.querySelector('.container > p');      // 第一个匹配元素
    const allEls = document.querySelectorAll('ul li.active'); // NodeList

    区别HTMLCollection 实时更新,NodeList 静态(部分浏览器支持实时)。

    四、节点遍历(Traversal)

    1
    2
    3
    4
    5
    6
    const parent = el.parentNode;       // 父节点
    const children = el.childNodes; // 所有子节点(含文本、注释)
    const first = el.firstChild; // 第一个子节点
    const last = el.lastChild; // 最后一个子节点
    const next = el.nextSibling; // 下一个同级节点
    const prev = el.previousSibling; // 上一个同级节点

    遍历元素节点(忽略文本)可以用:

    1
    const childrenEls = el.children;    // 只包含元素节点的 HTMLCollection

    五、节点读取与写入(Read & Write)

    1. 文本和 HTML 内容

    1
    2
    3
    4
    5
    6
    7
    // 读取
    let text = el.textContent; // 纯文本(包括子元素文本)
    let html = el.innerHTML; // 包含子元素标签的 HTML

    // 写入
    el.textContent = '新文本'; // 自动转义,不会解析 HTML
    el.innerHTML = '<strong>加粗文本</strong>'; // 插入 HTML 结构

    2. 属性与数据属性

    1
    2
    3
    4
    5
    6
    7
    // 属性操作
    el.setAttribute('data-id', '123');
    let id = el.getAttribute('data-id');
    el.removeAttribute('data-id');

    // dataset 快捷访问
    el.dataset.user = 'alice'; // 对应 data-user="alice"

    六、结构修改(Manipulation)

    1. 创建与插入

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    let newDiv = document.createElement('div');
    newDiv.classList.add('card');
    newDiv.textContent = '新卡片';

    // append
    document.body.appendChild(newDiv);

    // insertBefore
    let container = document.querySelector('#container');
    container.insertBefore(newDiv, container.firstChild);

    2. 克隆与替换

    1
    2
    let clone = newDiv.cloneNode(true);      // 深克隆(包含子节点)
    container.replaceChild(clone, newDiv); // 替换节点

    3. 删除节点

    1
    2
    3
    container.removeChild(clone);
    // 或者
    newDiv.remove(); // 现代浏览器可用

    七、CSS 样式与类名操作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // 类名
    el.classList.add('active');
    el.classList.remove('hidden');
    el.classList.toggle('open');

    // 样式
    el.style.width = '100px';
    el.style.cssText += 'margin:10px; padding:5px;';
    // 读取计算后的样式
    let computed = window.getComputedStyle(el).display;

    八、事件绑定(Events)

    1. 直接绑定

    1
    2
    3
    4
    function handleClick(e) {
    console.log('Clicked:', e.target);
    }
    el.addEventListener('click', handleClick);

    2. 事件委托

    1
    2
    3
    4
    5
    6
    let list = document.querySelector('ul');
    list.addEventListener('click', (e) => {
    if (e.target.matches('li.item')) {
    console.log('点击了列表项:', e.target.textContent);
    }
    });

    3. 移除监听器

    1
    el.removeEventListener('click', handleClick);

    九、综合示例:动态图文列表

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <ul id="gallery"></ul>
    const data = [
    { title: '图1', src: '1.jpg' },
    { title: '图2', src: '2.jpg' }
    ];
    const gallery = document.getElementById('gallery');
    // 使用 DocumentFragment 批量插入
    let frag = document.createDocumentFragment();
    data.forEach(item => {
    let li = document.createElement('li');
    let img = document.createElement('img'); img.src = item.src;
    let caption = document.createElement('p'); caption.textContent = item.title;
    li.appendChild(img);
    li.appendChild(caption);
    frag.appendChild(li);
    });
    gallery.appendChild(frag);

    十、性能优化与最佳实践

    1. 批量修改:使用 DocumentFragment 或模板字符串拼接后一次渲染。
    2. 节点缓存:频繁操作同一节点时,先查询并保存引用。
    3. 事件委托:避免大量子元素的单独监听。
    4. 最小重绘:减少对 layout 触发的读取/写入混合。
    5. 安全:避免直接插入未经过滤的用户内容,防范 XSS 攻击。

    十一、总结

    本档详细介绍了从节点类型、选取、遍历、读写结构修改、样式、事件、性能等全方位的 DOM 操作技术。掌握这些知识,可帮助你构建交互丰富、高性能的网页应用。