讲师中心 微信公众号

工具推荐

视频效率加速
立刻MV
立刻MV

低成本歌曲 MV、视频生成

Seko
Seko

AI短剧一键生成成片

AniShort
AniShort

AI短剧协同制作平台

updream

一键生成高质量推广成片

深入理解:使用CSS和JavaScript实现悬停时对同组非当前元素添加样式

云辰君_6502

云辰君_6502

发布时间:2025-12-09 11:19:07

|

484人浏览过

|

来源于php中文网

原创

深入理解:使用CSS和JavaScript实现悬停时对同组非当前元素添加样式

本教程探讨如何实现当鼠标悬停在一组元素中的某个元素上时,为该组中除当前悬停元素之外的其他元素添加或移除特定样式。文章将详细介绍两种主要实现方式:纯css解决方案,利用父级`:hover`和子级`:not(:hover)`伪类组合;以及基于vanilla javascript的事件监听和`classlist`操作。通过具体代码示例和解析,帮助开发者根据项目需求选择最合适的交互实现方案。

在前端开发中,我们经常需要实现复杂的交互效果。其中一个常见的需求是,当用户鼠标悬停在一组元素中的某个特定元素上时,不是改变当前元素的样式,而是改变同组中其他非悬停元素的样式。例如,在一个列表或卡片组中,当鼠标悬停在第二项时,希望第一项和第三项的背景色发生变化。本文将详细介绍两种实现这种效果的专业方法。

方法一:纯CSS实现(推荐)

对于大多数此类需求,纯CSS解决方案是首选,因为它更简洁、性能更好,并且不需要额外的JavaScript代码。这种方法的核心在于利用CSS的伪类选择器组合:父元素的:hover状态与子元素的:not(:hover)状态。

实现原理

  1. 外部容器的:hover: 当鼠标悬停在包含所有子元素的父容器上时,表示整个组处于“活跃”状态。
  2. 子元素的:not(:hover): 在父容器处于:hover状态时,选择所有不是当前鼠标悬停目标的子元素。

示例代码

首先,我们需要一个HTML结构,将所有目标子元素包裹在一个父容器中。

HTML 结构:

立即学习“Java免费学习笔记(深入)”;

<div class="wrapper">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>

CSS 样式:

.wrapper {
  display: flex; /* 便于展示,非核心功能 */
  gap: 10px;
  border: 1px solid #ccc;
  padding: 10px;
}

.wrapper div {
  padding: 15px;
  border: 1px solid #eee;
  background-color: #f9f9f9;
  transition: background 0.3s ease; /* 添加过渡效果 */
}

/* 核心样式:当鼠标悬停在 .wrapper 上时,
   选择其中所有非当前悬停的 div 元素,并应用背景色 */
.wrapper:hover div:not(:hover) {
  background: red;
  color: white;
}

解析

  • .wrapper:hover: 这个选择器首先匹配当鼠标悬停在.wrapper元素上时的状态。
  • div:not(:hover): 在.wrapper处于悬停状态时,这个部分进一步筛选出所有子div元素中,当前鼠标没有悬停在其自身上的那些元素。

通过这种组合,我们精确地定位到了在父容器悬停时,所有非当前悬停子元素,并为它们应用了background: red的样式。

优点

  • 简洁高效: 无需编写JavaScript,代码量少。
  • 性能优异: 浏览器原生处理CSS伪类,性能开销小。
  • 易于维护: 样式和结构分离,逻辑清晰。

方法二:JavaScript 实现

虽然CSS方法简单有效,但在某些复杂场景下,例如需要动态添加/移除的类名、根据更复杂的逻辑判断、或者与后端数据交互时,JavaScript提供了更高的灵活性和控制力。

JavaScript 开发专家
JavaScript 开发专家

掌握包含 ES6+、异步模式和 Node.js API 的现代 JavaScript。处理 Promise、事件循环和浏览器/Node 兼容性。在 JavaSc

下载

实现原理

  1. 事件监听: 为每个子元素添加mouseenter和mouseleave事件监听器。
  2. 状态判断: 在事件触发时,判断是鼠标进入 (mouseenter) 还是鼠标离开 (mouseleave)。
  3. 遍历与操作: 遍历所有子元素,为除当前触发事件的元素之外的其他元素添加或移除指定类。

示例代码

我们将使用Vanilla JavaScript来操作DOM。

HTML 结构:

立即学习“Java免费学习笔记(深入)”;

与CSS方法相同,需要一个父容器包裹子元素。

<div class="wrapper">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>

CSS 样式:

我们需要定义一个表示“活跃”状态的类,例如.red。

.wrapper {
  display: flex;
  gap: 10px;
  border: 1px solid #ccc;
  padding: 10px;
}

.wrapper div {
  padding: 15px;
  border: 1px solid #eee;
  background-color: #f9f9f9;
  transition: background 0.3s ease;
}

