实现滚动进度驱动的文本高亮效果

实现滚动进度驱动的文本高亮效果

本教程将详细介绍如何利用JavaScript监听浏览器滚动事件,实现文本内容根据页面滚动百分比进行动态填充或高亮的效果。通过计算滚动位置,我们可以实时更新文本的样式,使其从左到右逐渐着色,并在回滚时取消着色,从而创造出独特的视觉交互体验。文章将提供完整的HTML、CSS和JavaScript代码示例,并探讨实现细节及注意事项。

核心原理

实现文本高亮与滚动进度关联的核心思想是:获取当前页面的滚动百分比,然后根据这个百分比来决定文本中应该有多少个单词被“高亮”显示。当用户向下滚动时,高亮词语的数量增加;当用户向上滚动时,高亮词语的数量减少。

HTML 结构

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

      滚动进度文本高亮      

这里, 是我们将通过JavaScript动态填充文本内容的容器。

CSS 样式

为了让页面能够滚动,我们需要给 body 设置足够的高度。同时,为了让文本在滚动时保持在视口内,我们可以使用 position: fixed。最后,定义高亮文本的样式。

body {  height: 5000px; /* 确保页面有足够的滚动空间 */  margin: 0;  font-family: Arial, sans-serif;  line-height: 1.6;}.text {  position: fixed; /* 使文本在滚动时保持在视口顶部 */  top: 10px;  left: 10px;  max-width: 80%; /* 防止文本过宽 */  background-color: #f9f9f9;  padding: 10px;  border-radius: 5px;  box-shadow: 0 2px 5px rgba(0,0,0,0.1);}.text span {  transition: color 0.1s ease-out; /* 为颜色变化添加平滑过渡 */}.highlight {  color: #f00; /* 高亮文本的颜色,这里设置为红色 */  font-weight: bold;}

JavaScript 逻辑

JavaScript是实现动态效果的核心。它负责:

获取原始文本并将其拆分成单词。将每个单词包裹在 标签中,以便单独控制样式。监听 scroll 事件,计算当前滚动百分比。根据滚动百分比,动态更新文本中高亮单词的数量。

const HIGHLIGHT_CLASS = 'highlight'; // 定义高亮CSS类名const LOREM_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 = LOREM_TEXT.split(" "); // 将文本按空格拆分为单词数组let textContainer = document.querySelector('.text'); // 获取文本容器元素// 初始化文本内容,将每个单词包裹在中textContainer.innerHTML = words  .map(w => `${w}`)  .join(' ');// 监听窗口滚动事件window.addEventListener('scroll', () => {  let scrollFraction = getScrollFraction(); // 获取当前滚动百分比 (0-1之间)  let wordsToHighlightCount = Math.floor(scrollFraction * words.length); // 根据滚动百分比计算需要高亮的单词数量  // 重新渲染文本内容,为需要高亮的单词添加CSS类  textContainer.innerHTML = words  .map((word, index) => `<span ${index ${word}`)  .join(' ');});/** * 计算页面滚动百分比的辅助函数。 * 返回一个0到1之间的浮点数,表示当前滚动位置占总可滚动高度的比例。 */function getScrollFraction() {    var docElem = document.documentElement,         bodyElem = document.body,        scrollTopProp = 'scrollTop',        scrollHeightProp = 'scrollHeight';    // 获取当前滚动条位置 (兼容不同浏览器)    var currentScrollTop = docElem[scrollTopProp] || bodyElem[scrollTopProp];    // 获取可滚动总高度    var totalScrollHeight = (docElem[scrollHeightProp] || bodyElem[scrollHeightProp]) - docElem.clientHeight;    // 避免除以零的情况    if (totalScrollHeight <= 0) {        return 0;    }    return currentScrollTop / totalScrollHeight;}

代码解析:

HIGHLIGHT_CLASS 和 LOREM_TEXT: 定义了高亮CSS类名和作为示例的文本内容。words = LOREM_TEXT.split(” “);: 将长文本分割成单词数组。初始化 textContainer.innerHTML: 在页面加载时,将每个单词用 标签包裹起来,并插入到 .text 容器中。这样做的目的是为了能够独立地为每个单词添加或移除高亮样式。window.addEventListener(‘scroll’, …): 注册一个滚动事件监听器,每当页面滚动时,其中的回调函数就会被执行。getScrollFraction(): 这是一个关键的辅助函数,它计算当前页面的滚动百分比。document.documentElement.scrollTop 或 document.body.scrollTop 获取当前滚动条距离页面顶部的距离。(document.documentElement.scrollHeight || document.body.scrollHeight) – document.documentElement.clientHeight 计算总的可滚动高度(即文档总高度减去视口高度)。两者相除即可得到滚动百分比(0到1之间)。*`wordsToHighlightCount = Math.floor(scrollFraction words.length);**: 根据滚动百分比,计算出当前应该高亮的单词数量。Math.floor` 确保得到一个整数。重新渲染 textContainer.innerHTML: 这是实现动态高亮的核心。它遍历 words 数组,如果当前单词的索引小于 wordsToHighlightCount,则为其 标签添加 HIGHLIGHT_CLASS。然后将所有 重新拼接成字符串,并更新 textContainer 的 innerHTML。

完整代码示例

将上述HTML、CSS和JavaScript代码分别保存为 index.html、style.css 和 script.js,并确保它们在同一目录下。

index.html

      滚动进度文本高亮      

style.css

body {  height: 5000px; /* 确保页面有足够的滚动空间 */  margin: 0;  font-family: Arial, sans-serif;  line-height: 1.6;}.text {  position: fixed; /* 使文本在滚动时保持在视口顶部 */  top: 10px;  left: 10px;  max-width: 80%; /* 防止文本过宽 */  background-color: #f9f9f9;  padding: 10px;  border-radius: 5px;  box-shadow: 0 2px 5px rgba(0,0,0,0.1);}.text span {  transition: color 0.1s ease-out; /* 为颜色变化添加平滑过渡 */}.highlight {  color: #f00; /* 高亮文本的颜色,这里设置为红色 */  font-weight: bold;}

script.js

const HIGHLIGHT_CLASS = 'highlight'; // 定义高亮CSS类名const LOREM_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 = LOREM_TEXT.split(" "); // 将文本按空格拆分为单词数组let textContainer = document.querySelector('.text'); // 获取文本容器元素// 初始化文本内容,将每个单词包裹在中textContainer.innerHTML = words  .map(w => `${w}`)  .join(' ');// 监听窗口滚动事件window.addEventListener('scroll', () => {  let scrollFraction = getScrollFraction(); // 获取当前滚动百分比 (0-1之间)  let wordsToHighlightCount = Math.floor(scrollFraction * words.length); // 根据滚动百分比计算需要高亮的单词数量  // 重新渲染文本内容,为需要高亮的单词添加CSS类  textContainer.innerHTML = words  .map((word, index) => `<span ${index ${word}`)  .join(' ');});/** * 计算页面滚动百分比的辅助函数。 * 返回一个0到1之间的浮点数,表示当前滚动位置占总可滚动高度的比例。 */function getScrollFraction() {    var docElem = document.documentElement,         bodyElem = document.body,        scrollTopProp = 'scrollTop',        scrollHeightProp = 'scrollHeight';    // 获取当前滚动条位置 (兼容不同浏览器)    var currentScrollTop = docElem[scrollTopProp] || bodyElem[scrollTopProp];    // 获取可滚动总高度    var totalScrollHeight = (docElem[scrollHeightProp] || bodyElem[scrollHeightProp]) - docElem.clientHeight;    // 避免除以零的情况    if (totalScrollHeight <= 0) {        return 0;    }    return currentScrollTop / totalScrollHeight;}

注意事项与优化

性能考量: 频繁地修改 innerHTML 会导致浏览器重新解析和渲染DOM,这在滚动事件中可能会引起性能问题,尤其是在长文本或复杂页面上。

优化方案: 可以考虑只更新每个 元素的 class 属性,而不是整个 innerHTML。这需要先获取所有的 元素,然后根据滚动进度遍历并修改它们的 classList。例如:

// 优化后的滚动事件处理let spans = textContainer.querySelectorAll('span'); // 获取所有span元素一次window.addEventListener('scroll', () => {    let scrollFraction = getScrollFraction();    let wordsToHighlightCount = Math.floor(scrollFraction * words.length);    spans.forEach((span, index) => {        if (index < wordsToHighlightCount) {            span.classList.add(HIGHLIGHT_CLASS);        } else {            span.classList.remove(HIGHLIGHT_CLASS);        }    });});

这种方式避免了DOM的完全重建,性能会更好。

滚动速度与文本长度: 示例中 body 高度为5000px,文本较短。如果文本很长,或者页面可滚动高度很小,高亮效果可能会显得过快或过慢。可以调整 body 的高度或文本长度来平衡效果。

平滑过渡: 通过CSS transition 属性 (.text span { transition: color 0.1s ease-out; }) 可以让颜色变化更加平滑,提升用户体验。

样式定制: 高亮效果不限于改变颜色,还可以是背景色、字体粗细、渐变填充等。只需修改 .highlight CSS 类即可实现。

节流/防抖: 滚动事件触发非常频繁。在某些复杂场景下,可以考虑使用节流(throttle)或防抖(debounce)函数来限制事件处理函数的执行频率,进一步优化性能。

总结

通过结合JavaScript的滚动事件监听和DOM操作,我们可以实现各种富有创意的滚动驱动动画效果。本文详细介绍了如何根据页面滚动百分比动态高亮文本的实现方法,并提供了完整的代码示例和性能优化建议。掌握这一技术,您可以为您的网页增添独特的交互性和视觉吸引力。在实际项目中,请务必考虑性能优化,以提供流畅的用户体验。

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

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

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月20日 13:12:49
下一篇 2025年12月8日 04:35:00

相关推荐

  • jQuery Validate 中带点号 name 属性的验证配置详解

    本文旨在解决 jQuery Validate 插件在处理包含点号(.)的 HTML name 属性时,无法正确触发验证规则的问题。核心解决方案在于,当 name 属性包含非标准标识符字符(如点号)时,必须在 jQuery Validate 的 rules 和 messages 配置中将其作为字符串字…

    好文分享 2025年12月20日
    000
  • Next.js 服务器组件中处理相对路径 API 路由 Fetch 错误的指南

    本文旨在解决 Next.js 服务器组件中使用相对路径调用内部 API 路由时遇到的 TypeError: Failed to parse URL 错误。我们将探讨该问题在 Node.js 环境下的根源,并提供两种主要解决方案:一是通过环境变量配置绝对 URL 进行数据请求,以适应不同部署环境;二是…

    2025年12月20日
    000
  • Tailwind CSS top 属性值自定义指南

    本文旨在解决在 Tailwind CSS 中直接扩展 top 属性无效的问题。我们将深入探讨 Tailwind CSS top、right、bottom、left 等定位工具类的生成机制,并提供两种正确的自定义方法:通过扩展 spacing 或 inset 配置,从而实现灵活的自定义值,例如使用 C…

    2025年12月20日
    000
  • JavaScript递归数组结构转换与父节点数据聚合计算

    本文详细阐述如何将具有多层嵌套的JavaScript数组转换为统一的递归树形结构,并着重解决在父节点上聚合其所有子节点数值型数据(如总数和可用量)的挑战。通过分步实现,首先进行结构映射,随后利用后处理机制对父节点数据进行汇总,确保在任意深度层级下都能准确完成数据整合。 1. 问题背景与目标 在前端开…

    2025年12月20日
    000
  • JavaScript递归数组数据转换与父节点聚合统计

    本文详细介绍了如何将一个具有嵌套结构的JavaScript数组转换为另一种递归树形结构,并在此过程中实现父节点属性(如total和available)的聚合计算。通过分两阶段处理:首先进行递归的结构转换,然后对顶层父节点执行后处理聚合,我们能够有效地管理复杂数据转换与汇总需求,确保数据的完整性和准确…

    2025年12月20日
    000
  • Tailwind CSS:正确扩展top属性的姿势

    本教程详细阐述了在Tailwind CSS中如何正确扩展top属性以定义自定义值。不同于直接修改top配置,正确的做法是通过扩展spacing或inset主题配置来添加自定义尺寸,从而为top-、right-、bottom-、left-等定位工具类提供新的值,并支持使用CSS变量实现动态控制。 在T…

    2025年12月20日
    000
  • jQuery Validate 验证规则失效问题解析:确保字段名与配置精准匹配

    本文深入探讨了在使用 jQuery Validate 时,因字段名配置不当导致验证规则无法触发的常见问题。核心在于 rules 和 messages 配置中,字段名必须严格匹配 HTML input 元素的 name 属性,特别是当字段名包含特殊字符(如点号 .)时,需使用引号包裹。文章提供了正确的…

    2025年12月20日
    000
  • Django用户不活动自动登出与后端状态更新策略

    本文探讨了在Django中实现用户不活动自动登出及后端状态更新的策略。核心挑战在于HTTP的无状态性,使得在没有用户请求的情况下检测并响应不活动状态变得复杂。文章详细介绍了如何通过Django的会话管理和自定义中间件来实现基于请求的登出机制,并探讨了使用如Celery等定时任务来处理真正的“无请求”…

    2025年12月20日
    000
  • JavaScript控制元素可见性:实现单元素切换与多元素互斥显示

    本教程将详细讲解如何使用JavaScript控制HTML元素的显示与隐藏。内容涵盖基础的单元素可见性切换方法,以及更复杂的场景,例如在多个可切换元素中,点击其中一个时,自动隐藏其他已显示的元素,确保始终只有一个元素可见。 基础:单元素可见性切换 在web开发中,我们经常需要根据用户的交互来显示或隐藏…

    2025年12月20日 好文分享
    000
  • JavaScript动态控制元素可见性教程:实现单元素与多元素互斥切换

    本教程详细阐述如何使用JavaScript控制HTML元素的可见性,从基础的单元素显示/隐藏切换,到更复杂的多个元素之间互斥显示逻辑的实现。文章将通过代码示例,指导读者如何利用display属性或CSS类来管理元素状态,并探讨事件监听、HTML数据属性的应用,以及在实际开发中提升代码健壮性和用户体验…

    2025年12月20日
    000
  • 解决JavaScript无限循环中的堆内存溢出问题

    本文旨在解决JavaScript无限循环中出现的“堆内存溢出”错误。通过分析问题原因,并结合setInterval方法,提供一种避免无限循环阻塞主线程、有效管理内存的解决方案,确保程序能够长时间稳定运行。 在JavaScript中,当执行无限循环时,即使循环体内部没有显式地创建新变量或分配内存,仍然…

    2025年12月20日
    000
  • 解决JavaScript无限循环与内存溢出:使用异步调度避免堆内存限制

    本文探讨了JavaScript中执行无限循环时遇到的“堆内存溢出”问题。即使循环操作看似简单,直接的while(true)循环也会阻塞事件循环,导致垃圾回收无法进行,最终耗尽内存。教程将详细介绍如何利用setInterval或requestAnimationFrame等异步调度机制,实现长时间运行的…

    2025年12月20日
    000
  • 解决JavaScript无限循环导致的堆内存溢出:异步任务调度实践

    本文探讨了JavaScript中“无限”同步循环导致堆内存溢出(JavaScript heap out of memory)的常见问题。即使循环内操作简单且不显式分配新内存,持续的同步执行也会阻止垃圾回收器工作并耗尽内存。教程推荐使用setInterval或requestAnimationFrame…

    2025年12月20日
    000
  • 使用Prisma Client Extensions集成外部数据与异步计算字段

    本文深入探讨如何利用Prisma Client Extensions,特别是其计算字段功能,将数据库查询结果与外部API数据或异步计算逻辑相结合。通过示例代码,我们展示了如何在Prisma模型中添加异步计算字段,从而实现数据聚合与扩展,提升数据模型的表达能力,并讨论了相关性能与最佳实践。 在现代应用…

    2025年12月20日
    000
  • JsPDF中异步添加图片并自动计算宽度:常见陷阱与解决方案

    本教程详细阐述了如何在JsPDF中实现图片异步加载并自动计算宽度,重点解决了在使用自定义函数添加图片时,JsPDF实例作用域不正确以及未调用doc.save()方法导致图片不显示的问题。文章通过代码示例和专业解析,指导读者正确传递jsPDF对象并管理PDF生成流程,确保图片能成功嵌入并显示在生成的P…

    2025年12月20日
    000
  • 解决Heroku上Puppeteer运行次数受限问题:内存泄漏排查与优化

    本文旨在帮助开发者解决在使用Puppeteer在Heroku上进行网页数据抓取时,程序运行次数受限的问题。通过分析常见原因,特别是内存泄漏问题,并提供相应的解决方案,确保Puppeteer应用在Heroku环境下稳定可靠地运行。 问题分析 在Heroku上部署Puppeteer应用时,经常会遇到程序…

    2025年12月20日
    000
  • 使用 JsPDF 动态调整图片宽度并添加到 PDF 的教程

    本文档旨在指导开发者如何使用 JsPDF 库,根据图片宽高比动态计算宽度,并将图片添加到 PDF 文档中。我们将提供一个完整的函数示例,并解释可能遇到的问题以及解决方案,确保图片能够正确显示在 PDF 中。通过本文,你将学会如何灵活地处理图片尺寸,并将其无缝集成到你的 PDF 生成流程中。 在使用 …

    2025年12月20日
    000
  • 解决 Puppeteer 在 Heroku 上运行中断:内存泄漏与浏览器资源管理

    本教程探讨 Puppeteer 在 Heroku 等云平台运行时,在执行少量任务后停止并抛出超时错误的问题。核心原因在于未正确关闭 Puppeteer 浏览器实例导致的内存泄漏。文章将详细解释这一现象,并提供通过在每次数据抓取后显式调用 browser.close() 来有效管理资源、防止内存耗尽的…

    2025年12月20日
    000
  • 使用 JsPDF 动态调整图片宽度并添加到 PDF 的正确方法

    本文介绍了如何使用 JsPDF 库动态计算图片宽度,并将其添加到 PDF 文档中。通过封装一个可复用的函数,可以方便地根据图片高度和宽高比自动调整图片宽度,避免手动计算的繁琐。文章提供了完整的代码示例,并指出了常见错误和注意事项,帮助开发者快速实现图片添加功能。 在使用 JsPDF 生成 PDF 文…

    2025年12月20日
    000
  • 监听特定点击事件并阻止其他事件触发

    本文旨在解决在HTML表格行绑定点击事件跳转链接的同时,如何阻止表格行内复选框点击事件触发跳转的问题。通过事件目标检测,可以精准地控制点击事件的响应,从而实现只在特定元素(非复选框)点击时才执行跳转逻辑,保证用户交互的灵活性和可控性。 监听特定点击事件并阻止其他事件触发 在Web开发中,经常会遇到需…

    2025年12月20日
    000

发表回复

登录后才能评论
关注微信