本例子实现了自定义hook之监听dom滚动悬浮状态hooks,具体代码如下
import { usePageScroll } from '@tarojs/taro';
import { useCallback, useEffect, useState } from 'react';
import { NodesRef, useDidShow } from '@tarojs/taro';
import { useSelectorQuery } from 'taro-hooks';
/**
* 获取指定dom 的 `rect` 对象
* @param id
* @returns
*/
const useQueryRect = (
id: string,
): [rect: NodesRef.BoundingClientRectCallbackResult | undefined, flush: () => void] => {
const [query] = useSelectorQuery();
const [rect, setRect] = useState<NodesRef.BoundingClientRectCallbackResult>();
const flush = useCallback(() => {
query
.select(id.startsWith('#') ? id : `#${id}`)
.boundingClientRect((respRect) => {
setRect(respRect);
})
.exec();
}, [id, query]);
useDidShow(() => {
flush();
});
useEffect(() => {
if (!rect) {
query
.select(id.startsWith('#') ? id : `#${id}`)
.boundingClientRect((respRect) => {
setRect(respRect);
})
.exec();
}
}, [id, query, rect]);
return [rect, flush];
};
/**
* @description 监听dom滚动悬浮状态
* @description navBar 悬浮状态
* @param id 需要监听的domId eg: 'navbar' | '#navbar'
*/
const useDomFixed = (id: string): [fixed: boolean] => {
const [rect] = useQueryRect(id);
const [fixed, setFixed] = useState(false);
usePageScroll((pageRes) => {
const pageScrollTop = pageRes.scrollTop;
if (rect && pageScrollTop >= rect?.top) {
!fixed && setFixed(true);
} else {
fixed && setFixed(false);
}
});
return [fixed];
};
export default useDomFixed;