/* 定义要添加/移除的样式类 */
.red {
  background: red;
  color: white;
}

JavaScript 代码:

// 1. 获取所有目标 div 元素
const elDivs = document.querySelectorAll(".wrapper div");

/**
 * 切换非当前悬停 div 元素的样式类
 * @param {Event} evt - 触发的事件对象
 */
const toggleClassDivs = (evt) => {
  // 判断事件类型,确定是添加还是移除类
  const isEnter = evt.type === "mouseenter";

  // 遍历所有 div 元素
  elDivs.forEach(el => {
    // 如果是鼠标进入,则为所有元素添加 'red' 类
    // 如果是鼠标离开,则为所有元素移除 'red' 类
    el.classList[isEnter ? "add" : "remove"]("red");
  });

  // 移除当前悬停元素自身的 'red' 类
  // 这样就实现了“除了我,其他都变色”的效果
  evt.currentTarget.classList.remove("red");
};

// 2. 为每个 div 元素添加事件监听器
elDivs.forEach(el => {
  el.addEventListener("mouseenter", toggleClassDivs);
  el.addEventListener("mouseleave", toggleClassDivs);
});

解析

  1. document.querySelectorAll(".wrapper div"): 选取所有.wrapper容器内的div元素,并将它们存储在一个NodeList中。
  2. toggleClassDivs(evt) 函数:
    • const isEnter = evt.type === "mouseenter";: 判断当前触发的事件是mouseenter(鼠标进入)还是mouseleave(鼠标离开)。
    • elDivs.forEach(el => el.classList[isEnter ? "add" : "remove"]("red"));: 遍历所有的div元素。如果isEnter为true,则为所有元素添加red类;如果为false,则为所有元素移除red类。
    • evt.currentTarget.classList.remove("red");: 这一步是关键。在所有元素都被统一处理后,我们单独将当前触发事件的元素(evt.currentTarget)的red类移除。这样就实现了“除了当前元素,其他元素都变色”的效果。
  3. 事件绑定: elDivs.forEach(el => { ... }); 循环为每个div元素分别绑定了mouseenter和mouseleave事件,当鼠标进入或离开该元素时,都会调用toggleClassDivs函数。

优点

  • 高度灵活: 可以实现更复杂的逻辑,例如根据数据动态改变类名,或者触发其他JavaScript函数。
  • 状态管理: 可以在JavaScript中管理元素的“活跃”状态,便于后续操作。
  • 跨浏览器兼容性: Vanilla JavaScript通常具有良好的兼容性。

总结与选择建议

  • 首选CSS方法: 对于简单的“悬停时改变非当前元素样式”的需求,纯CSS解决方案(利用.wrapper:hover div:not(:hover))是最推荐的方式。它代码量少、性能高、易于理解和维护。
  • JavaScript方法适用于复杂场景: 当你需要:
    • 根据更复杂的条件判断来添加/移除类。
    • 动态地决定要添加的类名。
    • 在悬停事件中触发其他JavaScript逻辑或API调用。
    • 处理大量元素,且CSS选择器可能变得过于复杂时(虽然在这种情况下JS也需优化)。

在实际开发中,应优先考虑使用CSS来处理样式和简单的交互,只有当CSS无法满足需求时,才引入JavaScript来增强交互逻辑。

热门AI工具

更多
音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Flowith
Flowith Hot

Flowith是一款基于画布和智能体工作流的 AI 协作工作空间。

函子Zion

一款支持AI搭建、可视化编辑和多端发布的全栈无代码开发平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

相关专题

更多
php中foreach用法
php中foreach用法

本专题整合了php中foreach用法的相关介绍,阅读专题下面的文章了解更多详细教程。

838

2025.12.04

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

2458

2023.09.20

js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

4996

2023.06.20

js获取当前时间
js获取当前时间

JS全称JavaScript,是一种具有函数优先的轻量级,解释型或即时编译型的编程语言;它是一种属于网络的高级脚本语言,主要用于Web,常用来为网页添加各式各样的动态功能。js怎么获取当前时间呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1455

2023.07.28

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1938

2023.08.03

js是什么意思
js是什么意思

JS是JavaScript的缩写,它是一种广泛应用于网页开发的脚本语言。JavaScript是一种解释性的、基于对象和事件驱动的编程语言,通常用于为网页增加交互性和动态性。它可以在网页上实现复杂的功能和效果,如表单验证、页面元素操作、动画效果、数据交互等。

10523

2023.08.17

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

1060

2023.09.01

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

3184

2023.09.04

Go-Zero API开发使用教程
Go-Zero API开发使用教程

本专题聚焦Go-Zero的API开发,拆解.api描述文件的语法结构、路由与分组定义、参数绑定与校验规则,说明统一响应体、JWT鉴权、跨域与接口文档生成的落地方式,并给出网关聚合与接口测试的实践建议。

20

2026.11.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn