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

news2024/11/29 22:45:12

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.coloradmin.cn/o/1159704.html

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

相关文章

力扣:147. 对链表进行插入排序(Python3)

题目&#xff1a; 给定单个链表的头 head &#xff0c;使用 插入排序 对链表进行排序&#xff0c;并返回 排序后链表的头 。 插入排序 算法的步骤: 插入排序是迭代的&#xff0c;每次只移动一个元素&#xff0c;直到所有元素可以形成一个有序的输出列表。每次迭代中&#xff0c…

解决在Win7下运行一些老游戏花屏或色彩异常问题的方法

有一些喜欢回顾经典老游戏的玩家们&#xff0c;在目前最新的windows7的操作系统下&#xff0c;运行某些游戏会出现花屏&#xff0c;问题的原因是因为win7对这些游戏的DirectDraw不兼容&#xff0c;一种方法是改游戏配置文件&#xff0c;把游戏色彩8bit改成16bit&#xff0c;当然…

安装pytorch报错torch.cuda.is_available()=false的解决方法

参考文章&#xff1a; https://blog.csdn.net/qq_46126258/article/details/112708781 https://blog.csdn.net/Andy_Luke/article/details/122503884 https://blog.csdn.net/anmin8888/article/details/127910084 https://blog.csdn.net/zcs2632008/article/details/127025294 …

为什么Facebook运营需使用IP代理?有哪些美国IP代理好用?

随着互联网的快速发展和全球用户规模的不断增长&#xff0c;Facebook已成为了全球最大的社交媒体平台之一。然而&#xff0c;大批量地运营Facebook账号往往需要借助IP代理这一工具&#xff0c;提高账号的安全性和可靠性&#xff0c;使得运营Facebook更加流畅。那么Facebook为什…

嵌入式到底如何理解呢?

今日话题&#xff0c;嵌入式到底如何理解呢&#xff1f;以我个人的理解&#xff0c;可以用一个客观的比喻来描述&#xff0c;就是将某个系统嵌入到特定的环境中&#xff0c;以实现特定的功能。这个过程包括将现实世界中的人、物的意图和逻辑关系&#xff0c;通过计算和运算的方…

【计算机网络】同源策略及跨域问题

1. 同源策略 同源策略是一套浏览器安全机制&#xff0c;当一个源的文档和脚本&#xff0c;与另一个源的资源进行通信时&#xff0c;同源策略就会对这个通信做出不同程度的限制。 同源策略对 同源资源 放行&#xff0c;对 异源资源 限制。因此限制造成的开发问题&#xff0c;称…

【Acwing170】加成序列(dfs+迭代加深+剪枝)题解和一点感想

本思路来自acwing算法提高课 题目描述 看本文需要准备的知识 1.dfs算法基本思想 2.对剪枝这个词有个简单的认识 迭代加深思想和此题分析 首先&#xff0c;什么是迭代加深呢&#xff1f;当一个问题的解有很大概率出现在递归树很浅的层&#xff0c;但是这个问题的解本身存在…

树结构及其算法-用数组来实现二叉树

目录 树结构及其算法-用数组来实现二叉树 C代码 树结构及其算法-用数组来实现二叉树 使用有序的一维数组来表示二叉树&#xff0c;首先可将此二叉树假想成一棵满二叉树&#xff0c;而且第层具有个节点&#xff0c;按序存放在一维数组中。首先来看看使用一维数组建立二叉树的…

Java使用pdfbox进行pdf和图片之间的转换

简介 pdfbox是Apache开源的一个项目,支持pdf文档操作功能。 官网地址: Apache PDFBox | A Java PDF Library 支持的功能如下图.引入依赖 <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox-app</artifactId><version>…

这样发布成绩,轻松没烦恼

老师们&#xff0c;你知道怎样公正、便捷发布学生成绩吗&#xff1f;今天我来教给大家一个超级实用的方法&#xff0c;成绩发布简单又轻松&#xff01; 成绩查询系统主要是学校和教师使用。能够实现学生成绩的录入、查询、发布和导出等功能&#xff0c;让老师告别传统操作&…

