JS原生实现浏览器滚动条滚动侧边栏高亮响应

news2024/11/18 1:33:59

目录

演示

​编辑

需求

代码

css

html

script

代码解释

情况1

情况2

4、设置高亮

5、添加节流,减少触发回调的频率


演示

需求

左侧侧边栏link1、link2...所对应右侧内容link1-content、link2-content...,当鼠标点击link的时候,自动滚动到对应的content。手动拖动滚动条,左侧link进行高亮响应,当link2-content出现在视口的时候,左侧link2高亮,当link2-content和link3-content同时出现在视口的时候,左侧link2高亮(谁接近视口顶部,对应的link高亮)。

代码

css

      * {
        padding: 0;
        margin: 0;
        list-style: none;
      }
      .header {
        height: 200px;
        background-color: aqua;
      }
      .main {
        padding: 30px 0;
        display: flex;
        max-width: 1400px;
        margin: 0 auto;
        gap: 30px;
      }
      .main .sidebar {
        position: sticky;
        top: 0;
        width: 300px;
        align-self: start;
      }
      .main .content {
        display: flex;
        flex: 1;
        flex-direction: column;
        gap: 30px;
      }
      .main .content .content-item{
        background-color: aqua;
        height: 400px;
      }
      .main .sidebar ul li{
        padding: 20px 10px;
        background-color: aqua;
      }

      .main .sidebar ul li .active{
        color: red;
      }
      .footer {
        height: 200px;
        background-color: aqua;
      }

html

  <body>
    <section class="header"></section>
    <section class="main">
      <div class="sidebar">
        <ul>
          <li><a class="active" href="#content-item1">link1</a></li>
          <li><a href="#content-item2">link2</a></li> // 设置锚点所对应的content的id
          <li><a href="#content-item3">link3</a></li>
          <li><a href="#content-item4">link4</a></li>
          <li><a href="#content-item5">link5</a></li>
          <li><a href="#content-item6">link6</a></li>
        </ul>
      </div>
      <div class="content">
        <div id="content-item1" class="content-item">link1-content</div>
        <div id="content-item2" class="content-item">link2-content</div>
        <div id="content-item3" class="content-item">link3-content</div>
        <div id="content-item4" class="content-item">link4-content</div>
        <div id="content-item5" class="content-item">link5-content</div>
        <div id="content-item6" class="content-item">link6-content</div>
      </div>
    </section>
    <section class="footer"></section>
  </body>

script

      const allLinks = document.querySelectorAll("a:link");
      allLinks.forEach(function (link) {
        link.addEventListener("click", function (e) {
          e.preventDefault();
          const href = link.getAttribute("href");
          if ( href.startsWith("#")) {
            const sectionEl = document.querySelector(href);
            link_content.scrollIntoView({ behavior: "smooth" });
          }
        });
      });

设置link的href和link-content的id所对应,调用scrollIntoView({ behavior: "smooth" })自动滚动到对应的位置。

      const handleScroll = () => {
        const allContents = document.querySelectorAll(".content-item");
        const rectContent = [];
        allContents.forEach((ele) => {
          const eleRect = ele.getClientRects()[0];
          if (
            eleRect.top >= 0 &&
            window.innerHeight - eleRect.top >= eleRect.height
          ) {
            rectContent.push(ele);
          } else if (eleRect.top >= 0) {
            rectContent.push(ele);
          }
        });
        let linkId
        if (rectContent[0]) linkId = rectContent[0].id
        allLinks.forEach(link => link.classList.remove('active'))
        const linkDom = document.querySelector(`a[href="#${linkId}"]`)
        linkDom.classList.add('active')
      }
      window.addEventListener("scroll", function() {
        throttle(handleScroll, 100)();
      });
      window.addEventListener('mouseup', function() {
        throttle(handleScroll, 100)();
      });

代码解释

浏览器滚动,每次滚动触发scroll回调

往数组追加值分两种情况

情况1

link-content1和link-content2都完全出现在视口中,谁接近视口顶部,对应的link高亮

情况2

都没有出现在视口中,则取出现在视口第一个与视口顶部,top > 0的值

4、设置高亮

        let linkId
        if (rectContent[0]) linkId = rectContent[0].id
        allLinks.forEach(link => link.classList.remove('active'))
        const linkDom = document.querySelector(`a[href="#${linkId}"]`)
        linkDom.classList.add('active')

