JS怎么使用classList添加、删除和切换class
全面讲解原生JavaScript中使用classList属性添加、删除和切换class的具体用法,包含add、remove、toggle语法示例、多类名操作、条件切换及避坑指南。
在原生 JavaScript 中,为 DOM 元素操作样式类名最标准、最高效的方式是使用元素的 classList 属性。classList 是一个只读的 DOMTokenList 集合,它专门提供了 add()、remove() 和 toggle() 等原生方法,彻底省去了过去通过 className 进行字符串拼接、正则替换和手动管理空格的麻烦。本文将从选取元素开始,逐步讲解如何利用这三个核心方法实现类名的添加、删除和切换,并介绍相关的条件控制与边界避坑技巧。
操作准备:选取 DOM 节点并访问 classList
在操作类名之前,必须先通过 DOM 查询方法获取到目标元素的引用。任何标准的 HTML 元素节点都原生具备 classList 属性:
// 1. 选取目标元素
const box = document.querySelector('#myBox');
// 2. 查看当前的 classList
console.log(box.classList);
// 输出类似: DOMTokenList(2) ["box", "highlight", value: "box highlight"]
classList 自身虽然是只读属性(不能执行 box.classList = 'new-class'),但它所返回的对象内部封装了一整套修改类名集合的便捷方法。所有通过这些方法产生的变更,都会立刻自动同步到该元素的 HTML class 属性上,并促使浏览器匹配最新 CSS 规则进行视图重绘。
使用 classList.add() 添加 class
当需要为元素添加一个或多个新的 CSS 类名时,调用 add() 方法是最直接的做法。
1. 添加单个类名
直接将类名作为字符串参数传入:
const btn = document.querySelector('.submit-btn');
// 添加单个类名 active
btn.classList.add('active');
如果该元素原本的 class 为 "submit-btn",执行后将自动更新为 "submit-btn active"。
2. 批量添加多个类名
add() 方法支持传入多个参数,一次性添加多个类名,中间用逗号隔开即可:
// 一次性添加三个类名
btn.classList.add('loading', 'disabled', 'btn-primary');
如果有现成的数组,还可以借助 ES6 展开运算符(Spread Operator)传递:
const extraClasses = ['shadow-lg', 'rounded-full'];
btn.classList.add(...extraClasses);
add() 具有幂等性。如果要添加的类名已经在元素的 classList 中存在,浏览器会自动忽略本次添加,不会产生重复的 class,也不会引发任何运行时报错。
使用 classList.remove() 删除 class
当某个交互状态结束(如模态框关闭、加载动画完成)需要撤销对应样式时,使用 remove() 方法进行清理。
1. 删除单个或多个类名
const modal = document.querySelector('.modal-window');
// 删除单个类名
modal.classList.remove('visible');
// 批量删除多个类名
modal.classList.remove('fade-in', 'open');
2. 容错与清除边界
remove() 同样具备安全的容错机制:如果要删除的类名并不在当前元素上,方法会静默忽略,不会抛出异常。当删除了元素上的所有类名后,元素在 DOM 中的 class 属性通常会变为空字符串(部分浏览器会在序列化时保留 class="" 或彻底移除该属性),完全符合标准规范。
机制深度解析:classList 与 className 的本质差异
在 classList 普及前,开发者通常通过 element.className 读写类名。理解二者的底层区别,能帮助我们避免很多历史代码遗留的隐患。
element.className 暴露的是整个 class 属性的纯文本字符串。使用它做局部修改时,开发者必须自行管理字符串的拼接、空格隔离以及正则表达式替换。例如想要追加一个类名时,如果写成 btn.className += 'active',一旦原本类名末尾没有空格,就会拼成 "btnactive" 导致样式彻底失效;而如果使用正则替换删除类名,当存在 btn 和 btn-primary 两种相似类名时,不严谨的正则很容易误伤子串。
而 classList 将类名抽象为结构化的 DOMTokenList 集合。每一个类名都是集合中一个独立的 Token。增删操作由浏览器内部的 C++ 引擎直接处理,天然杜绝了空格拼接失误、子串误删和重复累加的问题。
使用 classList.toggle() 切换 class
在折叠菜单展开/收起、暗黑模式切换、复选状态选中等场景中,一个类名往往需要在“存在”与“不存在”之间交替变化。toggle() 方法正是为此设计的。
1. 基础无参切换(Toggle)
当只传入类名一个参数时:如果元素已经包含该类名,则将其删除;如果不包含,则将其添加。该方法会返回一个布尔值,表示操作后该类名是否存在:
const drawer = document.querySelector('#drawer');
// 每次点击时切换 open 状态
const isOpen = drawer.classList.toggle('open');
console.log('当前是否处于展开状态:', isOpen);
// 若成功添加了 'open',返回 true;若移除了 'open',返回 false
2. 条件切换:利用第二个参数 force
toggle() 支持传入第二个可选参数 force(布尔值),这在响应数据驱动状态时极为好用:
- 当
force计算为true时:强制添加该类名(若已存在则保持不变),相当于add(); - 当
force计算为false时:强制移除该类名(若本就不存在则保持不变),相当于remove()。
// 根据实际的滚动高度决定导航栏是否添加 'scrolled' 类
const isScrolled = window.scrollY > 100;
navbar.classList.toggle('scrolled', isScrolled);
// 相比传统的 if-else,代码从五行精简为一行:
// if (isScrolled) { navbar.classList.add('scrolled'); } else { navbar.classList.remove('scrolled'); }
常用辅助方法:contains() 与 replace()
除了添加、删除和切换,classList 还提供了两个在逻辑判断中非常高频的辅助方法:
1. 判断是否存在:classList.contains()
用于检测元素当前是否包含某个特定类名,返回 true 或 false。它完全取代了以往依赖 indexOf() 的繁琐判断:
if (menu.classList.contains('active')) {
console.log('菜单当前处于激活状态');
}
2. 原子替换:classList.replace()
如果需要将一个旧类名平滑迁移为新类名(例如从未选中状态变更为选中状态),使用 replace(oldClass, newClass) 可以一步完成:
const success = badge.classList.replace('badge-pending', 'badge-success');
// 如果 'badge-pending' 存在,则替换为 'badge-success' 并返回 true;
// 如果旧类名不存在,则不做任何改动并返回 false。
常见误区与异常报错排查
以下是新手经常遇到的典型错误写法与正确写法的对比:
// ❌ 错误写法:会抛出 DOMException: Failed to execute 'add' on 'DOMTokenList'
box.classList.add('btn btn-primary');
// ❌ 错误写法:传入空字符串也会抛出 SyntaxError
box.classList.add('');
// ✔ 正确写法:拆分为多个独立的字符串实参
box.classList.add('btn', 'btn-primary');
// ✔ 正确写法:如果拿到的是带空格的字符串,先用 split 拆分为数组再展开
const rawClassString = 'card elevated rounded';
box.classList.add(...rawClassString.split(' ').filter(Boolean));
核心方法速查与总结
classList API 接口设计精炼、职责分明。在现代 Web 开发中,所有与样式类增删改查相关的逻辑,都应当优先选用 classList。
| 方法名称 | 参数示例 | 返回值 | 核心作用与典型场景 |
|---|---|---|---|
add() |
add('a', 'b') |
undefined |
添加一个或多个类名;自动幂等查重,重复添加安全无副作用。 |
remove() |
remove('a', 'b') |
undefined |
移除一个或多个类名;若类名原本不存在直接静默忽略,不报错。 |
toggle() |
toggle('open', force?) |
boolean |
存在则删、不存在则加;配合 force 参数可单行实现条件显隐。 |
contains() |
contains('active') |
boolean |
精确检查是否包含特定类名;用于业务状态前置拦截判断。 |
replace() |
replace('old', 'new') |
boolean |
原子化替换旧类名为新类名;仅在旧类名存在时生效并返回 true。 |
总结来说,掌握 add()、remove() 和 toggle() 的核心用法与 force 条件参数,即可覆盖绝大多数日常交互开发需求,既能保证代码简洁可读,又能彻底杜绝类名拼接与正则替换带来的隐式缺陷。
网页开发三者分工:HTML结构、CSS样式与JavaScript交互怎么协作
2026-11-05 12:51:22
JS解析URL参数时怎么处理中文乱码和特殊字符
2026-11-05 12:47:23
js-cookie 存储 JSON 对象:自动序列化与反序列化技巧
2026-11-05 12:36:26
marked.js 快速上手:安装与基础 Markdown 转 HTML 示例
2026-11-05 09:32:53
Phaser.js 与 PixiJS、Cocos Creator 的技术选型对比
2026-11-05 08:36:30








