新闻中心
使用jQuery实现卡片内信息面板的折叠与展开(手风琴效果)

本教程详细介绍了如何使用jquery高效地管理卡片(card)内部信息面板(div)的显示与隐藏。通过优化事件绑定机制,利用`closest()`和`find()`进行精确的dom元素定位,并提供两种核心切换逻辑:独立的面板切换和手风琴式(一次只展开一个)的面板切换,旨在帮助开发者构建更简洁、功能更完善的交互式ui组件。
在现代网页设计中,卡片式布局(Card Layout)因其清晰的结构和良好的信息组织能力而广受欢迎。在这些卡片中,常常需要点击按钮来显示或隐藏额外的详细信息。本文将指导您如何使用jQuery,以一种高效且易于维护的方式实现这一功能,包括支持多个面板独立切换和实现手风琴(Accordion)效果。
HTML 结构
首先,我们需要一个清晰的HTML结构来表示卡片、按钮和待切换的信息面板。关键在于将信息面板(例如 .more-info-panel)嵌套在卡片(.coin-card)内部,并默认添加一个 hidden 类来隐藏它。
<div class="coin-card">
<div class="headInfo">
<p class="coin-symbol">btc</p>
<!-- 其他头部信息 -->
</div>
<p class="coin-name">Bitcoin</p>
<!-- 移除按钮上的 onclick 属性,我们将使用 jQuery 绑定事件 -->
<button class="btn btn-info mybtn" data-toggle="collapse" data-target="info">More Info</button>
<div class="more-info-panel hidden" symbol="bitcoin">
@@##@@
<p class="info-title">Coin Prices:</p>
<p class="usd">USD: $30</p>
<p class="eur">EUR: €30</p>
<p class="ils">ILS: ₪30</p>
</div>
</div>
<!-- 可以有多个这样的卡片 -->
<div class="coin-card">
<!-- ... 另一个卡片的内容 ... -->
</div>关键点:
- 每个卡片是一个 .coin-card 容器。
- 按钮是 .btn-info,位于 .coin-card 内部。
- 信息面板是 .more-info-panel,也位于 .coin-card 内部,并且初始状态带有 hidden 类。
- 重要: 从按钮上移除 onclick="handleMoreInfo()" 属性,我们将通过jQuery统一管理事件。
CSS 样式
为了让 hidden 类生效,我们需要定义相应的CSS样式来控制元素的显示与隐藏。最简单的方式是使用 display: none;。
.coin-card {
border: 1px solid #ccc;
margin: .5rem;
padding: 1rem;
float: left; /* 示例布局 */
width: 20%; /* 示例布局 */
box-sizing: border-box; /* 确保 padding 不会增加总宽度 */
}
p {
margin: 0;
}
/* 隐藏信息面板的核心样式 */
.coin-card .more-inf
o-panel.hidden {
display: none;
}jQuery 核心逻辑
现在,我们将使用jQuery来处理按钮点击事件,并切换信息面板的可见性。
1. 事件绑定
使用jQuery的 .on('click', ...) 方法来绑定事件。推荐将事件绑定到按钮的类上,而不是直接在HTML中写 onclick。
火龙果写作
用火龙果,轻松写作,通过校对、改写、扩展等功能实现高质量内容生产。
277
查看详情
// 确保在DOM加载完成后执行
$(document).ready(function() {
// 绑定点击事件到所有 .coin-card 内部的 .btn-info 按钮
$('.coin-card .btn-info').on('click', async function() {
// 'this' 指向被点击的按钮元素
// 使用 closest() 向上查找最近的 .coin-card 父元素
const $card = $(this).closest('.coin-card');
// 使用 find() 向下查找当前卡片内的 .more-info-panel
const $infoPanel = $card.find('.more-info-panel');
// 在这里可以添加异步数据获取逻辑,例如:
// const coinName = $card.find('.coin-name').text().toLowerCase();
// const data = await fetchMoreInfo(coinName);
// if (data) {
// // 更新面板内容
// $infoPanel.find('.more-info-image').prop("src", data?.image?.large);
// $infoPanel.find('.usd').text(`USD: $${data?.market_data?.current_price?.usd}`);
// // ... 其他数据更新
// }
// 选择一种切换行为:
// 方式一:独立切换(每个面板独立开关,互不影响)
// $infoPanel.toggleClass('hidden');
// 方式二:手风琴效果(点击一个按钮时,关闭所有其他面板,然后打开当前面板)
const isOpen = !$infoPanel.hasClass('hidden'); // 检查当前面板是否即将打开(或已经打开)
// 1. 关闭所有其他卡片的信息面板
$('.coin-card .more-info-panel').addClass('hidden');
// 2. 如果当前面板之前是关闭的(即isOpen为true),则打开它
if (isOpen) {
$infoPanel.removeClass('hidden');
}
});
});代码解析:
- $(document).ready(function() { ... });:确保在DOM完全加载后再执行J*aScript代码。
- $('.coin-card .btn-info').on('click', ...):这是一个高效的事件委托方式,它只绑定一次事件处理函数到所有匹配的按钮上。当按钮被点击时,这个函数就会执行。
- const $card = $(this).closest('.coin-card');:$(this) 指向被点击的按钮。closest('.coin-card') 方法向上遍历DOM树,找到最近的父级 .coin-card 元素。这确保了我们操作的是正确卡片内部的元素。
- const $infoPanel = $card.find('.more-info-panel');:find('.more-info-panel') 方法向下查找当前卡片($card)内部的 .more-info-panel 元素。这样可以精确地定位到需要切换的面板。
- 独立切换 ($infoPanel.toggleClass('hidden');):这是最简单的切换方式。toggleClass() 会根据元素是否包含指定类来添加或移除它。如果存在,则移除;如果不存在,则添加。
-
手风琴效果逻辑:
- const isOpen = !$infoPanel.hasClass('hidden');:在执行任何操作之前,先判断当前点击的面板在执行操作后是否会是打开状态。如果它当前是隐藏的(hasClass('hidden') 为 true),那么 !true 就是 false,表示点击后会打开。如果它当前是显示的,那么 !false 就是 true,表示点击后会关闭。
- $('.coin-card .more-info-panel').addClass('hidden');:这一步是手风琴效果的关键。它会选择页面上所有 .coin-card 内部的 .more-info-panel,并为它们添加 hidden 类,从而关闭所有已打开的面板。
- if (isOpen) { $infoPanel.removeClass('hidden'); }:在所有面板都被关闭后,如果当前点击的面板在操作前是关闭状态(即 isOpen 为 true),那么就重新打开它。这样就实现了点击一个按钮,关闭其他面板,并打开当前面板的效果。如果点击的是一个已经打开的面板,isOpen 会是 false,它会被关闭,但不会再被重新打开。
2. 异步数据获取与显示(可选)
如果您的面板内容需要从后端动态加载,可以在事件处理函数中集成异步请求。
// ... 在 .on('click', function() { ... } 内部 ...
// 示例:获取数据并更新面板
// 假设您有一个 fetchMoreInfo 函数来获取数据
// const coinID = ($card.find('.coin-name').text()).toLowerCase();
// const data = await fetchMoreInfo(coinID); // 假设 fetchMoreInfo 是一个异步函数
// if (data) {
// $infoPanel.find('.more-info-image').prop("src", data?.image?.large);
// $infoPanel.find('.usd').text(`USD: $${data?.market_data?.current_price?.usd}`);
// $infoPanel.find('.eur').text(`EUR: €${data?.market_data?.current_price?.eur}`);
// $infoPanel.find('.ils').text(`ILS: ₪${data?.market_data?.current_price?.ils}`);
// }
// ...完整示例
将上述HTML、CSS和jQuery代码整合在一起,即可实现功能。请确保引入jQuery库。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>jQuery 卡片信息面板切换</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
background-color: #f4f4f4;
}
.container {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.coin-card {
border: 1px solid #ddd;
border-radius: 8px;
background-color: #fff;
padding: 1rem;
width: calc(33% - 1rem); /* 示例:每行3个卡片 */
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
float: left; /* 用于旧版浏览器兼容或特定布局 */
box-sizing: border-box;
margin-bottom: 1rem;
}
.coin-card:hover {
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
}
p {
margin: 0 0 .5rem 0;
line-height: 1.5;
}
.headInfo {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: .5rem;
}
.coin-symbol {
font-weight: bold;
text-transform: uppercase;
color: #555;
}
.coin-name {
font-size: 1.2em;
font-weight: bold;
color: #333;
margin-bottom: 1rem;
}
.btn-info {
background-color: #007bff;
color: white;
border: none;
padding: 8px 15px;
border-radius: 5px;
cursor: pointer;
font-size: 0.9em;
transition: background-color 0.2s ease;
margin-top: 10px;
}
.btn-info:hover {
background-color: #0056b3;
}
.more-info-panel {
margin-top: 1rem;
padding-top: 1rem;
border-top: 1px dashed #eee;
color: #666;
}
.more-info-panel.hidden {
display: none;
}
.more-info-image {
max-width: 100%;
height: auto;
border-radius: 5px;
margin-bottom: 10px;
}
.info-title {
font-weight: bold;
color: #444;
margin-bottom: 5px;
}
.usd, .eur, .ils {
margin-bottom: 3px;
}
</style>
</head>
<body>
<div class="container">
<div class="coin-card">
<div class="headInfo">
<p class="coin-symbol">btc</p>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch">
<label class="form-check-label"></label>
</div>
</div>
<p class="coin-name">Bitcoin</p>
<button class="btn btn-info mybtn" data-toggle="collapse" data-target="info">More Info</button>
<div class="more-info-panel hidden" symbol="bitcoin">
@@##@@
<p class="info-title">Coin Prices:</p>
<p class="usd">USD: $30000</p>
<p class="eur">EUR: €28000</p>
<p class="ils">ILS: ₪100000</p>
</div>
</div>
<div class="coin-card">
<div class="headInfo">
<p class="coin-symbol">eth</p>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch">
<label class="form-check-label"></label>
</div>
</div>
<p class="coin-name">Ethereum</p>
<button class="btn btn-info mybtn" data-toggle="collapse" data-target="info">More Info</button>
<div class="more-info-panel hidden" symbol="ethereum">
@@##@@
<p class="info-title">Coin Prices:</p>
<p class="usd">USD: $2000</p>
<p class="eur">EUR: €1800</p>
<p class="ils">ILS: ₪7000</p>
</div>
</div>
<div class="coin-card">
<div class="headInfo">
<p class="coin-symbol">doge</p>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch">
<label class="form-check-label"></label>
</div>
</div>
<p class="coin-name">Dogecoin</p>
<button class="btn btn-info mybtn" data-toggle="collapse" data-target="info">More Info</button>
<div class="more-info-panel hidden" symbol="dogecoin">
@@##@@
<p class="info-title">Coin Prices:</p>
<p class="usd">USD: $0.07</p>
<p class="eur">EUR: €0.06</p>
<p class="ils">ILS: ₪0.25</p>
</div>
</div>
</div>
<script>
$(document).ready(function() {
$('.coin-card .btn-info').on('click', async function() {
const $card = $(this).closest('.coin-card');
const $infoPanel = $card.find('.more-info-panel');
// 异步数据获取(如果需要)
// const coinName = $card.find('.coin-name').text().toLowerCase();
// const data = await fetchMoreInfo(coinName); // 假设 fetchMoreInfo 存在并返回数据
// if (data) {
// $infoPanel.find('.more-info-image').prop("src", data?.image?.large);
// $infoPanel.find('.usd').text(`USD: $${data?.market_data?.current_price?.usd}`);
// $infoPanel.find('.eur').text(`EUR: €${data?.market_data?.current_price?.eur}`);
// $infoPanel.find('.ils').text(`ILS: ₪${data?.market_data?.current_price?.ils}`);
// }
// 选择一种切换行为:
// 方式一:独立切换(取消下面两行的注释,并注释掉手风琴逻辑)
// $infoPanel.toggleClass('hidden');
// 方式二:手风琴效果(默认启用,如果需要独立切换请注释掉此段并启用方式一)
const isOpen = !$infoPanel.hasClass('hidden'); // 判断当前面板是否即将打开(或已经打开)
// 关闭所有其他卡片的信息面板
$('.coin-card .more-info-panel').addClass('hidden');
// 如果当前面板之前是关闭的,则打开它
if (isOpen) {
$infoPanel.removeClass('hidden');
}
});
});
</script>
</body>
</html>注意事项
- 避免混用事件绑定方式: 避免在HTML元素的 onclick 属性中直接编写J*aScript代码,同时又通过jQuery的 .on() 方法绑定事件。这会导致事件重复触发、逻辑混乱,并且难以调试和维护。推荐统一使用jQuery的事件绑定机制。
- 精确的DOM遍历: 利用jQuery提供的 closest() 和 find() 等方法,可以高效且精确地定位到目标元素。closest() 用于向上查找父级元素,find() 用于向下查找子级元素。这比使用全局选择器或复杂的DOM操作更具性能和可读性。
- 选择合适的切换逻辑: 根据您的UI需求,选择独立的面板切换(toggleClass())或手风琴效果。手风琴效果通常在空间有限或需要聚焦用户注意力的场景下更为适用。
- 异步内容加载: 如果面板内容是动态加载的,请确保在切换可见性之前或之后,正确处理异步请求和数据更新。使用 async/await 可以使异步代码更易读。
- 性能优化: 对于大量卡片的场景,jQuery的事件委托(例如将事件绑定到父容器,然后使用 $(document).on('click', '.coin-card .btn-info', function(){...}))可以进一步优化性能,减少事件处理器的数量。但在本示例中,直接绑定到按钮已足够高效。
总结
通过本教程,您应该已经掌握了如何使用jQuery来高效地控制卡片内信息面板的显示与隐藏。核心在于:
- 简化HTML,移除 onclick。
- 利用CSS的 display: none; 和 hidden 类来控制可见性。
- 通过jQuery的 .on('click') 绑定事件,并使用 closest() 和 find() 精确定位元素。
- 根据需求选择独立的 toggleClass() 或手风琴式的切换逻辑。
这种方法不仅代码更简洁、可读性更强,而且更易于维护和扩展,是构建响应式和交互式Web界面时的推荐实践。

以上就是使用jQuery实现卡片内信息面板的折叠与展开(手风琴效果)的详细内容,更多请关注其它相关文章!
# 的是
# 网络营销推广实操考试内容
# 兴宁网站关键词排名优化
# 网站建设报告大学推荐
# 宁夏服务网站建设
# seo产品销售好做嘛
# 佛山抖音营销推广方式
# 东海SEO优化哪里有
# 深圳最好的seo外包
# seo排名原则
# 人工智能会取代SEO
# 遍历
# 多个
# 如何使用
# 您的
# 是一个
# css
# 复选框
# 加载
# 移除
# 绑定
# switch
# ai
# 后端
# 浏览器
# 处理器
# ajax
# js
# html
# jquery
# java
# javascript
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
Windows10怎么开启夜间模式 Windows10系统设置调整色温与亮度缓解夜间用眼疲劳【教程】
漫蛙Manwa2官网入口地址分享 漫蛙漫画PC版永久访问通道
网站内容防复制粘贴的实现策略与局限性
PHP中获取MongoDB服务器运行时间(Uptime)的专业指南
qq游戏网页版直接玩_qq游戏免下载快速入口
深入理解Promise链:如何在catch后中断then的执行
Lar*el的路由模型绑定怎么用_Lar*el Route Model Binding简化控制器逻辑
Win11怎么设置开机NumLock亮 Win11修改注册表InitialKeyboardIndicators值
Win11怎么隐藏桌面图标 Win11一键隐藏所有桌面元素及恢复显示
包子漫画官方网站阅读入口-包子漫画在线漫画官网直达链接
夸克AO3官网入口_AO3镜像网站2025推荐
在React函数组件中利用原生HTML5进行邮箱地址验证
Win11如何使用Windows Sandbox Win11沙盒功能开启与使用教程【详解】
期待已久:小米17 Ultra、小米首款NAS本月登场
AO3镜像入口大全 AO3网页版内容访问全集
c++ 获取系统当前时间 c++时间戳获取方法
邮政快递单号查询入口 邮政快递物流信息在线查询入口
在J*a中如何在J*a中使用异常机制记录错误日志_异常日志实践经验
C++如何实现一个装饰器模式_C++设计模式之动态地给对象添加额外职责
Node.js 中使用 node-cron 实现定时 API 数据抓取与处理
steam官方入口大全 steam账号注册及操作指南
《刺客信条:影》PS5 Pro和Switch 2画面对比
Mac怎么查看崩溃日志_Mac控制台错误报告分析
在Blazor WebAssembly应用中动态注入客户端特定指标代码的策略
《明末:渊虚之羽》设计师谈设计角色:那会刚毕业 充满激情
在WordPress中通过REST API获取BasicAuth保护的远程文章
React/Next.js中实现列表项的动态选择与移动
2025年云电脑操作系统体验 | 无需本地硬件,随时随地使用高性能PC
css绝对定位元素脱离父容器怎么办_确保父元素position非static
大象笔记网页版入口 印象笔记网页版登录入口
J*a TimerTask中HashMap意外清空的深层原因与解决方案
如何使用Node.js csv 包按条件移除含空字段的CSV记录
如何设置Windows Defender的定时扫描_计划任务实现自动杀毒【安全】
QQ邮箱稳定登录入口_QQ邮箱官方网站网页版使用
如何使用Rector自动化升级旧代码_通过Composer安装和配置Rector进行代码重构
《马克思佩恩3》早期版本曝光 UI设计曾多次调整!
outlook中文官网入口地址 outlook官方中文版直达首页链接
如何将HTML表格多行数据保存到Google Sheets
电脑IP地址怎么查 查看本机IP地址的几种方法
Bilibili动漫最新防封地址发布-Bilibili动漫2025年最稳正版入口推荐
Linux如何构建多环境配置管理_Linux多环境配置方案
怎样更改Windows系统的默认安装路径_避免C盘爆满的终极设置【技巧】
蛙漫2日版入口 WAMAN2(日版)无删减漫画官网链接
MongoDB聚合管道:正确匹配对象数组中_id的方法
ExcelARRAYTOTEXT函数怎么自定义分隔符输出数组文本_ARRAYTOTEXT实现动态生成SQL语句
夸克浏览器图书入口 夸克手机浏览器阅读入口
照顾宝贝2小游戏免费秒玩入口
b站赚钱渠道_b站收益来源
Django模型中自动计算可用余额的实现方法
Lar*el递归关系中排除子孙节点的策略


2025-10-19
浏览次数:次
返回列表
o-panel.hidden {
display: none;
}