js:锚点滚动到页面对应区域

锚点跳转到对应页面的区域使用 scrollIntoView

// anchor即你要跳转到的元素
anchor.scrollIntoView({
  behavior: "smooth",  
  block: "center",  
  inline: "nearest"  
});

1、behavior:定义滚动行为。它可以设置为 “auto” 或 “smooth”。默认是 “auto”。
“auto”:立即跳转到元素,没有动画。
“smooth”:平滑地滚动到元素,有动画效果。

2、block:定义垂直方向的对齐方式。它可以设置为 “start”、“center”、“end” 或 “nearest”。默认是 “start”。
“start”:元素的顶部与视口的顶部对齐。
“center”:元素的中心与视口的中心对齐。
“end”:元素的底部与视口的底部对齐。
“nearest”:滚动到最接近视口的位置。

3、inline:定义水平方向的对齐方式。它可以设置为 “start”、“center”、“end” 或 “nearest”。默认是 “nearest”。
“start”:元素的左侧与视口的左侧对齐。
“center”:元素的中心与视口的中心对齐。
“end”:元素的右侧与视口的右侧对齐。
“nearest”:滚动到最接近视口的位置。

下面代码主要是针对具体项目可能遇到的一些问题,主要是我自己做一个记录,上面其实已经给出了答案,大家酌情看下面的内容:
在这里插入图片描述

监听滚动的盒子 html 结构

<div ref="scrollFun">
  <div class="compute-nav-num" id="navEle1"></div>
  <div class="compute-nav-num" id="navEle2"></div>
  <div class="compute-nav-num" id="navEle3"></div>
</div>

监听滚动的盒子js逻辑

const scrollFun = ref();
onMounted(() => {
  scrollFun.value.addEventListener('scroll', handleScroll);
});
onBeforeUnmount(() => {
  scrollFun.value.removeEventListener('scroll', handleScroll)
});
const handleScroll = () => {
  handleScroll();
};
const closeEventFun = () => {
  scrollFun.value.removeEventListener('scroll', handleScroll);
}
const openEventFun = () => {
  scrollFun.value.addEventListener('scroll', handleScroll);
}

const handleScroll = () => {
  if (scrollTimer) {
    clearTimeout(scrollTimer);
  }
  scrollTimer = setTimeout(() => {
    // compute-nav-num 这个类名是为了收集所有滚动的盒子里的子集
    const viewList = document.querySelectorAll('.compute-nav-num');
    let active = 0;
    if (viewList.length === 0) return;
    for (let i = 0; i < viewList.length; i++) {
      const top = (scrollFun as any).value.scrollTop + 30;
      if (i === 0) {
        const next = (viewList[i + 1] as any).offsetTop;
        if (top < next) {
          active = i;
          break;
        }
      } else {
        const target = (viewList[i] as any).offsetTop;
        const next = (viewList[i + 1] as any).offsetTop;
        if (top > target || top == target) {
          if (top < next) {
            active = i;
            break;
          }
        }
      }
    }
    activeNavIndex.value = active + 1;
  }, 50);
};
const routerClick = (obj: any) => {
  // i是点亮导航栏的
  activeNavIndex.value = Number(obj.i);
  // id是固定的 是控制滚动的
  viewActive(obj.id);
};
const viewActive = (id: any) => {
  // 当点击导航栏时清除滚动监听,这是因为scrollIntoView事件,也会触发滚动监听
  // 关闭主要是因为,最下面总有几个特别小的盒子,滚动其实是无法点亮对应导航栏的
  // 点击属于最后几个小盒子对应的导航栏时,如果滚动监听也触发了,那最后算的 activeNavIndex肯定不对
  closeEventFun();
  const anchor = document.querySelector('#navEle' + id);
  if (anchor) {
    anchor.scrollIntoView({
      behavior: 'smooth'
    });
  }
  // 下面的事件既是滚动的一个事件间隔,争取在滚动结束后,再放开监听
  setTimeout(() => {
    openEventFun();
  }, 850);
}

导航栏组件

// 这里的数据 id之所以写这里,是为了固定id数值,这样是为了适应,导航栏有时在某些情况下
// 需要隐藏一些,这时 index 就是随机的,加上固定id,点击传出,这样 querySelector 才能找到
let navListObj: any = reactive([
  {
    name: '工单',
    id: '1',
    img: orderInfo,
    imgActive: orderInfoActive
  },
  {
    name: '来电',
    id: '2',
    img: phoneInfo,
    imgActive: phoneInfoActive
  }
]);
// 点击传出参数
const emit = defineEmits(["routerClick"]);
const routerClick = (id: any, i: any) => {
  emit("routerClick", {id: id, i: i});
}
<div class="affix-nav">
    <ul>
      <li v-for="(obj, i) in navListObj" :key="i">
        <a @click="routerClick(obj.id, i + 1)" :class="activeNavIndex === i + 1 ? 'active' : ''">
          <img :src="activeNavIndex === (i + 1) ? obj.imgActive : obj.img" alt="">
          <span>{{ (obj as any).name1 }}</span>
          <span v-if="(obj as any).name2">{{ (obj as any).name2 }}</span>
        </a>
      </li>
    </ul>
  </div>
