vue3写nav滚动事件中悬停在顶部

1. 防抖类Animate, 使用requestAnimationFrame代替setTimeout

也可以使用节流函数, lodash有现成的防抖和节流方法

_.debounce防抖

_.throttle节流

export default class Animate {constructor() {this.timer = null;}start = (fn) => {if (!fn) {throw new Error('需要执行函数');}if (this.timer) {this.stop();}this.timer = requestAnimationFrame(fn);};stop = () => {if (!this.timer) {return;}cancelAnimationFrame(this.timer);this.timer = null;};
}

2. 使用animate封装滚动方法

const animate = new Animate();

throttleScroll = e => animate.start(() => handleScroll(e));

3. 着手写滚动函数handleScroll

//滚动的函数
function handleScroll(e) {
  const scrollingElement = e.target.scrollingElement;
  const headerOffsetTop = header1.value.offsetTop; //header的高度
  const headerOffsetHeight = header1.value.offsetHeight;
  const scrollTop = scrollingElement.scrollTop;

  // 如果滚动元素的scrollTop比header元素的高度+offsetTop还大, 就让nav部分悬停在顶部!!!
  if (scrollTop >= headerOffsetHeight + headerOffsetTop) {
    isFixed.value = true;
  } else {
    isFixed.value = false;
  }
}

nav的定位何时设置为fixed的原理:

当滚动后, header元素因为向上滚动,或者向下滚动而消失不见时, 就让nav悬停在顶部, 反之就让nav元素正常显示在header元素下面

实践可知:

1) 滚动元素的scrollTop === header元素的offsetTop + header元素的offsetHeight时, header元素开始消失在视野;

2) scrollTop > header元素的offsetTop + header元素的offsetHeight时, header元素继续消失在视野;

3) 反之header就是可见到它的一部分就是它的全部都在视野范围中

4. 在onMounted钩子监听scroll事件(因为dom已经渲染完成)

onMounted(() => {
  //写在掉接口的里面的
  nextTick(() => {
    window.addEventListener('scroll', throttleScroll, false);
  });
  // 这里使用监听的scroll的事件,使用了防抖函数封装;
  throttleScroll = e => animate.start(() => handleScroll(e));
});

5. 组件将要销毁或者将要离开此组件时解除scroll事件绑定

onBeforeUnmount(() => { // 页面即将销毁取消事件监听(相当于vue2的beforeDestroy)
  //离开页面需要remove这个监听器,不然还是卡到爆。
  window.removeEventListener('scroll', throttleScroll);
});

