【Java Web学习 | 第12篇】JavaScript(6)DOM

【Java Web学习 | 第12篇】JavaScript(6) – DOM(文档对象模型)深度详解(2026最新版)

恭喜你完成 BOM 部分!
现在进入 DOM(Document Object Model,文档对象模型),这是 JavaScript 操作 HTML 页面结构、内容和样式的核心技术。在 Java Web 项目中,DOM 操作是实现动态页面(如用户列表渲染、表单提交反馈、实时数据更新)的关键。

2026 年,DOM 操作依然以原生 API 为主,querySelector / querySelectorAll 是主流选择器,配合 DocumentFragment、事件委托、classList 等实现高性能更新。避免频繁直接操作 live DOM 是性能优化的核心原则。

1. DOM 核心概念

  • DOM 是浏览器将 HTML 解析成的一个树状结构(节点树)。
  • 节点类型:元素节点(Element)、文本节点(Text)、注释节点等。
  • document 是 DOM 的入口对象。
console.log(document);                    // 整个文档
console.log(document.documentElement);    // <html> 根元素
console.log(document.body);               // <body>

2. 元素选择(Selection)—— 2026 推荐写法

// 1. 推荐:querySelector(返回第一个匹配元素)
const title = document.querySelector('h1');
const firstCard = document.querySelector('.card');

// 2. querySelectorAll(返回 NodeList,支持 forEach)
const cards = document.querySelectorAll('.card');
cards.forEach(card => {
    card.style.border = '2px solid #007bff';
});

// 3. 传统方法(仍可用,但不推荐作为首选)
document.getElementById('userList');
document.getElementsByClassName('item');
document.getElementsByTagName('div');

// 最佳实践:缓存引用(避免重复查询)
const userList = document.querySelector('#userList');   // 缓存

性能提示:ID 最快,其次是类/标签。复杂选择器从右向左匹配,尽量简化。

3. 修改内容与属性

// 1. 文本内容(推荐 textContent,安全且快)
title.textContent = "Java Web 项目标题已更新";

// 2. HTML 内容(小心 XSS,信任数据时使用)
userInfo.innerHTML = `<strong>${username}</strong>`;

// 3. 属性操作
img.setAttribute('src', 'https://picsum.photos/300');
img.src = 'https://picsum.photos/300';   // 常用属性可直接操作

// 4. class 操作(强烈推荐 classList)
element.classList.add('active');
element.classList.remove('inactive');
element.classList.toggle('dark-mode');
element.classList.contains('highlight');   // 返回 boolean

4. 创建、添加与删除元素(动态渲染核心)

// 创建元素
const newDiv = document.createElement('div');
newDiv.className = 'user-item';
newDiv.innerHTML = `<h3>${user.username}</h3><p>年龄:${user.age}</p>`;

// 添加到文档
document.body.appendChild(newDiv);           // 追加到末尾
parentElement.append(newDiv);                // 现代写法,支持多个
parentElement.prepend(newDiv);               // 插入到开头

// 批量插入性能优化:使用 DocumentFragment
function renderUserList(users) {
    const fragment = document.createDocumentFragment();   // 轻量容器,不触发重绘

    users.forEach(user => {
        const item = document.createElement('div');
        item.className = 'user-item';
        item.textContent = user.username;
        fragment.appendChild(item);
    });

    userList.innerHTML = '';          // 清空原有
    userList.appendChild(fragment);   // 一次性插入,只触发一次重绘
}

5. 事件处理(Event)—— 动态交互基础

// 1. 推荐:addEventListener(支持多个监听器)
const btn = document.querySelector('#submitBtn');

btn.addEventListener('click', (event) => {
    console.log('按钮被点击');
    event.preventDefault();   // 阻止默认行为(如表单提交)
});

// 2. 事件委托(性能最佳实践,大量子元素时推荐)
userList.addEventListener('click', (e) => {
    if (e.target.closest('.delete-btn')) {   // 委托到父元素
        const item = e.target.closest('.user-item');
        item.remove();                       // 删除元素
        console.log('删除成功');
    }
});

