Live2D

traojs 封装一个支持onFirstAppear和onAppear的view组件

第一步:基础view

import { View as TaroView } from '@tarojs/components';
import { ViewProps } from '@tarojs/components/types/View';
import dayjs from 'dayjs';

interface iViewsProps extends ViewProps {
  onAppear?: () => void;
  onFirstAppear?: () => void;
  id?: string;
  throttleTime?: number;
}

/** 注意唯一className */
const View = (props: iViewsProps) => {
  const { throttleTime = 1000, ...restProps } = props;
  const throttle = (fn, wait = 1000) => {
    if (!fn) {
      return;
    }
    // 上一次执行 fn 的时间
    let previous = dayjs().valueOf();
    let firstClick = true;
    // 将 throttle 处理结果当作函数返回
    return function (...args) {
      // 获取当前时间,转换成时间戳,单位毫秒
      const now = dayjs().valueOf();
      // 将当前时间和上一次执行函数的时间进行对比x
      // 大于等待时间就把 previous 设置为当前时间并执行函数 fn
      console.error('now - previous: ', now - previous, firstClick);
      if (firstClick) {
        fn && fn.apply(this, args);
        firstClick = false;
        previous = dayjs().valueOf();
      } else if (now - previous > wait) {
        previous = now;
        firstClick = false;
        fn && fn.apply(this, args);
      }
    };
  };

  const throttledClick = throttle(props?.onClick, throttleTime);
  return <TaroView {...restProps} onClick={throttledClick} />;
};

export default View;

第二步: 封装支持onFirstAppear和onAppear

import TaroView from '@/components/GymComponents/GymView';
import { useRef, useEffect } from 'react';
import Taro, { PageInstance } from '@tarojs/taro';
import { ViewProps } from '@tarojs/components/types/View';

interface iViewsProps extends ViewProps {
  onAppear?: () => void;
  onFirstAppear?: () => void;
  id?: string;
}
/** 注意唯一className */
const View = (props: iViewsProps) => {
  const { onAppear, onFirstAppear, className, id } = props;
  const timeRef = useRef(0);
  const setTimeId: { current: NodeJS.Timeout | null } = useRef(null);

  // 监听最顶部元素是否在视野内
  useEffect(() => {
    if (!className && !id) {
      return;
    }
    const observer = Taro.createIntersectionObserver(
      Taro.getCurrentInstance().page as PageInstance,
      {
        thresholds: [0],
      },
    );

    setTimeId.current = setTimeout(() => {
      const el = id ? `#${id}` : `.${className}`;
      observer.relativeToViewport().observe(el, res => {
        if (res.intersectionRatio) {
          onAppear && onAppear();
          timeRef.current++;
          console.error('onAppear',timeRef.current)

          if (timeRef.current <= 1) {
            console.error('123123123',123123123)
            onFirstAppear && onFirstAppear();
          }
        }
      });
    }, 0);

    return () => {
      if (observer) {
        observer.disconnect();
        if (setTimeId.current) {
          clearTimeout(setTimeId.current);
          setTimeId.current = null;
        }
      }
    };
  }, [className, id]);

  return <TaroView {...props} />;
};

export default View;

使用:

import RecordView form "../view"

   <RecordView
       id="login_btn"
       onFirstAppear={()={//doSomething}}
       onAppear={()={//doSomething}}
     />

 

posted @ 2025-03-13 15:59  喻佳文  阅读(20)  评论(0)    收藏  举报