最基础版(文本直接跟随鼠标)
这是最直接的方法,文本的左上角会精确地定位在鼠标指针的位置。

(图片来源网络,侵删)
实现思路
- HTML: 创建一个用于显示跟随文本的
<span>或<div>元素。 - CSS: 将该元素设置为
position: absolute(绝对定位),并设置一些基本样式(如颜色、字体、指针事件pointer-events: none防止它遮挡鼠标)。 - JavaScript:
- 监听整个文档的
mousemove事件。 - 在事件触发时,获取鼠标的
clientX和clientY坐标。 - 将获取到的坐标直接赋给该元素的
style.left和style.top属性。
- 监听整个文档的
完整代码示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">基础文本跟随鼠标</title>
<style>
body {
height: 100vh;
margin: 0;
background-color: #f0f0f0;
overflow: hidden; /* 防止页面滚动条出现 */
cursor: none; /* 可选:隐藏默认鼠标指针 */
}
#follower {
position: absolute;
color: #333;
font-size: 20px;
font-family: 'Arial', sans-serif;
/* 关键样式:绝对定位,并设置初始位置 */
left: 0px;
top: 0px;
pointer-events: none; /* 防止文本元素捕获鼠标事件,避免卡顿 */
user-select: none; /* 防止用户选中跟随的文本 */
}
</style>
</head>
<body>
<span id="follower">你好,世界!</span>
<script>
// 1. 获取要移动的元素
const follower = document.getElementById('follower');
// 2. 监听 mousemove 事件
document.addEventListener('mousemove', (event) => {
// 3. 获取鼠标的 X 和 Y 坐标
const x = event.clientX;
const y = event.clientY;
// 4. 将坐标应用到元素的 style 上
follower.style.left = x + 'px';
follower.style.top = y + 'px';
});
</script>
</body>
</html>
优化版(文本中心对准鼠标)
基础版中,文本的左上角在鼠标位置,看起来不太自然,我们可以让文本的中心点对准鼠标。
实现思路
与基础版类似,但在设置 left 和 top 时,需要减去文本自身宽度和高度的一半。
完整代码示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">中心对准文本跟随鼠标</title>
<style>
body {
height: 100vh;
margin: 0;
background-color: #282c34;
color: white;
overflow: hidden;
cursor: none;
display: flex;
justify-content: center;
align-items: center;
font-family: 'Courier New', Courier, monospace;
}
#follower {
position: absolute;
color: #61dafb;
font-size: 24px;
font-weight: bold;
padding: 10px 20px;
border: 2px solid #61dafb;
border-radius: 8px;
pointer-events: none;
user-select: none;
/* 添加一点过渡效果,让移动更平滑 */
transition: left 0.05s, top 0.05s;
}
</style>
</head>
<body>
<span id="follower">跟随我</span>
<script>
const follower = document.getElementById('follower');
document.addEventListener('mousemove', (event) => {
const x = event.clientX;
const y = event.clientY;
// 获取元素自身的宽度和高度
const rect = follower.getBoundingClientRect();
const width = rect.width;
const height = rect.height;
// 计算新的位置,使元素中心对准鼠标
const newX = x - width / 2;
const newY = y - height / 2;
follower.style.left = newX + 'px';
follower.style.top = newY + 'px';
});
</script>
</body>
</html>
注意: 这里我们使用了 transition 属性,让元素的移动有一个微小的延迟,效果会更平滑。
进阶版(带延迟的平滑跟随)
酷炫的特效通常不是瞬时的,我们可以让文本有一个“延迟跟随”的效果,就像鼠标拖着一条尾巴一样。

