vue平滑滚动的自定义指令以及脚本中获取scss变量的值

该代码参考抖音渡一前端必修课的视频

效果图

在这里插入图片描述

页面使用

模板代码

<div v-slide>这是一个方块自行添加样式</div>

模板脚本

import slide from "./directives/slide";
const vSlide = {
  mounted: (el) => {
    slide.mounted(el);
  },
  unmounted: (el) => {
  	slide.unmounted(el);
  },
};

slide代码

import { getCssVariable } from "@qhy/common";

// 定义元素滑入动画的距离和持续时间
const DISTANCE: number = 40;
const DURATION: number = 1400;
// 页脚高度
const footerHeight = parseFloat(getCssVariable(`--app-footer-height`));
let isScrollBottom= false; //页面是否向下滚动
let listenersAdded = false; //是否添加过监听
let oldScrollTop = 0

const animations = new WeakMap();
// 创建一个IntersectionObserver实例,用于检测元素是否进入视图区域
const observer = new IntersectionObserver((entries) => {
  // 当元素进入视图区域时,获取存储的动画对象并播放动画,然后停止观察该元素
  for (const entry of entries) {
    // 判断是否出现在视口中
    const animation = animations.get(entry.target);
    if (animation && isScrollBottom) {
      animation.play();
      // observer.unobserve(entry.target); // 取消元素观察
    }
  }
});

// 判断元素是否在视图区域下方
const isBelowViewport = (el: HTMLElement) => {
  const rect = el.getBoundingClientRect();
  return rect.top - window.innerHeight + footerHeight > 0;
};

const scrollYFun = (e) => {
  const scrollTop = e.target.scrollTop;
  const scrollStep = scrollTop - oldScrollTop;
  oldScrollTop = scrollTop;
  isScrollBottom = scrollStep > 0;
};

// 定义滑入动画的类
const slide = {
  // 在元素挂载时应用动画
  mounted(el: HTMLElement) {
    console.log("mounted");
    if (!listenersAdded) {
      window.addEventListener("scroll", scrollYFun, true);
      listenersAdded = true;
    }
    // 如果元素不在视图区域下方,则无需应用动画
    if (!isBelowViewport(el)) {
      return;
    }
    // 创建并设置动画,然后将动画对象存储在WeakMap中,并开始观察元素
    const animation = el.animate(
      [
        {
          transform: `translateY(${DISTANCE}px)`,
          opacity: 0.5,
        },
        {
          transform: "translateY(0)",
          opacity: 1,
        },
      ],
      {
        duration: DURATION,
        easing: "ease",
        fill: "forwards",
      }
    );
    animation.pause();
    animations.set(el, animation);
    observer.observe(el);
  },
  // 在元素卸载时停止观察
  unmounted(el: any) {
    observer.unobserve(el);
    animations.delete(el); // 清除动画记录
    if (listenersAdded) {
      window.removeEventListener("scroll", scrollYFun, true);
    }
  },
};
export default slide;


脚本获取scss变量的值

我这里的getCssVariable 方法是封装好的获取变量值的

const getCssVariable = (variableName: string): string => {
  return getComputedStyle(document.documentElement)
    .getPropertyValue(variableName)
    .trim();
};
console.log(getCssVariable('--变量名'))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值