找到存储在数组的第一项link-content,获取id,根据id获取对应的侧边栏link,清空之前设置的link的类active,为对应的link添加类active。

5、添加节流,减少触发回调的频率

      const throttle = (fn, delay) => {
        let lastExecuted = 0;
        return function() {
          const now = Date.now();
          if (now - lastExecuted > delay) {
            fn();
            lastExecuted = now;
          }
        }
      }

      window.addEventListener("scroll", function() {
        throttle(handleScroll, 100)();
      });
      window.addEventListener('mouseup', function() {
        throttle(handleScroll, 100)();
      });

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1295086.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【EMNLP 2023】面向Stable Diffusion的自动Prompt工程算法BeautifulPrompt

近日&#xff0c;阿里云人工智能平台PAI与华南理工大学朱金辉教授团队合作在自然语言处理顶级会议EMNLP2023上发表了BeautifulPrompt的深度生成模型&#xff0c;可以从简单的图片描述中生成高质量的提示词&#xff0c;从而使文生图模型能够生成更美观的图像。BeautifulPrompt通…

谷歌Gemini刚发就惹质疑:测试标准有失偏颇,效果视频疑似剪辑

梦晨 克雷西 发自 凹非寺 量子位 | 公众号 QbitAI 谷歌憋了许久的大招&#xff0c;双子座Gemini大模型终于发布&#xff01;其中一图一视频最引人注目&#xff1a; 一图&#xff0c;MMLU多任务语言理解数据集测试&#xff0c;Gemini Ultra不光超越GPT-4&#xff0c;甚至超越了…

拆解贝医生冲牙器F3,换电池

是这款伸缩式的&#xff0c;如下图&#xff0c; 用了差不多两年&#xff0c;终于充不了电&#xff0c;而且不能开机&#xff0c;估计是电池坏了&#xff0c;拆开试一下。 一、拆解 拆解难度不算大&#xff0c;本来以为这东西为了防水肯定要用一堆胶水&#xff0c;没想到只是卡…

十大最好猫主食罐头有哪些品牌?排名前五猫主食罐头品牌推荐

我发现不少人有这样的困扰&#xff01;买到各种数值都很好的猫罐头后&#xff0c;猫咪一点都不吃。或者是猫咪吃了猫罐头之后&#xff0c;吃了一段时间后就软便身体不舒服。 猫罐头侠登场&#xff01;养猫这么久了我就把我吃的不错的猫罐头分享一下&#xff01;别纠结了&#…

❤ Mac IDEA使用并运行项目

❤ IDEA导入项目并运行 Mac IDEA使用 (1) 仓库导入 通过获取giett仓库包的url&#xff0c;在idea中导入项目 在gitee里获取项目的ur打开idea&#xff0c;点击 File->new->Project from Version Control (2) 创建数据库ry并导入数据脚本 &#xff08;3&#xff09;修改配…

Altair Radioss碰撞 安全与冲击 衡祖仿真

Altair Radioss是解决瞬态加载工况下非线性问题的领先的结构分析求解器。其具备高扩展性、高品质、高鲁棒性&#xff0c;以及诸多功能&#xff1a;多域求解技术、高级材料功能(复合材料)等。Radioss求解器被广泛应用于汽车、航空航天、电子/家电、包装、轨道机车、生物医疗、能…

harmony开发之Text组件的使用

TextInput、TextArea是输入框组件&#xff0c;通常用于响应用户的输入操作&#xff0c;比如评论区的输入、聊天框的输入、表格的输入等&#xff0c;也可以结合其它组件构建功能页面&#xff0c;例如登录注册页面。 图片来源黑马程序员 Text组件的使用&#xff1a; 文本显示组…

【C++】开源:Boost配置文件解析库PropertyTree配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍Boost配置文件解析库PropertyTree配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注…

js写旋转的时钟动态