常用事件:click、input、submit、keydown、load、resize 等。

6. 遍历与节点关系

// 子节点
const children = parent.children;        // HTMLCollection(仅元素节点)
const childNodes = parent.childNodes;    // NodeList(包含文本节点)

// 父/兄弟节点
element.parentElement;
element.nextElementSibling;
element.previousElementSibling;

7. 完整实战示例:动态用户列表(结合后端数据准备)

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>DOM 实战 - 用户列表</title>
    <style>
        .user-item { padding: 15px; margin: 8px 0; background: #f8f9fa; border-radius: 8px; }
        .delete-btn { color: red; margin-left: 10px; }
    </style>
</head>
<body>
    <h1>用户管理</h1>
    <button id="addBtn">添加用户</button>
    <div id="userList"></div>

    <script>
        const users = [
            { id: 1, name: "张三", age: 25 },
            { id: 2, name: "李四", age: 30 }
        ];

        const userList = document.getElementById('userList');
        const addBtn = document.getElementById('addBtn');

        function renderUsers() {
            const fragment = document.createDocumentFragment();

            users.forEach(user => {
                const div = document.createElement('div');
                div.className = 'user-item';
                div.innerHTML = `
                    ${user.name}(${user.age}岁)
                    <button class="delete-btn" data-id="${user.id}">删除</button>
                `;
                fragment.appendChild(div);
            });

            userList.innerHTML = '';
            userList.appendChild(fragment);
        }

        // 事件委托
        userList.addEventListener('click', (e) => {
            if (e.target.classList.contains('delete-btn')) {
                const id = parseInt(e.target.dataset.id);
                const index = users.findIndex(u => u.id === id);
                if (index > -1) users.splice(index, 1);
                renderUsers();
            }
        });

        addBtn.addEventListener('click', () => {
            const newUser = { id: Date.now(), name: "新用户", age: 28 };
            users.push(newUser);
            renderUsers();
        });

        // 初始化
        renderUsers();
    </script>
</body>
</html>

8. 2026 DOM 操作最佳实践

  • 缓存元素引用:避免重复 querySelector
  • 批量更新:使用 DocumentFragmentinnerHTML(数据可信时)。
  • 事件委托:减少监听器数量。
  • 避免强制重排:批量读写分离,必要时用 requestAnimationFrame
  • 现代替代:复杂场景可考虑 Web Components / Shadow DOM,但原生 DOM 仍是基础。
  • 性能工具:浏览器 DevTools(Performance 面板)分析重绘/重排。

9. 小练习(立即动手)

  1. 创建一个按钮,点击后动态添加一个带随机颜色的 <div> 到页面。
  2. 实现一个待办事项列表:输入内容后添加,点击项可删除(使用事件委托)。
  3. querySelectorAll 获取所有 .card,给它们添加 hover 效果(通过 classList)。
  4. 修改上面的用户列表示例,添加“编辑”按钮(点击弹出 prompt 修改名称)。

下一篇文章预告:《【Java Web学习 | 第13篇】JavaScript(7) – 异步编程(Promise + async/await)与 Fetch API》

我们将学习现代异步机制,并使用 fetch 真正调用 Spring Boot 后端 REST 接口,实现数据增删改查。


本篇核心总结

  • 选择器:优先 querySelector / querySelectorAll
  • 修改:textContent(安全)、classList(优雅)
  • 批量:DocumentFragment
  • 事件:addEventListener + 委托

有问题随时问:

  • 想要更多性能优化示例(如虚拟列表)?
  • 需要完整购物车 / 表单验证 DOM 实战?
  • 或直接进入 异步 + Fetch 篇?

回复“给我练习答案”或“下一篇 Fetch”,我立刻继续!

DOM 是 JavaScript 操作页面的“双手”,掌握后你已经可以构建动态交互界面。继续加油,下一章我们就要和后端真正交互了!🚀

文章已创建 5288

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部