0
点赞
收藏
分享

微信扫一扫

好看的滚动文字渐入效果

全部代码:

const observers = [] // 用于存储所有观察者 -> 收集起来主要是为了当路由变化时效果之前的观察者。

export default {
 // ... 省略
 setup() {
  const route = useRoute()
  onMounted(() => {
   initFirstScreen() // 初始化 -> 给首次渲染就在视口的元素加上自定义属性,这些元素永远不用加动画类
   animateFn() // 执行核心脚本
  })
  
    // 元素是否在视口
  const isElementInViewport = element => {
   var rect = element.getBoundingClientRect()
   const isInViewport =
    rect.top >= 0 &&
    rect.bottom <=
     (window.innerHeight || document.documentElement.clientHeight)
   return isInViewport
  }
 
    // 检查是否有自定义属性
  const checkHasAttribute = element => {
   return !!element.getAttribute('snow_is_show')
  }
  
    // 初始化函数
  const initFirstScreen = () => {
   const main = document.querySelector('.vp-doc>div') || []
   const paragraphs = [...(main?.children || [])]
   paragraphs.forEach(item => {
    if (isElementInViewport(item)) {
     item.setAttribute('snow_is_show', true)
    }
   })
  }
  
    // 核心脚本 
  const animateFn = () => {
   const main = document.querySelector('.vp-doc>div') || []
   const paragraphs = [...(main?.children || [])]
   paragraphs.forEach(item => {
    const observer = new IntersectionObserver(entries => {
     entries.forEach(entry => {
      if (entry.isIntersecting && !checkHasAttribute(item)) {
       // 元素进入视口
       item.classList.add('animate__animated')
       item.classList.add('animate__fadeInUp')
       item.setAttribute('snow_is_show', true)
      }
     })
    })
    observer.observe(item)
    observers.push(observer)
   })
  }
  
    // 清空所有 observer 的函数
  const destructionObserver = () => {
   observers.forEach(observe => {
    observe.disconnect()
   })
   observers.length = 0
  }
    
  watch(
   () => route.path,
   () =>
    nextTick(() => {
     destructionObserver() // 先清空所有的观察者
     initFirstScreen() // 再初始化一次 类似onMounted
     animateFn() // 再次执行核心函数
    })
  )
 },
 Layout,
}

举报

相关推荐

0 条评论