元素平滑上升

给元素设置v-slide-in设置平滑上升,引入vSlideIn使用

scss 复制代码
// vSlideIn.js
const DISTANCE = 150;
const DURATION = 1000;
const animationMap = new WeakMap()
const ob = new IntersectionObserver(entries => {
    for (const entry of entries) {
        if (entry.isIntersecting) {
            console.log(entry);
            const animation = animationMap.get(entry.target);
            animation.play();
            ob.unobserve(entry.target);
        }
    }
})
function isBelowViewport(el) {
    const rect = el.getBoundingClientRect()
    return rect.top > window.innerHeight;
}
export default {
    mounted(el) {
        if (!isBelowViewport(el)) {
            return;
        }
        const animation = el.animate([
            {
                transform: `translateY(${DISTANCE}px)`,
                opacity: 0.5
            },
            {
                transform: 'translateY(0)',
                opacity: 1
            }
        ], {
            duration: DURATION,
            easing: 'ease'
        })
        animation.pause();
        animationMap.set(el, animation);
        ob.observe(el)
    },
    unmounted(el) {
        ob.unobserve(el)
    }
}

el.animate()

animate(keyframes, options)
keyframes关键帧对象数组, 一个关键帧对象
options代表动画持续时间的整数(以毫秒为单位),或者一个包含一个或多个时间属性的对象:

  • delay

  • 延迟动画开始的毫秒数。默认值为 0。

  • direction

  • 动画是向前 ()、向后 ()、在每次迭代后切换方向 (),还是在每次迭代后向后运行并切换方向 ()。默认值为 。normal``reverse``alternate``alternate-reverse``"normal"

  • duration

  • 动画每次迭代完成所需的毫秒数。默认值为 0。尽管这在技术上是可选的,但请记住,如果此值为 0,则动画将不会运行。

  • easing

  • 动画随时间的变化率。接受 <easing-function>,如 、 、 或 。默认值为 。"linear"``"ease-in"``"step-end"``"cubic-bezier(0.42, 0, 0.58, 1)"``"linear"

  • endDelay

  • 动画结束后延迟的毫秒数。这主要用于根据另一个动画的结束时间对动画进行排序。默认值为 0。

  • fill

  • 指示动画的效果是否应由播放前的元素反映 (s)、在动画完成播放 () 后保留,还是 .默认值为 。"backwards"``"forwards"``both``"none"

  • iterationStart

  • 描述动画应在迭代中的哪个时间点开始。例如,0.5 表示在第一次迭代的中途开始,如果设置了此值,则具有 2 次迭代的动画将在第三次迭代的中途结束。默认值为 0.0。

  • iterations

  • 动画应重复的次数。默认为 ,并且还可以采用 Infinity 值,使其在元素存在期间重复。1

  • composite

  • 确定如何在此动画和其他单独的动画之间组合值 未指定其自身特定复合操作的动画。默认值为 。replace

    • add决定了一种加法效果,其中每次连续迭代 建立在上一个的基础上。例如,使用 ,a 不会覆盖前面的值,而是生成 。transform``translateX(-200px)``rotate(20deg)``translateX(-200px) rotate(20deg)
    • accumulate相似但更聪明一点:并成为,而不是。blur(2)``blur(5)``blur(7)``blur(2) blur(5)
    • replace用新值覆盖以前的值。
  • iterationComposite

  • 确定值在此动画中如何从迭代到迭代生成。可以 设置为 OR(见上文)。违约 自。accumulate``replace``replace

  • pseudoElement

  • 包含伪元素选择器的 A,例如 .如果存在,则效果将应用于 的选定伪元素,而不是其本身。string``"::before"``target``target

WeakMap和Map的区别

JavaScript 中的 MapWeakMap 都是用来存储键值对的数据结构,但它们之间存在显著的区别:

  1. 键的类型限制

    • Map:可以接受任何类型的值作为键,无论是基本类型(如字符串、数字、布尔值等)还是对象引用。
    • WeakMap:其键必须是对象引用(除了null,因为null在JavaScript中被视为非对象),不能是基本类型的值。
  2. 引用强度

    • Map:对键值对的引用是强引用,这意味着只要 Map 存在并且包含某个键值对,即使外部没有任何其他引用指向键,键值对也会继续存在,不会被垃圾回收机制回收。
    • WeakMap:对键的引用是弱引用,也就是说,如果 WeakMap 中键所指向的对象在其他地方都没有引用了,则会在垃圾回收时被自动清理,同时对应的值也会被移除。这意味着你无法通过 WeakMap 使对象避免被垃圾回收。
  3. 迭代性

    • Map:提供了迭代方法,如 entries(), keys(), values(),以及可以直接迭代的特性。
    • WeakMap:不支持迭代操作,因此没有 size 属性,也无法直接遍历内部的键值对。
  4. 用途场景

    • Map:适用于需要长期存储、管理和检索键值对的场景,尤其当键可能是各种类型的复杂数据结构时。
    • WeakMap:通常用在需要关联对象的私有数据而又不想干扰垃圾回收机制的场景,例如关联 DOM 节点与附加数据,或者在闭包中存储对象的状态而不影响对象生命周期。

