:active伪类无法实现真实水波纹效果,因其仅触发瞬时样式切换,缺乏点击点定位、扩散动画及透明度渐变能力;必须用javascript结合getboundingclientrect()与clientx/clienty计算相对坐标,动态创建span元素并配以scale和opacity的css动画。

为什么直接用 :active 无法实现真实水波纹效果
移动端点击时,:active 伪类往往不触发或延迟明显,尤其在 iOS Safari 上——它依赖于“按下并保持”的手势,而真实点击是瞬时的。更关键的是,:active 只能控制样式切换,无法生成从点击点向外扩散的圆形动画,也就做不到中心定位、透明度渐变、尺寸缩放这些水波纹核心特征。
所以必须用 JavaScript 捕获点击坐标,动态创建一个 span 元素作为涟漪容器,并用 CSS 动画驱动它。
如何用 getBoundingClientRect() 和 clientX/clientY 算出点击相对位置
目标是让水波纹从用户真正点击的位置(而非元素左上角)开始扩散。需要把屏幕坐标转成相对于目标元素内部的偏移量:
-
const rect = target.getBoundingClientRect()获取元素在视口中的位置 -
const x = e.clientX - rect.left计算点击点距元素左侧距离 -
const y = e.clientY - rect.top同理计算距顶部距离 - 注意:如果目标元素有
transform或border,需额外减去borderLeftWidth和borderTopWidth(可通过getComputedStyle获取)
漏掉 border 或未处理 transform 会导致涟漪中心偏移,这是最常被忽略的细节。
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
CSS 动画关键参数怎么设才自然
水波纹不是简单放大消失,它的视觉节奏靠三个 CSS 属性协同控制:
-
transform: scale(0)初始状态必须为 0,否则会有“闪一下” -
opacity: 0.4不能设太高(>0.6 显脏),也不能太低( -
animation: ripple 0.6s ease-out——ease-out比linear更符合物理衰减感;时长 0.5–0.7s 是实测最舒服区间
别忘了加 pointer-events: none 到涟漪元素上,否则它会挡住后续点击;也别漏掉 overflow: hidden 在父容器上,否则涟漪可能溢出圆角边界。
如何避免多次点击触发多个涟漪叠加
快速连点时,若不控制,会堆叠多个 span.ripple,造成卡顿和视觉混乱。解决方式很简单但容易被跳过:
- 给目标元素加
data-ripple-active="true"标记 - 点击前先检查:
if (target.hasAttribute('data-ripple-active')) return; - 动画结束后用
animationend事件移除该属性和 DOM 节点 - 额外建议:加个
setTimeout(() => {}, 100)防抖,过滤误触
移动端手指面积大,实际点击区域比光标大得多,这点防抖比桌面端更重要。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










