如何在Vue视口插件可见的视口上触发功能

Nat*_*ira 1 counter viewport vue.js

我正在使用计数器来显示一些数字,但是它们会在页面加载时加载,因此除非我执行某个按钮来触发它,否则它会加载。找到了这个视口插件(https://github.com/BKWLD/vue-in-viewport-mixin),但我无法使用它。这就是我需要做的,当我到达某个元素(完全)时触发一个函数,如何实现它?

Cat*_* Ha 6

你不一定需要一个包来做到这一点。添加事件监听器来监听滚动事件,并在每次有滚动事件时检查元素是否在视口中。下面的示例代码 - 请注意,我添加了一个动画来强调“如果在视口中出现”效果。

代码笔在这里

new Vue({
  el: '#app',
  created () {
    window.addEventListener('scroll', this.onScroll);
  },
  destroyed () {
    window.removeEventListener('scroll', this.onScroll);
  },
  data () {
    return {
      items: [
        1,
        2,
        3,
        4,
        5,
        6, 
        7, 
        8, 
        9, 
        10, 
        11, 
        12
      ],
      offsetTop: 0
    }
  },
  watch: {
    offsetTop (val) {
       this.callbackFunc()
    }
  },
  methods: {
    onScroll (e) {
      console.log('scrolling')
      this.offsetTop = window.pageYOffset || document.documentElement.scrollTop
    },
    isElementInViewport(el) {
      var rect = el.getBoundingClientRect();
      return (
        rect.top >= 0 &&
        rect.left >= 0 &&
        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
        rect.right <= (window.innerWidth || document.documentElement.clientWidth)
      );
    },
    callbackFunc() {
      let items = document.querySelectorAll(".card");
      for (var i = 0; i < items.length; i++) {
        if (this.isElementInViewport(items[i])) {
          items[i].classList.add("in-view");
        }
      }
    }
  }
})
Run Code Online (Sandbox Code Playgroud)
.card {
  height: 100px;
  border: 1px solid #000;
  visibility: hidden;
  opacity: 0
}
.in-view {
  visibility: visible;
  opacity: 1;
  animation: bounce-appear .5s ease forwards;
}

@keyframes bounce-appear {
  0% {
    transform: translateY(-50%) translateX(-50%) scale(0);
  }
  90% {
    transform: translateY(-50%) translateX(-50%) scale(1.1);
  }
  100% {
    tranform: translateY(-50%) translateX(-50%) scale(1);
  }
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app" onscroll="onScroll">
  <div v-for="item in items" class="card">
    {{item}}
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用交叉观察者——我还没有探索过这个,但这个教程看起来不错:alligator.io/vuejs/lazy-image。请注意,您将需要一个用于 IE 的 polyfill。

  • 它不会在每个卷轴上更新。它在每一个卷轴上聆听——这是有区别的。我不太确定性能差异,但您也可以为此使用交叉观察器:https://alligator.io/vuejs/lazy-image/,这是您定向到的包所基于的。就我个人而言,我总是更喜欢创建自己的组件而不是使用其他人的包,因为担心包膨胀和版本控制问题以及出于学习的目的。 (3认同)
  • 我建议将 `offsetTop: 0` 替换为 `offsetTop: window.pageYOffset || document.documentElement.scrollTop`。当最初在不同位置加载页面时,这应该设置正确的偏移量 - 假设您位于顶部位置并不总是正确的。 (2认同)