.affix-nav {
  max-height: 60%;
  position: absolute;
  right: 5px;
  top: 0;
  bottom: 0;
  margin: auto;
  z-index: 1000;
  overflow: auto;
  background-color: #fff;
  box-shadow: -2px 2px 10px rgba(0, 0, 0, .5);
  padding: 20px 8px;
  border-radius: 5px;
  ul {
    padding-left: 0;
  }
  li a {
    text-align: center;
    display: block;
    font-size: 12px;
    margin-bottom: 10px;
    cursor: pointer;
    img {
      position: relative;
      right: 0;
      left: 0;
      margin: auto;
      padding-bottom: 5px;
    }
    span {
      color: #BBBBBB;
      line-height: 16px;
      display: block;
    }
  }
  .active span {
    color: #f00;
  }
}

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

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

相关文章

老师布置作业的技巧有哪些

布置作业可不只是简单地给学生分配任务&#xff0c;而是需要运用一些技巧&#xff0c;以达到更好的教学效果。那么&#xff0c;老师应该如何布置作业呢&#xff1f; 一、作业要有针对性 布置作业时&#xff0c;老师应该根据学生的实际情况和课程要求&#xff0c;有针对性地设…

小程序商城在易货模式中的可行性

一、引言 随着科技的快速发展和互联网的普及&#xff0c;电子商务已经深入人们的生活。小程序商城作为电子商务的一种形式&#xff0c;凭借其便捷性、高效性和广泛覆盖的优势&#xff0c;成为商业领域的新宠。本文将探讨使用小程序商城实现易货模式的可行性。 二、小程序商城的…

Grind75第9天 | 733.图像渲染、542.01矩阵、1235.规划兼职工作

733.图像渲染 题目链接&#xff1a;https://leetcode.com/problems/flood-fill 解法&#xff1a; 可以用深度优先搜索和广度优先搜索。 深度优先搜索。每次搜索到一个方格时&#xff0c;如果其与初始位置的方格颜色相同&#xff0c;就将该方格的染色&#xff0c;然后继续对…

鸿蒙NEXT来了,操作系统的寒武纪时代

鸿蒙来了&#xff0c;加上Android、iOS&#xff0c;企业又要投入人力物力财力&#xff0c;多支持一个技术阵营的一种技术平台。从IT角度看&#xff0c;是更多的责任&#xff1a;新技能培训、新员工招聘、新小组成立&#xff0c;也是新增的代码、新的bug、新的测试任务&#xff…

智能车培训——硬件篇:电源转换的硬件设计

培训课件及资料 链接&#xff1a;https://pan.baidu.com/s/1IikVfZ04Wl9UmEuizfP12A?pwd89gs 提取码&#xff1a;89gs 一.BUCK降压电路的设计 1.什么是BUCK降压&#xff1f;&#xff08;原理&#xff09; &#xff08;1&#xff09;导通回路与续流回路 电流的环路是电源通…

【H3C】配置AAA认证和Telnet远程登陆,S5130 Series交换机

AAA配置步骤为&#xff1a; 1.开启telent远程登陆服务 2.创建用户&#xff0c;设置用户名、密码、用户的服务类型 3.配置终端登录的数量 4.配置vlan-if的ip地址&#xff0c;用来远程登陆 5.允许对应的vlan通过 1.开启telent远程登陆服务 sys …

react umi/max 页签(react-activation)

思路&#xff1a;通过react-activation实现页面缓存&#xff0c;通过umi-plugin-keep-alive将react-activation注入umi框架&#xff0c;封装页签组件最后通过路由的wrappers属性引入页面。 浏览本博客之前先看一下我的博客实现的功能是否满足需求&#xff0c;实现功能&#xf…

C++I/O流——(4)格式化输入/输出(第二节)

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 含泪播种的人一定能含笑收获&#xff…

一文极速了解【自注意力机制】

