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

如何实现页面向下滚动时的打字机效果?

实现页面滚动触发的打字机效果

嘿,这个需求其实挺常见的——核心就是把打字机效果的触发时机从「页面加载完成」改成「目标元素滚动到用户可见区域」。我给你拆解一下具体实现步骤,附完整可运行的代码示例:

核心思路

  • 监听页面的滚动事件
  • 实时检测目标文本元素是否进入视口(用户能看到它的范围)
  • 一旦元素进入视口,启动打字机动画,同时设置标记避免重复触发

完整代码示例

HTML结构

我们把要展示的文本放在元素的data-text属性里,这样JS可以方便读取,也能保持HTML结构整洁:

<!-- 让容器在页面下方,方便测试滚动效果 -->
<div class="typewriter-container">
  <p id="typewriter-text" data-text="这是滚动触发的打字机效果!当你把我滚到视野里,我就开始逐个字符显示啦~"></p>
</div>

CSS样式

给元素加一点基础样式,再模拟打字机的光标闪烁效果:

.typewriter-container {
  margin-top: 1000px; /* 让元素处于页面下方,测试时需要滚动才能看到 */
  font-size: 24px;
  font-family: 'Courier New', monospace; /* 用等宽字体更有打字机感 */
  padding: 20px;
}

/* 打字时的光标动画 */
#typewriter-text::after {
  content: "|";
  animation: blink 1s infinite alternate;
}

@keyframes blink {
  from { opacity: 1; }
  to { opacity: 0; }
}

/* 打字结束后移除光标 */
#typewriter-text.finished::after {
  display: none;
}

JavaScript逻辑

这部分是核心,分三个关键函数:

  1. 判断元素是否在视口内
  2. 实现打字机效果
  3. 监听滚动并触发打字
// 1. 判断元素是否进入视口
function isElementInViewport(element) {
  const rect = element.getBoundingClientRect();
  // 只要元素顶部在视口底部之上,且底部在视口顶部之下,就算进入视口
  return rect.top <= window.innerHeight && rect.bottom >= 0;
}

// 2. 打字机核心函数
function startTypewriter(element, text, speed = 120) {
  let charIndex = 0;
  const typeInterval = setInterval(() => {
    if (charIndex < text.length) {
      // 逐个添加字符
      element.textContent += text.charAt(charIndex);
      charIndex++;
    } else {
      // 打字完成后清除定时器,添加结束类移除光标
      clearInterval(typeInterval);
      element.classList.add('finished');
    }
  }, speed);
}

// 3. 监听滚动事件,触发打字机
const typewriterEl = document.getElementById('typewriter-text');
const targetText = typewriterEl.dataset.text;
let hasTriggered = false; // 标记是否已经触发过打字效果,避免重复执行

function handleScrollTrigger() {
  if (!hasTriggered && isElementInViewport(typewriterEl)) {
    startTypewriter(typewriterEl, targetText);
    hasTriggered = true;
    // 触发后移除滚动监听,优化性能
    window.removeEventListener('scroll', handleScrollTrigger);
  }
}

// 页面加载时先检查一次:如果元素本来就在视口内,直接触发
window.addEventListener('load', () => {
  if (isElementInViewport(typewriterEl)) {
    startTypewriter(typewriterEl, targetText);
    hasTriggered = true;
  } else {
    window.addEventListener('scroll', handleScrollTrigger);
  }
});

适配你现有代码的小技巧

如果你已经有自己的打字机代码,只需要修改触发逻辑:

  1. 保留你原有的打字函数
  2. 把原来直接调用打字函数的代码,替换成上面的「滚动监听+视口检测」逻辑
  3. 加上hasTriggered标记防止重复触发就好啦

内容的提问来源于stack exchange,提问作者Laura Kašinskaitė

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:05:59