css伪元素实现li列表圆点相连+锚点跳转悬浮窗实现

实现效果:
在这里插入图片描述
html代码:

<div class="sidenav">
  <ul class="nav-text progressbar">
    <!-- data-target的值对应要跳转的模块的id -->
        <li data-target="module1"><div class="text">锚点名称</div></li>
        <li data-target="module2"><div class="text">锚点名称</div></li>
        <li data-target="module3"><div class="text">锚点名称</div></li>
        <li data-target="module4"><div class="text">锚点名称</div></li>
  </ul>
</div>

给要跳转的dom元素id赋值即可。

css:

/* 侧边锚点跳转 */
.sidenav {
  z-index: 40;
  left: 1%;
  bottom: 15%;
  min-height: 55px;
  position: fixed;
  /* width: 140px; */
  background: #ffffff;
  box-shadow: 0px 0px 35px 0px rgba(106, 76, 248, 0.16);
  border-radius: 8px;
  padding: 25px 22px 0px 16px;
}

.progressbar li {
  list-style-type: none;
  /* float: left; 
  width: 33.33%;  */
  position: relative;
  text-align: center;
  font-size: 16px;
  align-items: center;
  display: flex;
  height: 42px;
  max-width: 102px;
  margin-bottom: 25px;
}

.progressbar .text {
  -webkit-box-orient: vertical;
  display: -webkit-box;
  /* width: 64px; */
  width: 80px;
  text-align: left;
  -webkit-line-clamp: 2;
  overflow: hidden;
  text-overflow: ellipsis;
color: #333333;
cursor: pointer;
}

.progressbar li:before {
  content: "";
  text-align: center;
  width: 12px;
  height: 12px;
background: #999999;
  border-radius: 50%;
  margin-right: 10px;
}

.progressbar li:after {
  /* 伪元素实现li圆点垂直相连的线*/
  top: -13px;
  transform: translate(-50%, 0) rotate(90deg);
  content: "";
  position: absolute;
  width: 66%;
  height: 1px;
  background: #999999;;
  left: 6px;
  z-index: -1;
}

.progressbar li:first-child:after {
  content: none;
}

js:

 // 避免点击事件触发时,触发滚动事件增加active类的函数
    var isProgressBarClick = false;
    // 获取悬浮窗的ul元素
    const moduleList = document.querySelector('.progressbar');

    var timeoutId = null;
    // 滚动到对应模块并添加active类的点击事件处理函数
    function scrollToModule(event){
      isProgressBarClick = true;
      var aim = event.target;
      if(event.target.className === 'text'){
        aim = event.target.parentNode
      }
      const targetModuleId = aim.getAttribute('data-target');
      const targetModule = document.getElementById(targetModuleId);
      if (targetModule) {
        // 使用平滑滚动实现滚动效果
        targetModule.scrollIntoView({ behavior: 'smooth' });

        // 移除之前被添加的active类
        const activeItem = document.querySelector('.progressbar li.active');
        if (activeItem) {
          activeItem.classList.remove('active');
        }

        // 为当前点击的列表项添加active类
        aim.classList.add('active');
      }
      // 等待锚点跳转完成后再重置标志变量
      clearTimeout(timeoutId);
      timeoutId = setTimeout(function() {
        isProgressBarClick = false;
      }, 1000);
    }

    $('.progressbar li').click(scrollToModule)
    $('.progressbar li .text').click(scrollToModule)

    // 监听页面滚动事件
    window.addEventListener('scroll', handleScroll);

    
    function handleScroll() {
      if(!isProgressBarClick){
        // 获取页面滚动的垂直位置
        const scrollPosition = window.scrollY;

        // 遍历模块元素,找到当前可见的模块
        var activeModuleId = null;
        var moduleElements = document.querySelectorAll('.module_list>div')

        for (const moduleElement of moduleElements) {
          // 用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置
          const { top, bottom } = moduleElement.getBoundingClientRect();
          // 判断模块是否在视口内(至少一半在视口内)
          if (top <= window.innerHeight / 2 && bottom >= window.innerHeight / 2) {
            activeModuleId = moduleElement.id;
            break;
          }
        }

        // 添加active类
        if (activeModuleId) {
          // 移除之前被添加的active类
          const activeItem = document.querySelector('.progressbar li.active');
          if (activeItem) {
            activeItem.classList.remove('active');
          }

          // 为当前可见的模块对应的列表项添加active类
          const activeListItem = document.querySelector(`.progressbar li[data-target="${activeModuleId}"]`);
          if (activeListItem) {
            activeListItem.classList.add('active');
          }
        }
      }
    }
    // 初始加载时触发一次滚动事件
    handleScroll();

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

