• vue之使用IntersectionObserver API实现封装滚动动画组件


    IntersectionObserver API 是浏览器监听元素是否在可视区域的API,详情见:vue自定义指令之图片懒加载

    使用:

    className 自定义动画类名
    mode shutdown表示执行一次,noShoudown 表示执行多次,持续监听

    <Scroll className="ani">
    	<div>
              我是内我是内容我是内容我是内容我是内容容我是内我是内容我是内容我是内容我是内容容我是内我是内容我是内容我是内容我是内容容我是内我是内容我是内容我是内容我是内容容我是内我是内容我是内容我是内容我是内容容我是内我是内容我是内容我是内容我是内容容
    	div>
    Scroll>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    组件

    <template>
      <div
        ref="scrollRef"
        class="scroll"
        :class="[
          isRunning && !!className
            ? className
            : isRunning && !className
            ? 'onscroll'
            : '',
        ]"
      >
        <slot>slot>
      div>
    template>
    
    <script>
    export default {
      props: {
        className: {
          type: String,
          default: '',
        },
        mode: {
          type: String,
          default: 'shutdown',
        },
      },
      data() {
        return {
          isRunning: false,
        }
      },
      mounted() {
        this.handelScroll()
      },
      methods: {
        handelScroll() {
          const el = this.$refs.scrollRef
          const observer = new IntersectionObserver(
            ([{ isIntersecting }]) => {
              if (this.mode === 'noShutdown') {
                this.isRunning = !!isIntersecting
              } else if (isIntersecting) {
                this.isRunning = true
                // 关闭监听
                observer.unobserve(el)
              }
              el.onerror = (err) => console.error(err)
            },
            { threshold: 0 }
          )
          //   开启监听
          observer.observe(el)
        },
      },
    }
    script>
    
    <style lang="scss" scoped>
    // 动画
    @keyframes scroll-ani {
      0% {
        opacity: 0;
        transform: translate3d(0, 100%, 0);
      }
      100% {
        opacity: 1;
        transform: translateZ(0);
      }
    }
    
    .onscroll {
      animation-duration: 0.46s;
      animation-delay: 0.2s;
      animation-fill-mode: both;
      animation-timing-function: ease-in-out;
      animation-name: scroll-ani;
      opacity: 0;
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    之前方法

    通过计算元素偏移量与视口高度距离得出是否在可视区域

    <script>
    export default {
      data: () => {
        return {
          running: false,
          screenHeight: 0,
          currentScroll: 0,
          tranTop: 0,
        }
      },
      mounted() {
        this.init()
        window.addEventListener('scroll', this.handleScroll, true)
      },
      beforeDestroy() {
        window.removeEventListener('scroll', this.handleScroll, true)
      },
      methods: {
        init() {
          this.screenHeight = window.innerHeight
          this.tranTop =
            this.$refs.scrollRef.getBoundingClientRect().top + window.scrollY
        },
        // 滚动动画
        handleScroll() {
          this.currentScroll = window.pageYOffset
          if (this.currentScroll >= this.tranTop - this.screenHeight) {
            this.running = true
          } else {
            this.running = false
          }
        },
      },
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
  • 相关阅读:
    SystemVerilog Assertions应用指南 Chapter1.29“ disable iff构造
    【Web_自动化测试_Python3_webdriver_etree_批量下载京东图片】通过地址抓取静态网页+解析标题和链接+通过链接批量下载图片
    测试基础:Nosql数据库之Redis
    详解容灾架构中的脑裂问题
    nginx(2)
    感性认识一下Linux的进程地址空间和写时拷贝技术
    算法学习-优先队列(堆)
    使用极域电子教室控制学员机开机问题
    线路横断面测量坐标转换程序
    C. Monoblock(思维/计数)
  • 原文地址:https://blog.csdn.net/wgh4318/article/details/126781622