超超超超详细!手把手带你用js实现简易版position:sticky

news/2024/7/19 15:52:38 标签: css, js

文章目录

  • 一、基本思路
  • 二、实现过程
    • 1.准备工作
    • 1.获取dom元素,设置偏移量
    • 2.给滑动添加事件
    • 3.判断是否在可视区
    • 4.脱离可视区触发回调函数
  • 总结


# 前言

前面我们在介绍position属性时(不知道的小伙伴可以去看看我的另一篇说position的博客哟,传送门:手把手带你体验position各种属性)有了解到,sticky的兼容性是很差的,那么我们想达到类似的效果该怎么办呢?

废话不多说,开撕

一、基本思路

sticky就是元素处于页面某个布局,当元素超出可视区时,根据设置进行定位。

官方介绍:它的行为就像 position:relative; 而当页面滚动超出目标区域时,它的表现就像 position:fixed;,它会固定在目标位置。

思路:

  1. 当元素处于原本位置时,设置position为relative
  2. 监听元素位置,当元素滑动到距离视口 0px 时再继续滑动,position替换为fixed
  3. 给滑动添加监听事件,监听元素是否在可视区
  4. 如果一直滑动会一直触发事件,给浏览器造成负荷,我们使用节流优化。

思路到位,开撕!

二、实现过程

1.准备工作

在实现前我们先分析一下,我们可以先建立一个函数,入参为需要监听的dom元素和对象,对象里面放置left等偏移量。

const sticky = (dom,obj) => {
      
    }

带我们带着问题去准备手撕:

  1. 获取dom元素,在对象设置偏移量
  2. 给滑动添加事件
  3. 监听元素位置,判断是否在可视区
  4. 脱离可视区position改为fixed,读取对象里的偏移量
  5. 滚动回之前区域时,元素回到原始位置

1.获取dom元素,设置偏移量

	const father = document.querySelector('.father')
    const obj = {
      top:0,
    }

2.给滑动添加事件

	window.addEventListener('scroll',() => {
        // 里面存放判断是否在可视区的代码及判断
      })

3.判断是否在可视区

const sticky = (dom,obj) => {
      window.addEventListener('scroll',() => {
        const rect = dom.getBoundingClientRect()
        console.log(rect);
      })
    }

我们使用getBoundingClientRect()来获取传入dom元素位置等参数,我们来看看得到了哪些数据:
在这里插入图片描述
可以看出在这个对象里可以拿到我们想要的参数,比如top就代表元素和浏览器窗口顶部距离,height是元素的高度。根据这个我们可以知道,当top <= 0时,元素开始脱离可视区。

4.脱离可视区触发回调函数

const sticky = (dom, obj) => {
        window.addEventListener("scroll", () => {
          const rect = dom.getBoundingClientRect();
          if (rect.top <= 0) {
            if ("top" in obj) {
              dom.style.position = "fixed";
              dom.style.top = `${obj.top}px`;
              dom.style.left = `${rect.left}px`;
            }else if (rect.top > 0) {
            dom.style.position = "relative";
            dom.style.top = `0px`;
            dom.style.left = `0px`;
          }
          } 
        });
      };

效果图:在这里插入图片描述
可以看到我们已经达到想要的效果啦。在超出可视区时吸顶,回去时变回之前。

由于监听了滚动事件,所以事件将会被大频率触发,加大了浏览器符合,所以我们可以用节流函数来优化,我的另一篇文章有详细介绍节流函数和代码,传送门:防抖节流详解

总结

其实这次只是实现了一个简单的吸顶效果,我看了源码,发现原生的是能多方向同时吸附的,由于技术问题,暂时还做不到这一步,如果大家感兴趣的话,可以去看一下源码自己实现一个啦!


http://www.niftyadmin.cn/n/861678.html

相关文章

一路摸爬滚打,我终于踏上了我的程序员之路!

我正在参与CSDN《新程序员》有奖征文活动&#xff0c;活动链接&#xff1a; https://marketing.csdn.net/p/52c37904f6e1b69dc392234fff425442 文章目录前言浑浑噩噩开学季自信心被重击虚度光阴初识编程你好&#xff0c;前端我的第一个轮播图期末课设前端是没有前途的开始前端之…

$set解决vue中修改数组或对象视图不更新的问题

文章目录前言一、案例二、解决方法$set总结前言 相信大家和我一样&#xff0c;在开发中总是遇到一个问题。 为啥我修改v-for遍历的数组&#xff0c;视图却没有更新&#xff1f;&#xff1f;&#xff1f;当我点击其他操作重新渲染后&#xff0c;又更新了&#xff1f;&#xff…

MongoDB入门学习

文章目录前言一、MongoDB是什么&#xff1f;二、MongoDB的基本操作1.基本指令2.插入文档3.查询文档4.修改文档5.删除文档6.简单操作总结前言 虽说现在关系型数据库还是主流&#xff0c;但是面对某些需求的时候&#xff0c;需要非关系型数据库来补充它&#xff0c;学习一个主流…

使用mongoose在express中操作数据库

文章目录前言一、Mongoose是什么&#xff1f;二、使用步骤1.引入库2.连接数据库3.操作数据库操作前的准备工作增加文档查询文档更新文档删除文档3.将增删查改操作写成接口总结前言 前面我们已经学会怎么去在命令行里操作数据库了&#xff0c;但是我们肯定不能让用户去操作命令…

浅谈xss和csrf攻击

文章目录前言一、XSS是什么&#xff1f;存储型(持久型)反射型(非持久型)dom型二、CSRF是什么&#xff1f;总结前言 由于博主目前在一家主做网络安全的公司实习&#xff0c;之前没有意识到网络安全的严重性&#xff0c;现在才感受到我们的系统存在了这么多问题&#xff0c;很容…

【ES6】浅谈Vue3为什么使用Proxy取代defineProperty

文章目录前言一、Proxy是什么&#xff1f;get()set()二、Vue双向绑定实现原理三、Vue3为什么使用ProxydefineProperty缺陷Proxy的好处总结前言 友友们大家好&#xff0c;vue3推出后大家有没有去看呢&#xff1f;博主是个性子急的人&#xff0c;哪能禁得住这诱惑。 经过博主粗…

【ES6】浅谈Generator和yield

文章目录前言一、async await实现二、Generator实现三、Generator函数1、什么是Generator2.Generator的特点3.Generator的执行四、yield表达式1、什么是yield2、yield注意点五、Iterator对象五、next方法的参数总结前言 问题发生在一个下午&#xff0c;当我正在实现Promise.al…

常见css居中问题

文章目录前言一、水平居中已知宽度未知宽度二、垂直居中已知高度未知高度三、垂直水平居中总结前言 居中是我们项目开发中最常用到样式&#xff0c;可以说&#xff0c;作为一名合格的前端&#xff0c;各种情况下的居中应该是得心应手的&#xff0c;接下来让我们看看有哪些方式…