监听页面是否是在可视区域

115 阅读1分钟

1. Intersection Observer API(推荐)

• Intersection Observer API提供了一种异步观察目标元素与其祖先元素或视口交叉状态变化的方法。在Vue中可以这样使用:

• 首先,在组件的mounted生命周期钩子中创建观察器。假设你有一个组件,想要观察它是否在可视区域:

<template>
  <div ref="targetElement">
    这是要观察的元素
  </div>
</template>
<script>
export default {
  name: 'MyComponent',
  mounted() {
    const target = this.$refs.targetElement;
    const observer = new IntersectionObserver((entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          console.log('元素进入可视区域');
          // 可以在这里执行元素进入可视区域后的逻辑,比如加载数据、播放动画等
        } else {
          console.log('元素离开可视区域');
          // 执行元素离开可视区域后的逻辑
        }
      });
    });
    observer.observe(target);
  },
  beforeDestroy() {
    const target = this.$refs.targetElement;
    const observer = new IntersectionObserver(() => {});
    observer.unobserve(target);
  }
};
</script>

• 这段代码创建了一个Intersection Observer对象,当被观察的元素(通过this.$refs.targetElement获取)与视口交叉状态发生变化时,会执行回调函数。如果entry.isIntersecting为true,表示元素进入可视区域,否则表示元素离开可视区域。

2. 通过计算元素位置和视口位置来判断(较复杂)

• 可以在mounted钩子中获取元素位置和视口位置相关信息,然后通过window的scroll事件来监听滚动,判断元素是否在可视区域。

• 例如:

  <div ref="targetElement">
    这是要观察的元素
  </div>
</template>
<script>
export default {
  name: 'MyComponent',
  data() {
    return {
      isVisible: false
    };
  },
  mounted() {
    const target = this.$refs.targetElement;
    const rect = target.getBoundingClientRect();
    const windowHeight = window.innerHeight;
    window.addEventListener('scroll', () => {
      const rect = target.getBoundingClientRect();
      if (rect.top <= windowHeight && rect.bottom >= 0) {
        this.isVisible = true;
        console.log('元素在可视区域');
      } else {
        this.isVisible = false;
        console.log('元素不在可视区域');
      }
    });
  },
  beforeDestroy() {
    window.removeEventListener('scroll', () => {});
  }
};
</script>

• 这里通过getBoundingClientRect方法获取元素相对于视口的位置信息,结合window.innerHeight(视口高度)来判断元素是否在可视区域。每次window滚动时,都会重新计算并更新isVisible状态。这种方法相对Intersection Observer API来说,性能可能稍差,因为需要频繁地计算元素位置和进行比较。