最基础版(文本直接跟随鼠标)

这是最直接的方法,文本的左上角会精确地定位在鼠标指针的位置。

javascript网页文本跟随鼠标
(图片来源网络,侵删)

实现思路

  1. HTML: 创建一个用于显示跟随文本的 <span><div> 元素。
  2. CSS: 将该元素设置为 position: absolute(绝对定位),并设置一些基本样式(如颜色、字体、指针事件 pointer-events: none 防止它遮挡鼠标)。
  3. JavaScript:
    • 监听整个文档的 mousemove 事件。
    • 在事件触发时,获取鼠标的 clientXclientY 坐标。
    • 将获取到的坐标直接赋给该元素的 style.leftstyle.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>

优化版(文本中心对准鼠标)

基础版中,文本的左上角在鼠标位置,看起来不太自然,我们可以让文本的中心点对准鼠标。

实现思路

与基础版类似,但在设置 lefttop 时,需要减去文本自身宽度和高度的一半。

完整代码示例

<!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 属性,让元素的移动有一个微小的延迟,效果会更平滑。


进阶版(带延迟的平滑跟随)

酷炫的特效通常不是瞬时的,我们可以让文本有一个“延迟跟随”的效果,就像鼠标拖着一条尾巴一样。

javascript网页文本跟随鼠标
(图片来源网络,侵删)

实现思路

  1. 不再直接设置元素的位置。
  2. mousemove 事件中,我们只记录目标位置(鼠标位置)。
  3. 使用 requestAnimationFrame 创建一个动画循环。
  4. 在循环中,计算当前元素位置与目标位置之间的差值,然后让元素向目标位置移动一小段距离(移动差值的 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之间)决定了跟随的速度和延迟程度。
  • transform vs top/left: 对于动画,使用 transform: translate() 的性能远优于修改 lefttop 属性,因为 transform 不会引起整个页面的重排,只会触发重绘。

酷炫版(多个粒子/文本跟随)

这是最高级的版本,创建一个由多个文本或粒子组成的“尾巴”,它们依次跟随前一个,形成非常炫酷的拖尾效果。

实现思路

  1. 创建一个数组来存储所有跟随元素(粒子)。
  2. mousemove 事件中,我们只更新“头”粒子的位置为鼠标位置。
  3. 在动画循环 (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动画、特殊交互

对于大多数网页应用,方法二(优化版)方法三(进阶版) 是最常用且效果很好的选择,你可以根据你的具体需求选择最适合的一种。

javascript网页文本跟随鼠标
(图片来源网络,侵删)