当前位置: 首页 > 工具软件 > scrollreveal > 使用案例 >

react使用scrollreveal页面加载会闪烁一下问题解决

马宜民
2023-12-01

问题

jlmakes / scrollreveal 是目前使用量最多的滚动揭示动画库,也是非常好用,只需要添加对应 className 即可。

但是在 react 中会有第一次加载闪烁的问题。

解决

首先你要把需要动态揭示的 dom 隐藏起来,我这里假定所有需要滚动揭示的节点都附加上 j-scroll-reveal_ 这个 class :

.j-scroll-reveal_ {
  visibility: hidden;
}

之后写一个滚动揭示的 hooks :

import { useEffect, useRef } from 'react'
import ScrollReveal from 'scrollreveal'

const REVEAL_CLASS = 'j-scroll-reveal_'

export const useScrollReveal = () => {

  // 把全局实例初始化起来
  const ins = useRef(
    ScrollReveal() as scrollReveal.ScrollRevealObject & {
      destroy?: () => void
    }
  )

  // 把隐藏恢复的锁
  const isStyleAddedRef = useRef(false)

  useEffect(() => {
    const ref = ins.current
    ref.reveal(`.${REVEAL_CLASS}`, {
      // .... other options
      interval: 150,
      // 在开始揭示的钩子里把 dom 展示出来
      beforeReveal: () => {
        if (isStyleAddedRef.current) {
          return
        }
        isStyleAddedRef.current = true
        const style = document.createElement('style')
        style.innerHTML = `.${REVEAL_CLASS} {visibility: visible;}`
        document.getElementsByTagName('head')[0].appendChild(style)
      },
    })

    return () => {
      // https://scrollrevealjs.org/guide/whats-new.html
      ref?.destroy?.()
    }
  }, [])
}

注意,现在 @types/scrollreveal 这个 type 库没有 destory 等最新的方法的 type,可以自己补一下。

核心思路是先通过全局样式隐藏掉,再开始揭示的时候展示出来,这样子就可以完美避免闪烁的问题。

有人会问使用 useLayoutEffect 在渲染前操作可不可以?当然不可以,滚动揭示是异步的,和 hooks 时机无关。

总结

虽然这种 hack 方式能解决问题,但在大部分业务项目里,一般不会用到滚动揭示。

如果确实有这种需求,也可以考虑使用一些动画库来实现滚动渐入,这方面就比较广了,但需要考虑好时机,需不需要自己管理 IntersectionObserver 等。

 类似资料: