本质是将鼠标相对于按钮的坐标转为box-shadow偏移量,需用getboundingclientrect()获取按钮位置、监听按钮自身mousemove事件、计算相对坐标并限制偏移范围(-10px~+10px),配合大模糊值(≥20px)和低透明度rgba色实现包裹感光晕;移动端须同时监听touchmove并适配坐标取值。

用 mousemove 获取鼠标坐标并动态设置 box-shadow
光晕效果本质是给按钮加一个随鼠标位置偏移的柔和阴影,关键不是“追踪鼠标”,而是把鼠标相对于按钮左上角的坐标(clientX/clientY)转成 box-shadow 的 x 和 y 偏移量。直接用全局坐标会错位,必须减去按钮自身位置。
- 先用
getBoundingClientRect()拿到按钮在视口中的left和top - 监听按钮的
mousemove事件(不是document),避免跨元素跳变 - 计算相对坐标:
const x = e.clientX - rect.left,y同理 - 把
x、y套进box-shadow: ${x}px ${y}px 20px rgba(0,100,255,0.4)即可
为什么不能用 document.addEventListener('mousemove')?
监听整个文档会导致鼠标一离开按钮区域,光晕就消失或错位——因为此时 e.clientX 还在变化,但按钮已不响应事件。更糟的是,如果页面有滚动,document 坐标和按钮实际渲染位置不同步,阴影会漂移。
- 只对目标按钮绑定
addEventListener('mousemove', handler) - 如果按钮是动态生成的,用事件委托也行,但需确保委托容器尺寸稳定
- 记得在不需要时调用
removeEventListener,避免内存泄漏
box-shadow 参数怎么调才像“光晕”而不是“投影”?
真正发光感靠的是模糊半径大、颜色浅、无偏移或极小偏移。很多人误设成 10px 10px 30px blue,结果看起来像斜角投影,不是悬浮光晕。
- 偏移量建议控制在
-10px ~ +10px范围内,太大就失去“包裹感” - 模糊值至少
20px,配合rgba(r,g,b,0.2~0.4)才通透 - 可以叠加多层阴影模拟渐变光晕:
"0 0 15px rgba(0,120,255,0.3), 0 0 30px rgba(0,80,220,0.15)"
移动端触摸屏怎么适配?
手机没有 mousemove,得监听 touchmove,且事件对象里坐标字段不同:要用 e.touches[0].clientX 替代 e.clientX。否则在 iOS 上完全没反应。
- 监听时同时注册
mousemove和touchmove,共用同一处理函数 - 从事件对象取坐标前先判断:
const clientX = e.touches ? e.touches[0].clientX : e.clientX - 注意
touchmove默认可能触发滚动,加{ passive: false }并在 handler 里调e.preventDefault()
光晕效果看着简单,但坐标系转换和事件源选择稍有偏差,阴影就会“飘”在按钮外或卡死不动。最常被忽略的是没限制偏移范围——鼠标快速划过时 x/y 瞬间飙到几百,反而让光晕炸开。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











