本文详解如何利用 Alpine.js 实时获取鼠标在页面中的精确像素坐标(pageX/pageY),自动同步为带 'px' 单位的响应式数据,并结合 Tailwind CSS 实现基于鼠标位置的径向模糊悬停效果。 想让页面元素“追着”鼠标产生动态模糊效果?这听起来很酷,但实现过程中有一个技术细节必须
Alpine.js 中追踪鼠标坐标实现动态径向模糊
作者:技术拾光
时间:2026-06-06
浏览:509
文章目录
本文详解如何利用 Alpine.js 实时获取鼠标在页面中的精确像素坐标(pageX/pageY),自动同步为带 'px' 单位的响应式数据,并结合 Tailwind CSS 实现基于鼠标位置的径向模糊悬停效果。
想让页面元素“追着”鼠标产生动态模糊效果?这听起来很酷,但实现过程中有一个技术细节必须处理好:如何让 Alpine.js 的模板语法直接消费像 '127px' 这样带单位的坐标字符串。
问题的核心在于,我们不仅需要实时捕获鼠标的整数坐标(pageX/pageY),还得将它们自动拼接成 CSS 能识别的、带 px 单位的字符串。更关键的是,这个方案还得足够健壮,能够应对不同浏览器的兼容性问题,尤其是旧版 IE 对 pageX/pageY 支持不佳的情况。
推荐实现方案:Alpine 数据函数 + 兼容性增强的 mousemove 监听
下面这个 Alpine 数据对象定义是一个可以直接投入生产环境的方案,建议将其保存为一个独立的模块文件,例如 blur.js。
export default () => ({
mouseX: 0,
mouseY: 0,
mouseXAsPx: '0px',
mouseYAsPx: '0px',
init() {
// 自动同步数值 → 带单位字符串
this.$watch('mouseX', (val) => (this.mouseXAsPx = `${val}px`));
this.$watch('mouseY', (val) => (this.mouseYAsPx = `${val}px`));
// 高兼容性 mousemove 处理器(支持 IE9+)
const handleMouseMove = (e) => {
const event = e || window.event;
let { pageX, pageY } = event;
// 兜底计算:当 pageX/pageY 不可用时,手动推导(参考 jQuery 源码逻辑)
if (pageX == null) {
const doc = document.documentElement;
const body = document.body;
const clientX = event.clientX;
const clientY = event.clientY;
const scrollLeft = window.pageXOffset || doc.scrollLeft || body.scrollLeft;
const scrollTop = window.pageYOffset || doc.scrollTop || body.scrollTop;
const clientLeft = doc.clientLeft || body.clientLeft || 0;
const clientTop = doc.clientTop || body.clientTop || 0;
pageX = clientX + scrollLeft - clientLeft;
pageY = clientY + scrollTop - clientTop;
}
this.mouseX = Math.round(pageX);
this.mouseY = Math.round(pageY);
this.applyBlur();
};
// 绑定全局监听(注意:若仅需限定于某 div 内,应改用该元素的 addEventListener)
document.addEventListener('mousemove', handleMouseMove);
// 清理:避免内存泄漏(Alpine v3.13+ 支持自动 cleanup,但显式解绑更稳妥)
this.$nextTick(() => {
this.$el.addEventListener('mouseleave', () => {
// 可选:鼠标离开时重置或暂停更新
});
});
},
applyBlur() {
// 此处可触发自定义逻辑,例如:
// - 触发 $dispatch('mouse-move', { x: this.mouseX, y: this.mouseY })
// - 更新 CSS 自定义属性:document.documentElement.style.setProperty('--mouse-x', this.mouseXAsPx)
// - 或直接用于内联样式(见下方模板示例)
}
});
在 HTML 中使用(配合 Tailwind 动态类)
有了数据逻辑,接下来就是在模板中应用它。这里的关键是利用 Alpine 的 :style 绑定来动态生成 CSS 渐变。
X: px, Y: px
注意事项与最佳实践
为了让这个鼠标追踪效果更加完善、性能更优,有几个细节需要特别注意。
- 作用域控制:上面的代码监听的是整个文档(
document)的鼠标移动。如果效果只需要在某个特定的内生效,应将监听器绑定到该元素上。把document.addEventListener(...)替换为this.$el.addEventListener('mousemove', ...),并确保这个容器元素设置了position: relative,这样才能为内部的绝对定位元素或径向渐变提供正确的坐标基准。- 性能优化:
mousemove事件的触发频率非常高,可能会给浏览器带来不小的重绘压力。如果感觉动画有卡顿,可以在事件处理器内部加入requestAnimationFrame进行节流。下面是一个简单的实现思路:let isQueued = false; const rafHandler = () => { this.mouseX = ...; this.mouseY = ...; this.applyBlur(); isQueued = false; }; const throttled = () => { if (!isQueued) { requestAnimationFrame(rafHandler); isQueued = true; } }; // 然后在事件中调用 throttled()- Tailwind 动态类限制:这里有一个常见的“坑”。Tailwind CSS 的动态类(Arbitrary Values)语法,如
bg-[radial-gradient(...)],其内部的at位置参数不支持通过 Alpine 的插值语法(如{{mouseXAsPx}})动态生成。因此,最可靠、最推荐的方式就是像示例中那样,使用:style绑定来直接设置background-image属性。- 移动端适配:
mousemove事件在触摸设备上是不会触发的。如果需要支持手机或平板,必须额外监听touchmove事件,并从event.touches[0]中获取clientX/clientY,再将其转换为页面坐标(pageX/pageY)。搞定以上这些,你就获得了一套稳定、兼容、响应式的鼠标坐标数据流。无论是实现文中的径向模糊、创建悬停高亮区域,还是构建更复杂的交互式粒子动画,都有了精准的空间锚点作为基础。
- 性能优化:
实用工具推荐
电子包浆
使用 ›绿化、压缩、噪点和虚拟水印,自由调节做旧程度。
图片压缩
使用 ›选择画质和输出格式,预览压缩前后的大小。
相关文章