position的粘性定位

功能需求:

最近在做报表功能,筛选条件自动吸顶,并且表格表头也要自动吸顶

思路:

首先想到的就是vue的自定义指令(原谅我css学的不好,第一时间没想到position的 sticky属性),既然想到使用自定义指令,那就想想需要实现的思路,实际很简单:

  1. 主要是获取当前需要吸顶的dom节点,这个vuv的自定义指令会提供对应的参数,如果不明太,可以去看下vue的自定义指令官方文档,很详细。
  2. 根据滚动的距离判断是否移动到当前需要吸顶的节点,如果已经滚动到当前节点,则给它增加样式:绝对定位元素,至于是相对于屏幕视口(viewport)的位置来指定元素位置,还是使用absolute通过指定元素相对于最近的非 static 定位祖先元素的偏移,来确定元素位置,这个取决于项目的实际需求
  3. 如果已经滚动到当前节点之外,则需要还原样式,移除定位

实现:

import type { Directive, App } from 'vue';

const stickyDirective: Directive = {
  mounted(el, binding) {
    const scrollParent = binding.value.scrollParent
      ? document.querySelector(binding.value.scrollParent)
      : document.body;
    el.parent = scrollParent;
    const parent = document.querySelector(binding.value.parent);
    el.scrollParent = scrollParent;
    el.parent = parent;
    const elHeight = el.getBoundingClientRect().height;
    const elWidth = el.getBoundingClientRect().width;
    el.height = elHeight;
    el.width = elWidth;
  },
  updated(el, binding) {
    const elTop = el.getBoundingClientRect().top;
    // on函数,是封装的监听事件,根据自己的需求适当修改即可
    on(el.scrollParent, 'scroll', (): void => {
      const scrollTop = el.scrollParent.pageYOffset || el.scrollParent.scrollTop;
      if (scrollTop > elTop - (binding.value.top || 0)) {
        el.style.position = 'fixed';
        el.style.zIndex = '9';
        el.style.top = (binding.value.top || 0) + 'px';
        el.style.width = el.width + 'px';
        el.style.boxShadow =
          '0px 9px 28px 8px rgba(0,0,0,0.05), 0px 6px 16px 0px rgba(0,0,0,0.08), 0px 3px 6px -4px rgba(0,0,0,0.12)';
        // 因为当前节点脱离文档流,导致吸顶的瞬间,节点之后的内筒瞬间向上移动当前节点高度,有一种跳跃感
        // 所以在此设置此节点父级paddingtop
        el.parent.style.paddingTop = el.height + 'px';
      } else {
        el.style.position = 'static';
        el.style.boxShadow = 'none';
        el.parent.style.paddingTop = 0;
      }
    });
  },

到此基本就实现了一个简单的节点吸顶的功能了。

现在着手实现表格表头的吸顶功能,在这里说下,我的项目中使用的是vben,一个基于antd vue的开箱即用的项目,本质上还是antd vue。

至于表格表头吸顶项目,肯定第一时间去看antd的官方文档Table,看到了这个sticky属性(这时才想起来position的这个属性)。

 可以去看下antd vue Table的源码,并不复杂,实际上就是通过position:sticky实现表头的吸顶。

既然知道怎么使用了,直接用在Table的组件上就好,满心欣喜的把sticky属性用上了,结果并没有起作用,第一时间有些懵逼,难道是vben里antd的版本过低,属性不存在,就去看了代码,发现antd版本是3.*是支持sticky属性的,看到这就更懵逼了,明明支持的属性却无法实现需要的功能,那就只能研究下position:sticky这个css属性了,毕竟归根结底是通过它实现的功能。

然后就在mdn,看到了这句话:

这两句话什么意思,就是需要吸顶的节点的父级,包含其祖先直到根节点,不能使用 overflow的hiddenscrollauto, 或 overlay这四个属性,如果使用,sticky将失效。

以上就是项目中遇到的一些问题,在这做一个记录,不喜勿喷。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值