效果展示

vue文件的指令使用
<style lang="scss">
.container {width: 88%;margin: 1rem auto;.item {background:url('../assets/boxImg.jpg') no-repeat;background-size: 100% 100%;width: 100%;height: 300px;margin-bottom: 20px;display: flex;align-items: center;justify-content: center;color: #fff;font-size: 3rem; }
}
</style>
<div class="container"><div class="item" v-domSlown v-for="(item, index) in 10" :key="index" > </div></div>
指令文件
//domSlowness.jsimport Vue from 'vue';// 判断元素是不是在视口之下
function isBelowViewport(el) {const rect = el.getBoundingClientRect();return rect.top > window.innerHeight;
}
const DISTANCE = 150;
const DURATION = 1000;
const animationMap = new WeakMap();const ob = new IntersectionObserver(entries => {for (const entry of entries) {if (entry.isIntersecting) { // 判断元素是否与视口交叉const animation = animationMap.get(entry.target);animation.play();ob.unobserve(entry.target);}}
})
Vue.directive('domSlown',{ inserted(el,binding){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);},unbind(el) {ob.unobserve(el);}
})
主文件入口引用指令文件
//main.js
import '@/assets/domSlowness.js'