安防视频监控汇聚平台EasyCVR视频监控综合管理平台接入Ehome告警,公网快照不显示的问题解决步骤

智能视频监控汇聚平台TSINGSEE青犀视频EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等&#xff0c;视频监控管理平台…

【JavaEE进阶】SpringBoot项目的创建

文章目录 一. SpringBoot简介1. 什么是SpringBoot?2. SpringBoot的优点 二. SpringBoot项目创建1. 使用IDEA创建2. 使用网页创建SpringBoot项目 三. 运行SpringBoot项目 一. SpringBoot简介 1. 什么是SpringBoot? Spring Boot 是一个用于快速构建基于 Spring 框架的应用程序…

Oracle和MySQL有哪些区别?从基本特性、技术选型、字段类型、事务、语句等角度详细对比Oracle和MySQL

导航&#xff1a; 【Java笔记踩坑汇总】Java基础进阶JavaWebSSMSpringBoot瑞吉外卖SpringCloud黑马旅游谷粒商城学成在线MySQL高级篇设计模式面试题汇总源码_vincewm的博客-CSDN博客 目录 一、基本区别 1.1 基本特性 1.2 Oracle和MySQL如何做技术选型&#xff1f; 1.3 RDBM…

BaseMapper的insert方法快速插入数据未提交问题

一、前言 今天测试一批日志数据插入数据库&#xff0c;发现通过BaseMapper的int insert(T entity);方法在大量数据进行插入的时候插入的数据变成了未提交。意思就是程序运行insert成功&#xff0c;但是数据库里却没有数据。当一条一条数据插入的时候却是可以的&#xff0c;循环…

基于Yolov5与LabelImg训练自己数据的完整流程

基于Yolov5与LabelImg训练自己数据的完整流程 1. 创建虚拟环境2. 通过git 安装 ultralytics3. 下载yolov54. 安装labelImg标注软件5. 使用labelImg进行标注&#xff0c;图片使用上面的coco1285.1 点击“打开目录”选择存储图像的文件夹进行标注&#xff0c;右下角会出现图像列表…

【图像融合】融合算法综述(持续更新)

按时间顺序&#xff0c;综述近5年的融合算法。重点分析了最近两年的work&#xff0c;欢迎留言探讨 文章目录 前言1.SSR-Laplacian Image Fusion&#xff08;2017&#xff09;2、FusionGAN&#xff08;2019&#xff09;3、MBNet&#xff08;2020&#xff09;4、DIDFuse&#xff…

SQL-每日一题【1341. 电影评分】

题目 表&#xff1a;Movies 表&#xff1a;Users 请你编写一个解决方案&#xff1a; 查找评论电影数量最多的用户名。如果出现平局&#xff0c;返回字典序较小的用户名。查找在 February 2020 平均评分最高 的电影名称。如果出现平局&#xff0c;返回字典序较小的电影名称。 …

【STM32RT-Thread零基础入门】 3. PIN设备(GPIO)的使用

硬件&#xff1a;STM32F103ZET6、ST-LINK、usb转串口工具、4个LED灯、1个蜂鸣器、4个1k电阻、2个按键、面包板、杜邦线 文章目录 前言一、PIN设备介绍1. 引脚编号获取2. 设置引脚的输入/输出模式3. 设置引脚的电平值4. 读取引脚的电平值5. 绑定引脚中断回调函数6. 脱离引脚中断…

【算法题】螺旋矩阵IV (求解n阶折线蛇形矩阵)

一、问题的提出 n阶折线蛇形矩阵的特点是按照图1所示的方式排列元素。n阶蛇形矩阵是指矩阵的大小为nn&#xff0c;其中n为正整数。 题目背景 一个 n 行 n 列的螺旋矩阵可由如图1所示的方法生成&#xff0c;观察图片&#xff0c;找出填数规律。填数规则为从 1 开始填到 nn。 …

