boxmoe_header_banner_img

Hello! 欢迎来到悠悠畅享网!

文章导读

基于滚动进度的文本高亮动画实现教程


avatar
作者 2025年9月16日 9

基于滚动进度的文本高亮动画实现教程

本教程将指导您如何利用JavaScript的滚动事件,实现一个引人注目的文本高亮动画效果。通过计算页面滚动百分比,我们将动态地为文本中的单词添加或移除高亮样式,从而使文本填充颜色与用户的滚动行为同步,提供独特的视觉反馈。

核心原理与实现思路

实现这种滚动进度关联的文本高亮效果,其核心在于以下几个步骤:

  1. 监听滚动事件: 捕获浏览器窗口的滚动行为。
  2. 计算滚动进度: 获取当前页面滚动条的位置,并将其转换为一个0到1之间的百分比值。
  3. 文本拆分与初始化: 将待高亮的整段文本拆分成独立的单词,并为每个单词包裹一个独立的html元素(如<span>),以便单独控制其样式。
  4. 动态应用样式: 根据计算出的滚动百分比,确定当前应该高亮的单词数量,并为这些单词动态地添加或移除特定的css高亮类。

HTML 结构准备

首先,我们需要一个基本的HTML页面结构,包含一个用于显示文本的容器元素。

<!DOCTYPE html> <html lang="zh-CN"> <head>   <meta charset="utf-8">   <meta name="viewport" content="width=device-width, initial-scale=1.0">   <title>滚动文本高亮</title>   <!-- 引入自定义CSS样式文件 -->   <link rel="stylesheet" href="style.css">  </head> <body>   <!-- 文本内容将动态加载到此span元素中 -->   <span class="text"></span>   <!-- 引入JavaScript逻辑文件 -->   <script src="script.JS"></script>  </body> </html>

在这个结构中,<span class=”text”></span> 是我们将用来承载和显示动态高亮文本的容器。

CSS 样式定义

为了让文本在滚动时固定在视口中,并定义高亮时的颜色,我们需要一些基本的CSS样式。