当下如火如荼的大模型&#xff0c;其中的关键技术就是注意力机制&#xff08;Attention&#xff09;&#xff0c;于2015年提出。2017年的“Attention is all you need”一文提出了Transformer模型&#xff0c;去掉RNN&#xff0c;只保留注意力&#xff0c;性能吊打所有机器翻译…

用Airtest快速实现手机文件读写与删除功能

1. 前言 前几天有同学留言&#xff0c;能不能安排“读写手机文件”的示例。我们今天就来实现这个小功能。 当然&#xff0c;熟悉adb的同学&#xff0c;看到这个需求&#xff0c;肯定很开心&#xff0c;不就是一个 adb push 和 adb pull 嘛&#xff0c;非常简单呀。 确实如此&…

Python 利用pandas对数据进行特定排序

背景 小编最近在处理hive表存储大小时&#xff0c;需要对每个表的大小进行排序&#xff0c;因通过 hadoop fs -du -s -h /path/table 命令获取的数据表大小&#xff0c;其结果是展示为人能直观理解的大小&#xff0c;例如 1.1T、1.9G、49.6M 等&#xff0c;如果想对这些表根据…

如何安装配置VisualSVN服务并实现公网访问本地服务【内网穿透】

文章目录 前言1. VisualSVN安装与配置2. VisualSVN Server管理界面配置3. 安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3.4 创建公网地址 4. 固定公网地址访问 前言 SVN 是 subversion 的缩写&#xff0c;是一个开放源代码的版本控制系统…

2018年认证杯SPSSPRO杯数学建模A题(第一阶段)海豚与沙丁鱼全过程文档及程序

2018年认证杯SPSSPRO杯数学建模 探究海豚猎捕时沙丁鱼群的躲避运动模型 A题 海豚与沙丁鱼 原题再现&#xff1a; 沙丁鱼以聚成大群的方式来对抗海豚的捕食。由于水下光线很暗&#xff0c;所以在距离较远时&#xff0c;海豚只能使用回声定位方法来判断鱼群的整体位置&#xf…

网页版短信系统功能简介|短信平台开发搭建源码

网页版短信系统功能简介|短信平台开发搭建源码 随着互联网的发展&#xff0c;科技的进步和人们对通讯方式的需求不断增加&#xff0c;短信成为了人们日常生活中必不可少的沟通工具之一。而网页版短信系统的出现&#xff0c;为人们提供了更加便捷和灵活的短信发送和接收方式。 网…

Ant Design Vue上传多个图片

模板代码&#xff1a; 定义变量&#xff1a; 文件限制的函数&#xff1a; 上传的函数&#xff1a; 样式函数&#xff1a; 完整代码&#xff1a; <template><div class"dialog-upload" v-if"showUploadDialog"><div class"dialog-uplo…

MySQL 基于创建时间进行RANGE分区

MySQL是一款广泛使用的关系型数据库。在MySQL中&#xff0c;大量数据场景提高查询效率是非常关键的&#xff0c;所以&#xff0c;对数据表进行分区是一个很好的选择。 在创建分区表之前&#xff0c;需要了解一下MySQL分区的基本概念。MySQL分区可以将一个大表分成多个小表&…

学习JavaEE的日子 day14 继承,super(),this(),重写

Day14 1.继承的使用 理解&#xff1a;子类继承父类所有的属性和方法 使用场景&#xff1a;多个类似的类&#xff0c;有相同的属性和方法&#xff0c;就可以把相同属性和方法抽取到父类 优点&#xff1a;减少代码的冗余&#xff1b; 使类与类之间产生了关系(多态的前提) 缺点&a…

前端实现轮训和长连接

简介 轮训和长连接相关内容可以参考之前的文章消息推送系统。消息推送系统-CSDN博客文章浏览阅读106次。在餐饮行业中&#xff0c;店内应用有pos、厨显屏等&#xff0c;云端应用为对应数据中心。为了实现云端数据和操作指令下发到店内应用&#xff0c;需要有一个系统实现这个功…

群晖nas内网穿透

目录 一、前言 二、操作步骤 &#xff08;一&#xff09;查看群晖是否有ipv6地址 &#xff08;二&#xff09;下载安装docker &#xff08;三&#xff09;docker里面安装ddns-go &#xff08;四&#xff09;阿里云官网购买域名 &#xff08;五&#xff09;域名解析 阿里…

Yolov8_使用自定义数据集训练模型1

前面几篇文章介绍了如何搭建Yolov8环境、使用默认的模型训练和推理图片及视频的效果、并使用GPU版本的torch加速推理、导出.engine格式的模型进一步利用GPU加速&#xff0c;本篇介绍如何自定义数据集&#xff0c;这样就可以训练出识别特定物体的模型。 《Yolov8_使用自定义数据…