vue2 实现echarts图表进入可视区域后再加载动画,以及 使用了resize之后,动画失效问题解决

Intersection Observer API是一个现代的浏览器 API,用于监测一个或多个目标元素与其祖先元素或视窗(viewport)之间的交叉状态(intersection)的变化。它可以有效地监听元素是否进入或离开可视区域,从而实现一些懒加载、无限滚动、图表加载等需求。

主要特点和用途:

  1. 懒加载(Lazy Loading):当页面中的某些元素在可视区域内时再加载它们,以提升页面加载速度和性能。

  2. 无限滚动(Infinite Scrolling):当滚动到页面底部时加载更多内容,实现无限滚动列表或分页加载。

  3. 图表加载:在图表或其他数据可视化组件进入可视区域时再触发加载动画或数据更新。

  4. 广告展示:监测广告是否被用户看到,从而统计广告的曝光量

javascript 复制代码
使用方法:
1、创建 IntersectionObserver 实例:
var observer = new IntersectionObserver(callback, options);
callback 是一个回调函数,用于处理交叉状态的变化。
options 是一个配置对象,可以设置 root(祖先元素)、rootMargin(边界)、thresholds(阈值)等参数。

2、观察目标元素:observer.observe(target);

3、处理交叉状态变化:
var callback = function(entries, observer) {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      // 处理目标元素进入可视区域的逻辑
    } else {
      // 处理目标元素离开可视区域的逻辑
    }
  });
};

4、停止观察:observer.unobserve(target);

主要属性和方法:

  • isIntersecting:表示目标元素是否与根元素(root)或视窗(viewport)相交。
  • intersectionRatio:表示目标元素的可见比例,取值范围为 0 到 1。
  • root:观察器的根元素,即相对于该元素来计算交叉状态,默认为视窗。
  • rootMargin:边界,可以设置在计算交叉状态时扩展或缩小根元素的大小。
  • thresholds:阈值数组,用于指定交叉比例的阈值,当目标元素的交叉比例超过指定的阈值时触发回调。

Intersection Observer API 的主要优势在于它可以高效地监测大量元素的交叉状态变化,而无需频繁地监听滚动事件或手动计算元素位置,从而提升了性能和用户体验。

javascript 复制代码
  mounted () {
    await this.getInitDataFun() //  数据
      this.$nextTick(() => {
        this.getEchartData() // 绘制图表
     })
  },

  methods: {
    // 获取数据 处理图表需要的data
     getInitDataFun () {
      return new Promise(async (resolve, reject) => {
        ........
      })
    },

    getEchartData () {
      const salesTrendDom = this.$refs.salesTrendRef //销售额
      const orderCustomerDom = this.$refs.orderCustomerRef //下单客户数趋势
      
      // 销售额
      if (salesTrendDom) {
        this.loadAnimationFun(salesTrendDom, 'salesTrendOption')
      }

      //下单客户数趋势
      if (orderCustomerDom) {
        this.loadAnimationFun(orderCustomerDom, 'orderCustomerOption')
      }
    },


    // 加载动画
    loadAnimationFun (dom, option) {
      let myChart = this.$echarts.init(dom)
      var observer = new IntersectionObserver((entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            // 加载动画
            myChart.setOption(this[option])
            this.addLoadEvent(myChart.resize) //添加 监听屏幕缩放
            setTimeout(function () {
         // 使用了resize之后,动画失效,这是echarts5的bug,echarts4不会  动画在这里加就好了
              myChart.resize({
                animation: {
                  duration: 1800,
                  easing: 'ease-in-out'
                }
              })
            }, 1)
            // 停止观察图表
            observer.unobserve(entry.target)
          }
        })
      })
      // 观察图表元素
      observer.observe(myChart.getDom())
    },


  addLoadEvent (fn) {
      var old = window.onresize
      if (typeof window.onresize != 'function') {
        //防止多个window.onresize   冲突  解决
        window.onresize = fn
      } else {
        window.onresize = function () {
          old()
          setTimeout(function () {
            //个别时候无法刷新echarts 延迟1MS  解决
            fn()
          }, 1)
        }
      }
    }
}
相关推荐
卸任5 小时前
Vibe coding工具使用心得
前端·ai编程
brien95 小时前
为什么模型标称 1M,Google Antigravity 聊到 256K 却突然失忆?我们给它做了个原生行内监控圆环
前端
修炼的dance6 小时前
录屏关键帧间隔多少合适?六档实测,2秒到10秒小了75.6%
前端
Lank_M6 小时前
关键帧从1秒拉到10秒,录屏小87.3%,摄像头小10.8%
前端
补码缩写6 小时前
用 ffprobe 拆录屏,八成字节在 29 个关键帧上
前端
百思不得小李6 小时前
一个复杂的动态表单是如何实现的
前端·设计模式
陈随易6 小时前
Cmder 停更 17 个月,2.0 支持 Windows Terminal
前端·后端·程序员
清晨Coding6 小时前
删了 Cookie 还能自动登录?Google系网站登录态自动恢复的原理分析
javascript
风骏时光牛马6 小时前
前沿视界
前端
kyriewen6 小时前
我扫了 814 个依赖,97 个还敢要 Node 10
前端·javascript·程序员