(图片来源网络,侵删)
实现思路
- 不再直接设置元素的位置。
- 在
mousemove事件中,我们只记录目标位置(鼠标位置)。 - 使用
requestAnimationFrame创建一个动画循环。 - 在循环中,计算当前元素位置与目标位置之间的差值,然后让元素向目标位置移动一小段距离(移动差值的 10%),这会产生缓动效果。
完整代码示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">平滑延迟跟随鼠标</title>
<style>
body {
height: 100vh;
margin: 0;
background: linear-gradient(45deg, #1a2a6c, #b21f1f, #1a2a6c);
background-size: 400% 400%;
animation: gradientBG 15s ease infinite;
color: white;
overflow: hidden;
font-family: 'Arial', sans-serif;
}
@keyframes gradientBG {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
#follower {
position: absolute;
color: #fff;
font-size: 18px;
font-weight: bold;
text-shadow: 0 0 10px rgba(255, 255, 255, 0.7);
pointer-events: none;
user-select: none;
transform: translate(-50%, -50%); /* 使用 transform 实现中心对齐,性能更好 */
}
</style>
</head>
<body>
<span id="follower">Smooth Follower</span>
<script>
const follower = document.getElementById('follower');
// 1. 定义目标位置和当前元素的位置
let targetX = 0;
let targetY = 0;
let currentX = 0;
let currentY = 0;
// 2. 鼠标移动时,更新目标位置
document.addEventListener('mousemove', (event) => {
targetX = event.clientX;
targetY = event.clientY;
});
// 3. 使用 requestAnimationFrame 创建平滑动画
function animate() {
// 计算当前位置与目标位置之间的差值
const deltaX = targetX - currentX;
const deltaY = targetY - currentY;
// 更新当前位置(乘以一个系数,如 0.1,来控制延迟程度)
// 值越小,延迟越明显,越平滑
currentX += deltaX * 0.1;
currentY += deltaY * 0.1;
// 使用 transform 属性来移动元素,性能优于 top/left
follower.style.transform = `translate(${currentX}px, ${currentY}px)`;
// 请求下一帧动画
requestAnimationFrame(animate);
}
// 启动动画
animate();
</script>
</body>
</html>
关键点:
requestAnimationFrame: 这是浏览器专门为动画提供的高效API,它会在下一次浏览器重绘之前调用指定的回调函数,从而实现流畅的动画效果。- 缓动公式:
current += (target - current) * factor是实现平滑跟随的核心公式。factor(0到1之间)决定了跟随的速度和延迟程度。 transformvstop/left: 对于动画,使用transform: translate()的性能远优于修改left和top属性,因为transform不会引起整个页面的重排,只会触发重绘。
酷炫版(多个粒子/文本跟随)
这是最高级的版本,创建一个由多个文本或粒子组成的“尾巴”,它们依次跟随前一个,形成非常炫酷的拖尾效果。
实现思路
- 创建一个数组来存储所有跟随元素(粒子)。
- 在
mousemove事件中,我们只更新“头”粒子的位置为鼠标位置。 - 在动画循环 (
requestAnimationFrame) 中,从第二个粒子开始,让每个粒子的目标位置成为它前一个粒子的当前位置,这样就会形成“链式反应”,产生拖尾效果。
完整代码示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">粒子拖尾跟随鼠标</title>
<style>
body {
height: 100vh;
margin: 0;
background-color: #000;
overflow: hidden;
cursor: none;
}
.particle {
position: absolute;
color: #fff;
font-size: 14px;
font-weight: bold;
pointer-events: none;
user-select: none;
opacity: 1; /* 初始不透明 */
}
</style>
</head>
<body>
<script>
const particlesCount = 15; // 粒子数量
const particles = []; // 存储所有粒子元素的数组
const text = '✨'; // 可以是任何字符或文本
// 1. 创建粒子元素并添加到页面和数组中
for (let i = 0; i < particlesCount; i++) {
const particle = document.createElement('span');
particle.className = 'particle';
particle.innerText = text;
particle.style.opacity = 1 - (i / particlesCount); // 尾部粒子更透明
document.body.appendChild(particle);
particles.push(particle);
}
let mouseX = 0;
let mouseY = 0;
// 2. 监听鼠标移动,更新目标位置
document.addEventListener('mousemove', (event) => {
mouseX = event.clientX;
mouseY = event.clientY;
});
// 3. 动画循环
function animate() {
// 让第一个粒子(头)跟随鼠标
particles[0].style.transform = `translate(${mouseX}px, ${mouseY}px)`;
// 从第二个粒子开始,让每个粒子跟随前一个粒子
for (let i = 1; i < particles.length; i++) {
const prevParticle = particles[i - 1];
const currentParticle = particles[i];
// 获取前一个粒子的位置
const prevRect = prevParticle.getBoundingClientRect();
const prevX = prevRect.left + prevRect.width / 2;
const prevY = prevRect.top + prevRect.height / 2;
// 当前粒子移动到前一个粒子的位置
currentParticle.style.transform = `translate(${prevX}px, ${prevY}px)`;
}
requestAnimationFrame(animate);
}
animate();
</script>
</body>
</html>
总结与选择建议
| 方法 | 特点 | 适用场景 |
|---|---|---|
| 基础版 | 实现简单,直接跟随 | 学习、简单装饰 |
| 优化版 | 中心对准,更自然 | 大多数UI效果、自定义光标 |
| 进阶版 | 平滑延迟,性能好 | 高质量交互体验、游戏UI |
| 酷炫版 | 粒子拖尾,视觉效果强 | 创意网站、Loading动画、特殊交互 |
对于大多数网页应用,方法二(优化版) 和 方法三(进阶版) 是最常用且效果很好的选择,你可以根据你的具体需求选择最适合的一种。

(图片来源网络,侵删)