hive-无法启动hiveserver2

启动hiveserver2没有反应&#xff0c;客户端也无法连接( beeline -u jdbc:hive2://node01:10000 -n root) 报错如下 查看hive的Log日志&#xff0c;发现如下报错 如何解决 在hive的hive_site.xml中添加如下代码 <property><name>hive.server2.active.passive…

UDS (Unified Diagnostic Services)汽车诊断标准协议

作者博客主页 作者 : Eterlove 一笔一画&#xff0c;记录我的学习生活&#xff01;站在巨人的肩上Standing on Shoulders of Giants! 该文章为原创&#xff0c;转载请注明出处和作者 参考文献&#xff1a; 《道路车辆统一诊断服务(UDS) Road vehicles - Unified diagnostic s…

__ob__: Observer 后缀的数组的取值方式

开发中&#xff0c;经常从接口、父组件中&#xff0c;拿到数组然后给新的数组使用&#xff0c; 但是&#xff0c;有时候会发现带有 __ob__: Observer 后缀的数组&#xff0c;对这种数组来说&#xff0c;你是无法取到这个数组的值的&#xff0c; 而且&#xff0c;离谱的是consol…

【Rust】Rust学习 第十章泛型、trait 和生命周期

泛型是具体类型或其他属性的抽象替代。我们可以表达泛型的属性&#xff0c;比如他们的行为或如何与其他泛型相关联&#xff0c;而不需要在编写和编译代码时知道他们在这里实际上代表什么。 之后&#xff0c;我们讨论 trait&#xff0c;这是一个定义泛型行为的方法。trait 可以…

MAC环境,在IDEA执行报错java: -source 1.5 中不支持 diamond 运算符

Error:(41, 51) java: -source 1.5 中不支持 diamond 运算符 (请使用 -source 7 或更高版本以启用 diamond 运算符) 进入设置 修改java版本 pom文件中加入 <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin&l…

matlab使用教程(16)—图论中图的定义与修改

1.修改现有图的节点和边 此示例演示如何使用 addedge 、 rmedge 、 addnode 、 rmnode 、 findedge 、 findnode 及 subgraph 函数访问和修改 graph 或 digraph 对象中的节点和/或边。 1.1 添加节点 创建一个包含四个节点和四条边的图。s 和 t 中的对应元素用于指定每条…

什么是前端框架?怎么学习? - 易智编译EaseEditing

前端框架是一种用于开发Web应用程序界面的工具集合&#xff0c;它提供了一系列预定义的代码和结构&#xff0c;以简化开发过程并提高效率。 前端框架通常包括HTML、CSS和JavaScript的库和工具&#xff0c;用于构建交互式、动态和响应式的用户界面。 学习前端框架可以让您更高效…

Android 组件

TextView 文本框 用于显示文本的一个控件。文本的字体尺寸单位为 sp 。sp: scaled pixels(放大像素). 主要用于字体显示。 文本常用属性 属性名说明id为TextView设置一个组件id&#xff0c;根据id&#xff0c;我们可以在Java代码中通过 findViewById()的方法获取到该对象&…

vue实现a组件中数据变化b组件实时更新(ab组件无关联)

需求&#xff1a;A组件新增、编辑或者删除数据时&#xff0c;B组件实时更新数据 // src/utils/bus.js// bus.$emit(bridge-updated) 是在事件总线实例 bus 上触发了一个自定义事件 // data-updated&#xff0c;相当于发布了一个事件。// bus.$on(bridge-update…

面试热题(合并K个升序链表)

给定一个链表数组&#xff0c;每个链表都已经按升序排列。 请将所有链表合并到一个升序链表中&#xff0c;返回合并后的链表。 输入&#xff1a;lists [[1,4,5],[1,3,4],[2,6]] 输出&#xff1a;[1,1,2,3,4,4,5,6] 解释&#xff1a;链表数组如下&#xff1a; [1->4->5,1…

ssh做端口转发

问题 主机1能访问外网&#xff0c;主机2 不能访问外网外部主机想要访问主机2 解决 在主机1和主机2之间建隧道。 在主机1上做本地端口转发。可以用ssh来做本地端口转发(转发到远端)。 方法&#xff1a; 在&#xff08;本地&#xff09;主机1上执行 ssh -C -f -N -g -L 10.…