深入理解元素的高度、行高、行盒和vertical-align

1.块级元素的高度 当没有设置高度时&#xff0c;高度由内容撑开&#xff0c;实际上是由行高撑开&#xff0c;当有多行时&#xff0c;高度为每行的行高高度之和。 行高为什么存在&#xff1f; 因为每行都由一个行盒包裹&#xff0c;行高实际上是行盒的高度。 2.什么是行盒&am…

模糊C均值聚类(FCM)python

目录 一、模糊C均值聚类的原理 二、不使用skfuzzy的python代码 三、 使用skfuzzy的python代码 一、模糊C均值聚类的原理 二、不使用skfuzzy的python代码 import numpy as np import random import matplotlib.pyplot as plt plt.rcParams[font.sans-serif][SimHei] plt.r…

记录 vue + vuetify + electron 安装过程

NodeJs 版本&#xff1a; 20 内容来自&#xff1a; Electron Vue.js Vuetify 构建跨平台应用_思月行云的博客-CSDN博客文章浏览阅读61次。Go coding!https://blog.csdn.net/kenkao/article/details/132600542 npm config set registry https://registry.npm.taobao.org np…

Physics2DPlugin3加载后会跳转gsap官网解决

因工作需要使用Physics2DPlugin3库&#xff0c;目标效果 加载他里面的在线js&#xff0c;使用效果正常&#xff0c;但是几秒会跳转官网&#xff0c;我们app内部、浏览器都会这样。 于是研究js代码&#xff0c;发现里面有setTimeout跳转。 删掉就好了 分享我改好的文件&#x…

uniapp原生插件之安卓获取设备唯一标识

插件介绍 安卓获取设备唯一标识&#xff0c;集成了获取imei&#xff0c;获取安卓ID&#xff0c;获取GUID&#xff0c;获取获取OAID/AAID等 插件地址 安卓获取设备唯一标识 - DCloud 插件市场 超级福利 uniapp 插件购买超级福利 详细使用文档 uniapp 安卓获取设备唯一标…

Unity 粒子特效-第五集-烟雾缭绕合并特效

一、特效预览 二、制作原理 1.素材介绍 我们之前几章做了有光球&#xff0c;星星&#xff0c;烟雾 我们把他们结合起来&#xff0c;做一些调整 2.合并方法 我们还是建一个粒子游戏物体 我们把所有的效果取消 再重置一下transform 现在这个物体就是一个可以控制粒子特效的空…

BUUCTF webshell后门 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 朋友的网站被黑客上传了webshell后门&#xff0c;他把网站打包备份了&#xff0c;你能帮忙找到黑客的webshell在哪吗&#xff1f;(Webshell中的密码(md5)即为答案) 密文&#xff1a; 下载附件&#xff0c;解压得到一…

Test-Agent----基于Centos7系统部署Test-Agent

【Test-Agent----基于Centos7系统部署Test-Agent】 一、部署 Test-Agent 1.1 环境准备 环境基本信息&#xff1a;Centos7.9操作系统&#xff0c;16核64G1T硬盘&#xff0c;Python3.9.7 1.2 部署 Test-Agent &#xff08;1&#xff09;安装git-lfs cd /opt curl -s https:…

git生成gitee和github两个不同的公钥

配置多个公钥 Windows 用户建议使用 Windows PowerShell 或者 Git Bash&#xff0c;在 命令提示符 下无 cat 和 ls 命令。 1、生成公钥文件&#xff1a; 通过命令 ssh-keygen 生成 SSH Key&#xff1a; ssh-keygen -t rsa -C "Gitee SSH Key" -f ~/.ssh/gitee_be…

端到端Scrum敏捷管理流程-

Leangoo领歌是一款永久免费的专业的敏捷开发管理工具&#xff0c;提供端到端敏捷研发管理解决方案&#xff0c;涵盖敏捷需求管理、任务协同、进展跟踪、统计度量等。 Leangoo领歌上手快、实施成本低&#xff0c;可帮助企业快速落地敏捷&#xff0c;提质增效、缩短周期、加速创新…