目录 1、css代码 2.html代码 3.js代码 1、css代码 .box {position: relative;width: 600px;height: 600px;background: url(./images/clock.jpg) no-repeat center;}.hour,.minute,.second {position: absolute;left: 0;top: 0;width: 100%;height: 100%;}.hour {background…

RHEL8_Linux访问NFS存储及自动挂载

本章主要介绍NFS客户端的使用 创建FNS服务器并通过NFS共享一个目录在客户端上访问NFS共享的目录自动挂载的配置和使用 1.访问NFS存储 前面介绍了本地存储&#xff0c;本章就来介绍如何使用网络上的存储设备。NFS即网络文件系统&#xff0c;所实现的是 Linux 和 Linux 之间的共…

JOSEF 单稳态中间继电器 UEG/A-4H-L DC110V 导轨安装

系列型号 UEG/A-2H2D中间继电器UEG/A-4H4D中间继电器UEG/A-2D中间继电器 UEG/A-2H中间继电器UEG/A-4H中间继电器UEG/A-4D中间继电器 UEG/A-6H中间继电器UEG/A-6D中间继电器UEG/A-8H中间继电器 UEG/A-10D中间继电器UEG/A-10H中间继电器UEG/A-2DPDT中间继电器 UEG/A-4DPDT中…

注意力机制的快速学习

注意力机制的快速学习 注意力机制 将焦点聚焦在比较重要的事物上 我&#xff08;查询对象Q&#xff09;&#xff0c;这张图&#xff08;被查询对象V&#xff09; 我看一张图&#xff0c;第一眼&#xff0c;就会判断那些东西对我而言比较重要&#xff0c;那些对于我不重要&…

JVM的内存结构详解「重点篇」

一、JVM虚拟机数据区 虚拟机栈 1、 线程私有 2、 每个方法被执行的时候都会创建一个栈帧用于存储局部变量表&#xff0c;操作栈&#xff0c;动态链接&#xff0c;方法出口等信息。每一个方法被调用的过程就对应一个栈帧在虚拟机栈中从入栈到出栈的过程。 3、栈帧: 是用来存储…

数字化升级,智慧医疗新时代——医院陪诊服务的技术创新

在信息技术飞速发展的今天&#xff0c;医疗服务正迎来数字化升级的新时代。本文将探讨如何通过先进技术的应用&#xff0c;为医院陪诊服务注入更多智慧元素&#xff0c;提升患者和家属的医疗体验。 1. 创新医疗预约系统 # Python代码演示医疗预约系统的简单实现 class Medic…

最新国内可用GPT4,Midjourney绘画网站+使用教程

一、前言 ChatGPT GPT4.0&#xff0c;Midjourney绘画&#xff0c;相信对大家应该不感到陌生吧&#xff1f;简单来说&#xff0c;GPT-4技术比之前的GPT-3.5相对来说更加智能&#xff0c;会根据用户的要求生成多种内容甚至也可以和用户进行创作交流。 然而&#xff0c;GPT-4对普…

ChatGPT有什么新奇的使用方式?

2023&#xff0c;ChatGPT几乎席卷了所有行业&#xff0c;并且具有不可测量的巨大潜力等着我们去挖掘。 越来越多人对ChatGPT的应用产生兴趣&#xff0c;知乎上“ChatGPT有什么新奇的使用方式&#xff1f;”这一个热门话题的兴起就是最好的证明。 写作&#xff0c;毫无疑问&…

【Java探索之旅】我与Java的初相识(一):Java的特性与优点及其发展史

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; Java入门到精通 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 一. Java语言概述与优势1.1 Java的概述1.2 Java语言的优势 二. Java领域与发展史2.1 Java的使用领域2.…

中国开源大模型登顶HuggingFace排行榜

12月8日消息&#xff0c;全球最大的开源大模型社区HuggingFace日前公布了最新的开源大模型排行榜&#xff0c;阿里云通义千问力压Llama2等国内外开源大模型登顶榜首。 HuggingFace的开源大模型排行榜&#xff08;Open LLM Leaderboard&#xff09;是目前大模型领域最具权威性的…

基于python+unittest实现接口自动化测试

简介 本文通过从Postman获取基本的接口测试Code简单的接口测试入手&#xff0c;一步步调整优化接口调用&#xff0c;以及增加基本的结果判断&#xff0c;讲解Python自带的Unittest框架调用&#xff0c;期望各位可以通过本文对接口自动化测试有一个大致的了解。 为什么要做接口…

VMware虚拟机搭建+云平台购买搭建(阿里云+UCloud)【设置主机名以及主机名映射、配置免密登录、配置JDK】

本地虚拟机的搭建 一、准备网段 在VMware的虚拟网络编辑器中将VMnet8虚拟网卡的 网段设置为&#xff1a;192.168.88.0网关设置为&#xff1a;192.168.88.2 二、下载CentOS操作系统文件&#xff0c;并安装 三、克隆多台虚拟机 依照同样的方法&#xff0c;克隆出node2…