总结来说,WeakMap 主要是为了那些希望键值对与对象生命周期紧密相关的应用设计的,它可以确保当对象不再需要时,与其相关联的数据也会被自动清除,从而减轻内存泄漏的风险。而 Map 则提供了一个更为通用且功能丰富的键值对容器。

IntersectionObserver

创建一个新的 IntersectionObserver 对象,当其监听到目标元素的可见部分(的比例)超过了一个或多个阈值(threshold)时,会执行指定的回调函数。

  • IntersectionObserver.disconnect()

  • 使 IntersectionObserver 对象停止监听目标。

  • IntersectionObserver.observe()

  • 使 IntersectionObserver 开始监听一个目标元素。

  • IntersectionObserver.takeRecords()

  • 返回所有观察目标的 IntersectionObserverEntry 对象数组。

  • IntersectionObserver.unobserve()

  • 使 IntersectionObserver 停止监听特定目标元素。

ini 复制代码
var observer = new IntersectionObserver(callback[, options]);
  • callback

  • 当元素可见比例超过指定阈值后,会调用一个回调函数,此回调函数接受两个参数:

    • entries

      一个IntersectionObserverEntry对象的数组,每个被触发的阈值,都或多或少与指定阈值有偏差。

    • observer

      被调用的IntersectionObserver实例。

  • options

  • 一个可以用来配置 observer 实例的对象。如果options未指定,observer 实例默认使用文档视口作为 root,并且没有 margin,阈值为 0%(意味着即使一像素的改变都会触发回调函数)。你可以指定以下配置:

    • root

      监听元素的祖先元素Element对象,其边界盒将被视作视口。目标在根的可见区域的任何不可见部分都会被视为不可见。

    • rootMargin

      一个在计算交叉值时添加至根的边界盒 (bounding_box (en-US)) 中的一组偏移量,类型为字符串 (string) ,可以有效的缩小或扩大根的判定范围从而满足计算需要。语法大致和 CSS 中的margin 属性等同; 可以参考 intersection root 和 root margin 来深入了解 margin 的工作原理及其语法。默认值是"0px 0px 0px 0px"。

    • threshold

      规定了一个监听目标与边界盒交叉区域的比例值,可以是一个具体的数值或是一组 0.0 到 1.0 之间的数组。若指定值为 0.0,则意味着监听元素即使与根有 1 像素交叉,此元素也会被视为可见。若指定值为 1.0,则意味着整个元素都在可见范围内时才算可见。可以参考阈值来深入了解阈值是如何使用的。阈值的默认值为 0.0。

el.getBoundingClientRect()

方法返回一个 DOMRect对象,其提供了元素的大小及其相对于视口的位置。

相关推荐
大金乄几秒前
自动构建打包脚本(开发环境)
前端
jerrywus3 分钟前
为什么每个程序员都应该试试 cmux:AI 加持的终端效率革命
前端·人工智能·claude
codeniu9 分钟前
@logicflow/vue-node-registry 在 Vite 中无法解析的踩坑记录与解决方案
前端·javascript
孟祥_成都16 分钟前
AI 术语满天飞?90% 的人只懂名词,不懂为什么!
前端·人工智能
Lupino43 分钟前
被 React “玩弄”的 24 小时:为了修一个不存在的 Bug,我给大模型送了顿火锅钱
前端·react.js
米丘1 小时前
了解 Javascript 模块化,更好地掌握 Vite 、Webpack、Rollup 等打包工具
前端
Heo1 小时前
深入 React19 Diff 算法
前端·javascript·面试
滕青山1 小时前
个人所得税计算器 在线工具核心JS实现
前端·javascript·vue.js
小怪点点1 小时前
手写promise
前端·promise
国思RDIF框架1 小时前
RDIFramework.NET Web 敏捷开发框架 V6.3 发布 (.NET8+、Framework 双引擎)
前端