body {   height: 5000px; /* 制造足够的滚动空间,以便观察效果 */   margin: 0; /* 移除浏览器默认的body边距 */   font-family: sans-serif; /* 设置基础字体 */   background-color: #f8f8f8; /* 背景色 */ }  .text {   position: fixed; /* 将文本容器固定在视口中 */   top: 10px; /* 距离视口顶部10px */   left: 10px; /* 距离视口左侧10px */   width: calc(100% - 20px); /* 占据大部分宽度,留出左右边距 */   line-height: 1.6; /* 设置行高,提高可读性 */   font-size: 24px; /* 设置字号 */   color: #333; /* 默认文本颜色 */   padding: 10px; /* 文本内边距 */   box-sizing: border-box; /* 边框盒模型 */ }  .text span {     /* 为文本颜色变化添加过渡效果,使高亮/取消高亮更平滑 */     transition: color 0.1s ease-out;      white-space: pre-wrap; /* 保留空格和换行符 */ }  .highlight {   color: #f00; /* 定义高亮文本的颜色,这里设置为红色 */ }

样式说明:

基于滚动进度的文本高亮动画实现教程

Fliki

高效帮用户创建视频,具有文本转语音功能

基于滚动进度的文本高亮动画实现教程96

查看详情 基于滚动进度的文本高亮动画实现教程

  • body { height: 5000px; }:这是关键一步,它为页面创建了足够的高度,从而生成滚动条。在实际应用中,这个高度应由您的实际内容决定。
  • .text { position: fixed; … }:使文本内容在用户滚动页面时始终保持在屏幕上的固定位置。
  • .highlight { color: #f00; }:定义了当单词被高亮时所呈现的颜色。
  • .text span { transition: color 0.1s ease-out; }:为颜色变化添加了平滑的过渡效果,提升用户体验。

JavaScript 逻辑实现

JavaScript是实现动态高亮的核心。它负责初始化文本、监听滚动事件、计算滚动进度并更新文本样式。

// 定义高亮样式类名常量 const HIGHLIGHT_CLASS = 'highlight';   // 待高亮的文章文本 const ARTICLE_TEXT = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer suscipit libero eu ligula molestie, sed faucibus leo iaculis. Quisque scelerisque ligula in volutpat venenatis. Fusce velit felis, pretium eu varius quis, facilisis eget nunc. Quisque eu eros tellus. Cras condimentum efficitur turpis, ac laoreet velit rhoncus et. Maecenas non lorem auctor dolor auctor gravida ut at diam. Proin eleifend elementum lacus in varius. In dapibus mi ut erat gravida, non dictum nisi luctus. Aliquam imperdiet commodo ante, posuere vestibulum eros mattis vitae. Cras molestie commodo turpis, vitae tempus magna dictum pharetra. Duis quis eros at magna sodales mollis. Fusce sollicitudin purus sit amet est ullamcorper luctus. Donec molestie, nisi quis luctus malesuada, lectus arcu rutrum turpis, ac bibendum libero tellus at metus. Vivamus mattis ultricies metus eu dignissim. Mauris sed consectetur nisl.";  // 将文章文本按空格分割成单词数组 let words = ARTICLE_TEXT.split(" ");  // 获取文本容器元素 let textContainer = document.querySelector('.text');   // 初始化文本:将每个单词包裹在<span>中并插入到dom // 这样每个单词都可以独立地被高亮或取消高亮 textContainer.innerHTML = words   .map(word => `<span>${word}</span>`)   .join(' ');  // 监听窗口滚动事件 window.addEventListener('scroll', () => {   // 获取当前页面滚动进度(0.0到1.0之间)   let scrollFraction = getScrollFraction();    // 根据滚动进度和总单词数,计算当前需要高亮的单词数量   let wordsToHighlight = math.floor(scrollFraction * words.length);     // 重新渲染文本容器的innerHTML,根据计算结果应用高亮样式   // 如果单词的索引小于wordsToHighlight,则为其添加高亮类   textContainer.innerHTML = words     .map((word, index) => `<span ${index < wordsToHighlight ? `class="${HIGHLIGHT_CLASS}"` : ''}>${word}</span>`)     .join(' '); });  /**  * 计算页面滚动百分比  * 此函数考虑了不同浏览器对scrollTop和scrollHeight的实现差异  * @returns {number} 滚动百分比(0.0到1.0之间),0表示顶部,1表示底部  */ function getScrollFraction() {     const docElem = document.documentElement;     const body = document.body;     // 获取当前滚动距离,兼容不同浏览器     const scrollTop = docElem.scrollTop || body.scrollTop;      // 计算可滚动总高度 = (文档总高度 - 视口高度)     const scrollHeight = (docElem.scrollHeight || body.scrollHeight) - docElem.clientHeight;      // 避免除以零,如果无可滚动高度则返回0     return scrollHeight > 0 ? scrollTop / scrollHeight : 0; }

JavaScript代码详解:

  • HIGHLIGHT_CLASS 和 ARTICLE_TEXT 是常量,用于配置样式类名和初始文本内容。
  • ARTICLE_TEXT.split(” “) 将文本按空格分割成一个单词数组。
  • 在页面加载时,textContainer.innerHTML = words.map(…) 会遍历单词数组,为每个单词生成一个 <span> 标签,并将其组合成HTML字符串插入到 .text 容器中。这是为了确保每个单词都能被独立地操作。
  • window.addEventListener(‘scroll’, …) 注册了一个滚动事件监听器。每当用户滚动页面时,回调函数就会执行。
  • getScrollFraction() 函数是核心辅助函数,它计算了当前滚动条位置占总可滚动高度的百分比。它通过获取 document.documentElement 或 document.body 的 scrollTop 和 scrollHeight 属性来完成计算,并考虑了浏览器兼容性。
  • wordsToHighlight 根据滚动百分比和总单词数计算出当前应该高亮的单词数量。Math.floor() 用于取整。
  • 最后,再次使用 map 方法遍历单词数组,根据 wordsToHighlight 的值,为相应的单词添加 highlight 类。通过更新 textContainer.innerHTML,浏览器会重新渲染文本,显示新的高亮状态。

注意事项与优化

  • 性能考量: 频繁地修改 innerHTML 会导致浏览器重新解析和渲染 DOM,这在大型文本或复杂页面中可能造成性能问题。对于更复杂的场景,可以考虑以下优化:
    • DOM 操作优化: 避免在每次滚动时完全重绘 innerHTML。可以只更新受影响的 <span> 元素的 class 属性。这需要更复杂的 DOM 操作逻辑(例如,存储所有 <span> 元素的引用,然后遍历并按需添加/移除类)。
    • 节流(Throttling)或防抖(Debouncing): 限制 scroll 事件处理函数的执行频率。例如,使用 requestAnimationFrame 或设置一个定时器,确保函数在一定时间间隔内只执行一次,以减少不必要的计算和DOM操作。
  • 可访问性: 这种视觉高亮可能不适用于所有用户。确保您的内容在没有此效果时也能清晰阅读,并考虑为屏幕阅读器提供替代文本或功能。
  • 滚动高度与文本长度: 页面 body 的 height 越大,滚动条的移动距离就越长,文本高亮的速度(相对于滚动条的移动)就越慢。反之,body 高度越小,文本高亮速度越快。您需要根据内容和期望的用户体验来调整 body 的高度。
  • 文本内容: 如果文本中包含HTML标签或特殊字符,split(” “) 可能需要更复杂的正则匹配来准确分割单词,以避免破坏HTML结构。
  • 平滑过渡: 如CSS代码所示,为 span 元素添加 transition 属性(如 transition: color 0.2s ease-out;)可以使高亮颜色的变化更加平滑自然。

通过上述步骤和注意事项,您可以实现一个功能完善且视觉吸引力强的基于滚动进度的文本高亮动画效果。



评论(已关闭)

评论已关闭