You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助实现鼠标悬停文字打乱复原效果(附jQuery代码)

纯原生JS实现文字悬停打乱归位效果

针对你提到的原jQuery实现的问题(首字母未真正打乱、文本宽度变化),以下是贴近示例效果的纯原生JS方案:

核心改进点

  • 每个字符独立拆分到固定宽度容器中,彻底解决宽度变化问题
  • 所有字符都会参与随机打乱,包括首字母
  • 字符动画加入错落延迟,更贴近示例的流畅效果
  • 纯原生JS实现,无需依赖jQuery

完整代码实现

HTML

<ul>
  <li>
    <a class="shuffle" href="#">shuffle</a>
  </li>
  <li>
    <a class="shuffle" href="#">texts</a>
  </li>
  <li>
    <a class="shuffle" href="#">hover</a>
  </li>
</ul>

CSS

body {
  font-family: helvetica;
  font-size: 16px;
  padding: 48px;
}

a {
  color: black;
  text-decoration: none;
}

ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

li {
  display: inline-block;
  margin: 0 16px 8px 0;
}

/* 字符容器:固定宽度,确保文本整体宽度不变 */
.shuffle .char {
  display: inline-block;
  text-align: center;
  /* 非等宽字体可注释掉下面的ch单位,改用JS计算的精确宽度 */
  width: 1ch;
}

JavaScript

document.addEventListener('DOMContentLoaded', () => {
  const shuffleElements = document.querySelectorAll('.shuffle');
  const animationSpeed = 50;    // 字符替换间隔(毫秒)
  const shuffleCount = 8;       // 每个字符打乱次数,之后恢复原字符
  const staggerDelay = 20;      // 字符动画错落延迟(毫秒)

  // 生成随机小写字母
  const getRandomChar = () => {
    const charPool = 'abcdefghijklmnopqrstuvwxyz';
    return charPool[Math.floor(Math.random() * charPool.length)];
  };

  // 预处理:将文本拆分为单个字符的span容器
  shuffleElements.forEach(el => {
    const originalText = el.textContent.trim();
    // 非等宽字体用这段代码计算精确宽度(注释掉上面CSS的width:1ch)
    /*
    const tempSpan = document.createElement('span');
    tempSpan.style.visibility = 'hidden';
    tempSpan.style.position = 'absolute';
    document.body.appendChild(tempSpan);
    */
    el.innerHTML = originalText.split('').map(char => {
      /*
      tempSpan.textContent = char;
      const charWidth = tempSpan.offsetWidth + 'px';
      */
      return `<span class="char" data-original="${char}">${char}</span>`;
      // 非等宽字体替换为下面的return
      // return `<span class="char" data-original="${char}" style="width: ${charWidth}">${char}</span>`;
    }).join('');
    // document.body.removeChild(tempSpan);
  });

  // 绑定悬停事件
  shuffleElements.forEach(el => {
    let activeTimers = []; // 存储定时器,用于清理

    el.addEventListener('mouseenter', () => {
      // 清除之前的定时器,避免动画叠加
      activeTimers.forEach(timer => clearInterval(timer));
      activeTimers = [];

      const charSpans = el.querySelectorAll('.char');
      charSpans.forEach((span, index) => {
        const originalChar = span.dataset.original;
        let currentShuffleCount = 0;

        const timer = setInterval(() => {
          if (currentShuffleCount >= shuffleCount) {
            span.textContent = originalChar;
            clearInterval(timer);
            return;
          }
          // 随机替换字符
          span.textContent = getRandomChar();
          currentShuffleCount++;
        }, animationSpeed + (index * staggerDelay)); // 错落延迟,增强层次感
        activeTimers.push(timer);
      });
    });

    // 鼠标离开时立即恢复原文本并清理定时器
    el.addEventListener('mouseleave', () => {
      activeTimers.forEach(timer => clearInterval(timer));
      activeTimers = [];
      el.querySelectorAll('.char').forEach(span => {
        span.textContent = span.dataset.original;
      });
    });
  });
});

自定义参数说明

  • animationSpeed:控制字符替换的快慢,值越小动画越快
  • shuffleCount:控制每个字符打乱的次数,值越大打乱时间越长
  • staggerDelay:控制字符动画的错落间隔,值越大错落感越明显

内容的提问来源于stack exchange,提问作者user1406440

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 02:25:03