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

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

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

核心原理与实现思路

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

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

HTML 结构准备

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

      滚动文本高亮              

在这个结构中, 是我们将用来承载和显示动态高亮文本的容器。

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; /* 定义高亮文本的颜色,这里设置为红色 */}

样式说明:

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

注意事项与优化

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

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

以上就是基于滚动进度的文本高亮动画实现教程的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1520354.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月20日 13:15:17
下一篇 2025年12月20日 13:15:29

相关推荐

  • JavaScript:将特定格式字符串高效转换为二维数组的教程

    本教程将详细阐述如何利用javascript将形如 `[[item1, item2], [item3, item4]]` 的特定格式字符串转换为可操作的二维数组。我们将通过字符串截取、正则表达式匹配和循环迭代等技术,逐步解析复杂的字符串结构,确保数据能够被精确提取和组织,从而为后续的数据处理提供便利…

    2025年12月21日
    000
  • JavaScript中正确获取从隐藏输入获取的列表(字符串)长度

    当从HTML隐藏输入字段获取JavaScript中的“列表”时,其值通常是一个字符串表示。直接使用`.length`属性会返回字符串的字符长度,而非实际的元素数量。要正确获取列表中元素的数量,需要先将该字符串通过特定的分隔符(如逗号)拆分成一个数组,然后获取该数组的长度。本文将详细介绍这一过程及更推…

    2025年12月21日
    000
  • 使用Proxy和Reflect实现高级数据绑定

    通过Proxy和Reflect可实现数据与视图自动同步。1. Proxy用于拦截对象的读取、赋值操作,2. Reflect确保默认行为并返回正确结果,3. 在set中调用更新函数实现响应式渲染,4. 结合递归代理支持嵌套对象监听,5. 传递receiver避免代理链断裂。该机制为构建轻量级双向绑定提…

    2025年12月21日
    000
  • JavaScript 调试技巧:Chrome DevTools 高级用法

    掌握Chrome DevTools高级技巧可高效定位内存泄漏、异步问题和性能瓶颈。1. 使用条件断点和日志点避免代码污染,精准输出特定条件下的变量值而不中断执行。2. 开启异步调用栈追踪并设置事件监听器断点,完整查看Promise链或事件回调路径,快速定位错误源头。3. 将第三方库脚本设为黑盒,调试…

    2025年12月21日
    000
  • JavaScript中从HTML隐藏输入获取列表长度的正确姿势

    本文探讨了在javascript中从html隐藏输入元素获取列表长度时常见的误区。由于html输入的值始终是字符串,直接访问`length`属性会返回字符串的字符数而非实际列表项数。教程将详细解释这一现象,并提供通过字符串拆分获取正确列表长度的方法,同时强调使用更优的数据传递策略以避免此类问题。 在…

    2025年12月21日
    000
  • 使用Object.defineProperty实现响应式数据

    Object.defineProperty通过get/set拦截属性读写,实现数据响应式,Vue 2据此追踪依赖并更新视图,但无法监听数组索引及属性增删,需递归遍历对象实现深度监听。 在 JavaScript 中,Object.defineProperty 是实现数据响应式的一种核心手段,尤其在 V…

    2025年12月21日
    000
  • JavaScript 默认参数:解决函数参数未传递的问题

    默认参数允许在函数定义时为参数指定默认值,当未传参或传入undefined时生效。例如function greet(name = “游客”)会输出“你好,游客!”;支持表达式、函数调用及前参引用,常用于配置对象、可选字段等场景,提升代码健壮性与可读性。 在 JavaScrip…

    2025年12月21日
    000
  • 使用Canvas实现简单图片滤镜效果_javascript技巧

    使用JavaScript和Canvas可实现图片滤镜,通过getImageData获取像素数据并修改RGB值,再用putImageData渲染;常见滤镜包括灰度、反色和亮度调整,需注意性能与跨域问题。 在网页开发中,使用 JavaScript 结合 HTML5 的 Canvas 可以为图片添加各种简…

    2025年12月21日
    000
  • 使用JavaScript实现一个简单的MVVM框架_javascript框架

    答案:通过Proxy实现数据响应式,Compiler解析模板指令,Watcher与Dep完成依赖收集和视图更新,构建极简MVVM框架。 要实现一个简单的MVVM(Model-View-ViewModel)框架,核心是数据绑定和响应式更新视图。我们可以通过JavaScript的Object.defin…

    2025年12月21日
    000
  • JavaScript:将特定格式字符串转换为二维数组的实用方法

    本文将探讨在javascript中如何将形如`[[item1, date], [item2, date]]`的特定格式字符串转换为可操作的二维数组。我们将详细介绍利用字符串分割、正则表达式等手动解析方法,以及在字符串符合json规范时如何使用`json.parse()`进行高效转换,帮助开发者便捷地…

    2025年12月21日
    000
  • 前端水印技术的JS实现方案_javascript技巧

    答案:前端水印通过Canvas或DOM生成,用于防信息泄露,可结合用户信息动态渲染并监听删除操作,但仅作辅助防护。 前端水印技术常用于防止信息泄露或追溯数据来源,尤其在后台管理系统、数据可视化平台中应用广泛。通过 JavaScript 动态生成水印,可以有效提醒用户当前页面内容受保护,同时具备一定的…

    2025年12月21日
    000
  • JS中URL编码与解码方法详解_javascript技巧

    encodeURI用于编码完整URL,保留结构字符,适用于整个链接;encodeURIComponent更严格,编码所有特殊字符,适合参数值;两者对应各自的解码方法,避免乱码。 在JavaScript中处理URL时,经常需要对特殊字符进行编码和解码,以确保数据能正确传输。由于URL中不允许出现空格、…

    2025年12月21日
    000
  • 优化大量网络请求:分批处理、并发控制与超时策略

    本文旨在解决前端应用中处理大量网络请求时遇到的api超时、403错误等问题。通过分析常见的错误尝试,文章重点介绍了如何利用bluebird.map进行并发控制,以及如何手动实现分批处理和延迟执行请求,从而有效管理请求负载,避免api限流,确保应用稳定性和用户体验。 引言:处理大量网络请求的挑战 在现…

    2025年12月21日
    000
  • JavaScript中的数据结构实现:栈与队列

    栈和队列可通过JavaScript数组或自定义类实现。1. 栈遵循后进先出(LIFO),用push/pop操作实现高效入栈出栈;2. 队列遵循先进先出(FIFO),可用push/shift操作,但shift为O(n)影响性能;3. 可通过类封装实现peek、front、isEmpty等方法;4. 栈…

    2025年12月21日
    100
  • JavaScript 数组归并:reduce() 方法实现数组累计操作

    reduce()方法用于将数组归并为单一值,不修改原数组。常用于求和、扁平化、统计频次等场景,通过累加器逐步积累结果,需注意初始值设置对执行过程的影响。 JavaScript 中的 reduce() 方法是处理数组累计操作的核心工具。它能将数组中的所有元素从左到右“归并”为一个单一值,适用于求和、拼…

    2025年12月21日
    000
  • 使用Node.js高效批量删除MongoDB多个集合

    本教程详细指导如何通过node.js编程方式批量删除mongodb数据库中的多个集合。文章将介绍使用mongodb官方驱动程序连接数据库,并演示如何迭代预定义的集合列表,逐一执行`drop()`操作,实现高效、自动化的集合清理。内容包含完整的代码示例、操作步骤及重要注意事项,帮助开发者安全、便捷地管…

    2025年12月21日
    000
  • Django DRF与React:解决管理员创建用户不设密码时的400错误

    本教程旨在解决django rest framework后端与react前端交互时,管理员创建用户无需设置密码导致400错误的问题。文章详细解析了错误原因,并提供了通过优化drf序列化器(设置`password`为`write_only`和`required=false`)、定制`create`方法…

    2025年12月21日
    200
  • Winston.js日志拦截与参数注入:利用自定义格式扩展日志信息

    本文深入探讨如何在winston.js日志系统中通过自定义格式(format)实现日志信息的拦截与动态参数注入。通过创建自定义格式函数,开发者可以在日志被记录前,对日志对象(info)进行修改和扩展,例如注入关联id(correlationid)等上下文信息,从而极大地提升日志的可追溯性和分析能力,…

    2025年12月21日
    000
  • 使用JavaScript实现一个简单的AST解析器_js编译原理

    首先实现词法分析将代码转为Token,再通过递归下降解析器构建AST,正确处理运算优先级,最终生成反映表达式结构的抽象语法树。 要实现一个简单的AST(抽象语法树)解析器,我们需要从词法分析(Lexer)开始,接着进行语法分析(Parser),最终生成AST。这个过程是编译原理中的核心部分,适用于构…

    2025年12月21日
    000
  • 如何在 MongoDB 中批量删除多个集合

    本文介绍了如何在 MongoDB 中通过脚本批量删除多个集合。通过 Node.js 脚本连接 MongoDB 数据库,循环遍历需要删除的集合列表,并使用 `drop()` 方法删除每个集合,从而实现批量删除操作。 在 MongoDB 中,删除单个集合可以使用 db.collectionName.dr…

    好文分享 2025年12月21日
    000

发表回复

登录后才能评论
关注微信