点击波纹效果在index.html中的实现:HTML5交互动效设计

作者:袖梨 2026-06-18
波纹效果需父容器设 position: relative,用 getBoundingClientRect() 精准定位圆心,动画用 transform: scale() 避免重排,移动端应监听 pointerdown 事件。

点击区域必须有相对定位才能触发波纹

波纹效果本质是用 position: relative 作为容器,再动态插入绝对定位的 span 圆形元素。如果父容器是默认的 static 定位,波纹会脱离点击位置,飞到页面左上角。

  • 给所有要加波纹的元素(比如 <button><div class="ripple">)加上 position: relative
  • 不要依赖父级全局设置,每个可点击块都得单独声明,否则移动端容易失效
  • 如果用了 CSS 框架(如 Bootstrap),检查是否被 .btn 等类重置了定位 —— 建议显式覆盖:.btn { position: relative !important; }

getBoundingClientRect() 是定位波纹中心的关键

event.clientX / clientY 算坐标在滚动页面时会偏移,必须用 element.getBoundingClientRect() 获取元素视口内位置,再减去元素左上角偏移,才能精准定位圆心。

  • 错误写法:const x = e.clientX - e.target.offsetLeft(滚动时错)
  • 正确写法:
    const rect = e.target.getBoundingClientRect();<br>const x = e.clientX - rect.left;<br>const y = e.clientY - rect.top;
  • 注意:rect 返回的是浮点数,但 CSS left/top 支持小数,无需 Math.round(),反而会抖动

波纹动画要用 transform: scale() 而非 width/height

直接改 widthheight 触发 layout,帧率掉得厉害;用 transform: scale() 只走合成层,60fps 更稳,尤其在低端安卓机上。

  • 初始波纹元素样式必须设 transform: scale(0)transform-origin: center
  • 动画结束时记得用 setTimeout 清除 DOM,否则大量点击后内存泄漏:setTimeout(() => ripple.remove(), 500)(500ms 对应 CSS 动画时长)
  • 别忘了加过渡:transition: transform 0.5s cubic-bezier(0.2, 0.8, 0.2, 1),比 ease-out 更自然

移动端 click 事件有 300ms 延迟,改用 touchstart

在 iOS 和部分安卓浏览器里,click 触发太慢,波纹响应滞后明显。必须监听 touchstart,并兼容鼠标设备用 pointerdown 更稳妥。

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

  • 推荐写法:el.addEventListener('pointerdown', handler, { passive: false })
  • passive: false 是必须的,否则 iOS Safari 会忽略 preventDefault()(虽然这里不一定需要,但留着不碍事)
  • 避免同时绑 clicktouchstart —— 会导致双触发,用 pointerdown 一个事件足矣

实际效果取决于三个地方:定位是否随滚动实时校准、缩放是否走 GPU 合成、事件是否绕过 click 延迟。漏掉任意一点,波纹就会“飘”“卡”或“延迟”。

相关文章

精彩推荐