第6课:DOM操作进阶——网页的“变形术”

生活就像一场马拉松,不在乎起点有多高,而在于你是否能坚持跑到终点。哪怕步履蹒跚,只要心中有梦,脚下有路,每一步都算数!

欢迎来到「JavaScript 魔法学院」第 6 课!之前我们学会了用 DOM 修改内容,今天将解锁更强大的"变形术"------动态创建元素、批量操控样式, 最后带大家开发「待办事项列表」,代码可直接用于简历项目!

一、元素创建与删除

1. 动态创建元素

javascript 复制代码
// 1. 创建元素:先造一个"白模"
const newDiv = document.createElement("div");

// 2. 添加内容与样式
newDiv.textContent = "我是新来的!";
newDiv.style.backgroundColor = "#ffe6e6";

// 3. 挂载到DOM树
document.body.appendChild(newDiv);  // 添加到页面末尾

2. 元素删除与移动

javascript 复制代码
// 删除元素
const oldEl = document.getElementById("old");
oldEl.remove();  // 简单粗暴!

// 移动元素(无需删除重建)
const box = document.querySelector(".box");
document.body.appendChild(box);  // 从原位置移动到body末尾

二、样式与类的进阶操作

1. classList------精准控制类名

方法 作用 示例
add() 添加类 el.classList.add("active")
remove() 移除类 el.classList.remove("hide")
toggle() 切换类(有 → 无,无 → 有) el.classList.toggle("dark")
contains() 判断是否包含类 if (el.classList.contains("error"))

2. 批量操作样式

javascript 复制代码
// 通过cssText批量设置
const title = document.getElementById("title");
title.style.cssText = `
  color: #fff;
  background: linear-gradient(45deg, #ff6b6b, #ff9f43);
  border-radius: 8px;
  padding: 5px 10px;
`;

避坑指南:

  • 优先用 class 控制样式,避免 JS 写死 style

  • display: none 会触发重绘,可用 visibility: hidden 优化性能

三、事件委托:高效的事件管理

1. 什么是事件委托?

传统方式: 给每个按钮绑定点击事件 → 性能差

委托模式: 给父元素绑定事件,通过 e.target 识别子元素 → 节省内存

2. 代码对比

javascript 复制代码
// 传统方式(不推荐)
document.querySelectorAll(".btn").forEach(btn => {
  btn.addEventListener("click", handleClick);
});

// 委托模式(推荐)
document.getElementById("btnGroup").addEventListener("click", function(e) {
  if (e.target.classList.contains("btn")) {
    handleClick(e.target);
  }
});

四、实战:待办事项列表

1. 功能需求

  • 输入文字添加新待办项

  • 点击复选框标记完成(删除线效果)

  • 可删除指定项

2. 效果演示

3. 完整代码

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>第6课:DOM操作进阶</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f5f5f5;
            margin: 0;
            padding: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
        }

        .todo-container {
            background-color: #fff;
            border-radius: 8px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
            padding: 20px;
            width: 300px;
            text-align: center;
        }

        #todoInput {
            width: 100%;
            padding: 10px;
            margin-bottom: 10px;
            border: 1px solid #ccc;
            border-radius: 4px;
            font-size: 16px;
            box-sizing: border-box;
        }

        button {
            width: 100%;
            padding: 10px;
            background-color: #007bff;
            color: #fff;
            border: none;
            border-radius: 4px;
            font-size: 16px;
            cursor: pointer;
        }

        button:hover {
            background-color: #0056b3;
        }

        #todoList {
            list-style: none;
            padding: 0;
            margin-top: 20px;
        }

        #todoList li {
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 10px 0;
            border-bottom: 1px solid #eee;
        }

        #todoList li:last-child {
            border-bottom: none;
        }

        .toggle {
            margin-right: 10px;
            cursor: pointer;
        }

        .delete {
            background-color: #dc3545;
            color: #fff;
            border: none;
            border-radius: 50%;
            width: 24px;
            height: 24px;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
        }

        .delete:hover {
            background-color: #a71d2a;
        }

        .completed {
            text-decoration: line-through;
            color: #ccc;
        }
    </style>
</head>

<body>
    <div class="todo-container">
        <input type="text" id="todoInput" placeholder="输入待办事项">
        <button onclick="addTodo()">添加</button>
        <ul id="todoList"></ul>
    </div>

    <script>
        function addTodo() {
            const input = document.getElementById("todoInput");
            const text = input.value.trim();
            if (!text) return;

            // 动态创建列表项
            const li = document.createElement("li");
            li.innerHTML = `
        <input type="checkbox" class="toggle">
        <span>${text}</span>
        <button class="delete">×</button>
      `;

            // 事件委托:监听ul处理点击
            document.getElementById("todoList").appendChild(li);
            input.value = "";  // 清空输入框
        }

        // 事件处理:切换完成态/删除
        document.getElementById("todoList").addEventListener("click", (e) => {
            const item = e.target.closest("li");
            if (e.target.classList.contains("delete")) {
                item.remove();  // 删除项
            } else if (e.target.classList.contains("toggle")) {
                item.querySelector("span").classList.toggle("completed");  // 切换样式
            }
        });
    </script>
</body>

</html>

4. 代码亮点

  • 动态生成:避免手动操作 HTML 结构

  • 事件委托:统一管理复选框和删除按钮事件

  • CSS 样式:用类名控制完成态效果

下节预告

第 7 课:事件处理------JS 的"感官系统"

  • 事件监听:addEventListener

  • 常见事件:click、input、load

  • 事件对象与事件冒泡

关注公众号,回复【JS】获取本课源码+工具包!

相关推荐
云端看世界9 分钟前
为什么要学习 ECMAScript 协议
前端·javascript·ecmascript 6
飞鱼荷兰猪11 分钟前
LLM大语言模型简述
后端·aigc
小爷毛毛_卓寿杰17 分钟前
【Dify(v1.x) 核心源码深入解析】errors、extension 和 external_data_tool 模块
人工智能·后端·python
前端付杰21 分钟前
深入理解 IndexedDB:索引与游标查询的高效应用
前端·javascript·indexeddb
溪饱鱼24 分钟前
秒杀传统数据库!Cloudflare D1 + Drizzle组合拳,高并发高可用,让我们的成本爆降10倍 - D1
前端·后端
江城开朗的豌豆27 分钟前
JavaScript篇:JavaScript事件循环:从厨房看异步编程的奥秘
前端·javascript·面试
廖广杰30 分钟前
java虚拟机-为什么TLAB能提升对象分配效率?如何配置TLAB大小
后端
weixin_5168756539 分钟前
Vue 3 Watch 监听 Props 的踩坑记录
前端·javascript·vue.js
全栈老李技术面试42 分钟前
【高频考点精讲】JavaScript中的访问者模式:从AST解析到数据转换的艺术
开发语言·前端·javascript·面试·html·访问者模式
独立开阀者_FwtCoder1 小时前
狂收 33k+ star!全网精选的 MCP 一网打尽!!
java·前端·javascript