<template><div class="fixed-top-container"><header class="header" :ref="header1">头部</header><nav class="fixed-top-nav" :ref="nav1" :class="{ isFixed }"><div class="box" v-for="(item, index) in navData" :key="index">{{ item.title }}</div></nav><ul class="fixed-top-list"><li class="list-item" v-for="(item, index) in listData" :key="index">{{ item }}</li></ul></div>
</template>
<script lang="ts" setup>
import { ref, reactive, onMounted, onBeforeUnmount, onDeactivated, nextTick, Ref } from 'vue'
import _ from 'lodash';
import Animate from '../../utils/animate'const navData = reactive([{ title: 'nav1', id: 1 },{ title: 'nav2', id: 2 },{ title: 'nav3', id: 3 },{ title: 'nav4', id: 4 },
]);const listData = reactive(Array.from({ length: 50 }, (_, i) => i + 1));const isFixed = ref(false); //是否固定的
let throttleScroll: any = null; //定义一个截流函数的变量
const header1 = ref('header1') as Ref;
const nav1 = ref('nav1') as Ref;
const animate = new Animate()//滚动的函数
function handleScroll(e) {const scrollingElement = e.target.scrollingElement;const headerOffsetTop = header1.value.offsetTop; //header的高度const headerOffsetHeight = header1.value.offsetHeight;const scrollTop = scrollingElement.scrollTop;// 如果滚动元素的scrollTop比header元素的高度+offsetTop还大, 就让nav部分悬停在顶部!!!if (scrollTop >= headerOffsetHeight + headerOffsetTop) {isFixed.value = true;} else {isFixed.value = false;}
}onMounted(() => {//写在掉接口的里面的nextTick(() => {window.addEventListener('scroll', throttleScroll, false);});// 这里使用监听的scroll的事件,使用了防抖函数封装;throttleScroll = e => animate.start(() => handleScroll(e));
});onBeforeUnmount(() => { // 页面即将销毁取消事件监听//离开页面需要remove这个监听器,不然还是卡到爆。window.removeEventListener('scroll', throttleScroll);
});
</script>
<style scoped lang="scss">
* {margin: 0;padding: 0;
}
.fixed-top-container {height: 100vh;& .header {height: 200px;width: 100%;background-color: #f40;}& .fixed-top-nav {display: flex;width: 100%;background-color: #f90;&.isFixed {position: fixed;left: 0;top: 0;z-index: 999;}& .box {font-size: 14px;height: 30px;line-height: 30px;color: #333;flex: 1 1 0%;}}& .fixed-top-list {list-style: none;& .list-item {width: 100%;height: 40px;line-height: 40px;font-size: 16px;border-bottom: 1px solid #333;background-color: #fff;}}
}
</style>

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

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

相关文章

pmp到底有多难考?

单说通过&#xff0c;难度不算特别高&#xff0c;但也有几点难度&#xff1a; 1、试卷难度&#xff1a;是笔试&#xff0c;180道题&#xff0c;题量大&#xff0c;比较机试耗时间&#xff1b; 2、题目难度&#xff1a;题目是中英文对照&#xff0c;可能有翻译不到位的地方&am…

0基础学习PyFlink——事件时间和运行时间的窗口

大纲 定制策略运行策略Reduce完整代码滑动窗口案例参考资料 在 《0基础学习PyFlink——时间滚动窗口(Tumbling Time Windows)》一文中&#xff0c;我们使用的是运行时间(Tumbling ProcessingTimeWindows)作为窗口的参考时间&#xff1a; reducedkeyed.window(TumblingProcess…

第4章_运算符

文章目录 1. 算术运算符1.1 加法与减法运算符1.2 乘法与除法运算符1.3 求模运算符 2. 比较运算符2.1 等号运算符2.2 安全等于运算符2.3 不等于运算符2.4 空运算符2.5 非空运算符2.6 最小值运算符2.7 最大值运算符2.8 BETWEEN AND运算符2.9 IN运算符2.10 NOT IN运算符2.11 LIKE运…

代码随想录算法训练营第三十九天丨 动态规划part02

62.不同路径 思路 动态规划 机器人从(0 , 0) 位置出发&#xff0c;到(m - 1, n - 1)终点。 按照动规五部曲来分析&#xff1a; 确定dp数组&#xff08;dp table&#xff09;以及下标的含义 dp[i][j] &#xff1a;表示从&#xff08;0 &#xff0c;0&#xff09;出发&#…

利用win32的GetLastInputInfo函数实现锁屏(C#)

前两天看到群里面讨论这个问题&#xff0c;刚好我们上一家公司的系统也有这个功能&#xff0c;就研究了一下&#xff0c;我们这边实现这个功能的目的如下&#xff1a;当用户长时间不操作系统时&#xff0c;自动退出系统并退回到登录界面&#xff0c;想要使用系统&#xff0c;就…

【数据结构】数组和字符串(十三):链式字符串的基本操作(串长统计、查找、复制、插入、删除、串拼接)

文章目录 4.3 字符串4.3.1 字符串的定义与存储4.3.2 字符串的基本操作&#xff08;链式存储&#xff09;1. 结构体2. 初始化3. 判空4. 串尾添加5. 打印6. 串长统计7. 查找8. 复制9. 插入10. 删除11. 串拼接12. 销毁13. 主函数14. 代码整合 4.3 字符串 字符串(String)是由零个或…

Latex排版SIGGRAPH总结(持续总结中...)

本文学习总结自&#xff1a;How to use the ACM SIGGRAPH / TOG LaTeX template 相关文件&#xff1a;百度网盘 首先解压 “my paper” 中的文件&#xff0c;并用Latex打开mypaper.tex. 多行连等公式 \begin{equation}表示编号公式&#xff0c;\[ \]表示无编号公式 无编号\b…

双轮差速模型机器人通过线速度、角速度计算机器人位姿

已知上一时刻机器人位置P_OLD (x,y,),机器人当前时刻的线速度和角速度&#xff08;v,&#xff09;,短时间内t内&#xff0c;机器人在线性部分和非线性部分的增量为 线性部分&#xff1a; 非线性部分&#xff1a; 由于可能非常小&#xff0c;导致非线性部分数值不稳定&#xf…

【R统计】各式各样的插补法解决数据缺失的问题!

&#x1f482; 个人信息&#xff1a;酷在前行&#x1f44d; 版权: 博文由【酷在前行】原创、需要转载请联系博主&#x1f440; 如果博文对您有帮助&#xff0c;欢迎点赞、关注、收藏 订阅专栏&#x1f516; 本文收录于【R统计】&#xff0c;该专栏主要介绍R语言实现统计分析的…

【计算机视觉】对极几何

文章目录 一、极线约束&#xff08;Epipolar Constraint&#xff09;二、相机标定过的情况三、相机没有标定过的情况四、八点算法&#xff08;eight-point algorithm&#xff09; 我的《计算机视觉》系列参考UC Berkeley的CS180课程&#xff0c;PPT可以在课程主页看到。 在上一…

关于preempt count的疑问

Linux中的preempt_count - 知乎 https://www.cnblogs.com/hellokitty2/p/15652312.html LWN&#xff1a;关于preempt_count()的四个小讨论&#xff01;-CSDN博客 主要是参考这些文章 之前一直认为只要是in_interrupt()返回非0值&#xff0c;那么就可以认为当前在中断上下文。即…

阿昌教你如何优雅的数据脱敏

阿昌教你如何优雅的数据脱敏 Hi&#xff0c;我是阿昌&#xff0c;最近有一个数据脱敏的需求&#xff0c;要求用户可自定义配置数据权限&#xff0c;并对某种类型数据进行脱敏返回给前端 一、涉及知识点 SpringMVCJava反射Java自定义注解Java枚举 二、方案选择 1、需求要求…

Webpack打包图片-js-vue

文章目录 一、Webpack打包图片1.加载图片资源的准备2.认识asset module type3.asset module type的使用4.url-loader的limit效果 二、babel1.为什么需要babel2.babel命令行的使用3.babel插件的使用4.babel的预设preset5.babel-loader6.babel-preset 三、加载Vue文件1.编写App.v…

使用Ansible中的playbook

目录 1.Playbook的功能 2.YAML 3.YAML列表 4.YAML的字典 5.playbook执行命令 6.playbook的核心组件 7.vim 设定技巧 示例 1.Playbook的功能 playbook 是由一个或多个play组成的列表 Playboot 文件使用YAML来写的 2.YAML #简介# 是一种表达资料序列的格式,类似XML #特…

开关电源测试过压保护的测试标准及其方法

过压保护的原理 过压保护是电压超过预定值时降低电压的一种方式&#xff0c;原理是通过电路中的电压检测电路来检测电路中的电压是否超过了设定的阈值&#xff0c;如果超过了阈值&#xff0c;就会触发过压保护器件&#xff0c;使电源断开或使受控设备电压降低&#xff0c;保护电…

网络协议--TCP的交互数据流

19.1 引言 前一章我们介绍了TCP连接的建立与释放&#xff0c;现在来介绍使用TCP进行数据传输的有关问题。 一些有关TCP通信量的研究如[Caceres et al. 1991]发现&#xff0c;如果按照分组数量计算&#xff0c;约有一半的TCP报文段包含成块数据&#xff08;如FTP、电子邮件和U…

使用Fiddler进行Mock测试

1、接口抓包 找到要mock的接口&#xff0c;打开fiddler抓包 以某某接口为例&#xff0c;找到下面的接口 http://XXX/SYSTEMS 2、复制该接口数据到本地 在接口上进行右键点击&#xff0c;选择save -> …and Open as Local File -> 默认会保存至桌面&#xff0c;示例中的数…

uniapp的启动页、开屏广告

uniapp的启动页、开屏广告 启动页配置广告开屏 启动页配置 在manifest.json文件中找到APP启动界面配置&#xff0c;可以看到有Android和iOS的启动页面的配置 &#xff0c;选择自定义启动图即可配置 广告开屏 在pages中新建一个广告开屏文件并在pases.json的最顶部配置这个页…

开发商城系统的一些小建议

电子商务的迅猛发展&#xff0c;商城系统已经成为了企业推广产品和服务、吸引更多消费者的重要工具。然而&#xff0c;要想在竞争激烈的市场中脱颖而出&#xff0c;提升用户体验成为了至关重要的一环。下面就商城系统的开发作一些简单分享&#xff0c;以帮助企业更好地满足用户…

跨国文件传输为什么要用专业的大文件传输软件?

跨国文件传输是许多跨国企业需要的基础工作&#xff0c;对于传输的质量和速度要求也是很严格的&#xff0c;随着数据量的不断增加&#xff0c;寻常传统的传输方式肯定是不行&#xff0c;需要新的技术和方式来进行传输&#xff0c;大文件传输软件应运而出&#xff0c;那它有什么…