气泡需用 position: fixed 定位并禁用 transform;mousemove 须用 requestanimationframe 节流;内容区域应设 pointer-events: none 或加距离判断防闪烁;移动端需处理 touchstart/touchmove 并做环境隔离。

气泡元素必须用 fixed 定位
绝对定位(position: absolute)在滚动时会脱离视口跟随,导致气泡错位;只有 position: fixed 才能绑定到视口坐标,确保始终贴着鼠标。气泡本身不能设 transform(比如 scale 或 translate),否则 getBoundingClientRect() 计算偏移会失准。
监听 mousemove 时要节流
原生 mousemove 在高速移动下每秒触发数十次,直接更新样式会造成卡顿。建议用 requestAnimationFrame 节流,或简单用 setTimeout 防抖(延迟 ≤ 16ms):
let rafId = null;
document.addEventListener('mousemove', (e) => {
if (rafId) cancelAnimationFrame(rafId);
rafId = requestAnimationFrame(() => {
bubble.style.left = `${e.clientX + 12}px`;
bubble.style.top = `${e.clientY + 12}px`;
});
});
气泡内容需避免触发自身 mouseenter/mouseleave
如果气泡内有文字、图标或透明区域,鼠标移入可能触发 mouseenter,导致气泡反复显示/隐藏。解决方法有三:
- 给气泡加
pointer-events: none,让事件穿透(适合纯展示) - 若需交互(如点击关闭),改用
pointer-events: auto并在mousemove中加距离判断:只在距目标元素20px内才显示 - 用
event.relatedTarget过滤是否来自气泡内部的移入事件
移动端适配要单独处理 touchstart/touchmove
手机端没有 mousemove,且 touchmove 默认会触发滚动,需 preventDefault()。同时注意:
-
touches[0]取第一个触点,而非changedTouches[0] - iOS Safari 下
fixed元素在滚动时可能闪烁,可加will-change: transform缓解 - 触摸屏无 hover 状态,别依赖
:hover控制气泡显隐
真正麻烦的是混合设备(带触控笔的 Windows 笔记本)——它既发 mousemove 又发 touchstart,得用 if ('ontouchstart' in window) 做环境隔离,不然气泡会双倍更新。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











