添加了导航栏的鼠标悬停效果
This commit is contained in:
93
src/h
Normal file
93
src/h
Normal file
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* useHover Hook
|
||||
* 用于检测鼠标悬停状态,仅在桌面端(Web)生效
|
||||
* 在移动端返回默认值 false
|
||||
*/
|
||||
import { useState, useCallback, useRef, useEffect } from 'react';
|
||||
import { Platform } from 'react-native';
|
||||
|
||||
interface UseHoverOptions {
|
||||
enterDelay?: number;
|
||||
leaveDelay?: number;
|
||||
}
|
||||
|
||||
interface UseHoverReturn {
|
||||
isHovered: boolean;
|
||||
hoverProps: {
|
||||
onMouseEnter: () => void;
|
||||
onMouseLeave: () => void;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测当前是否在 Web 平台
|
||||
*/
|
||||
const isWeb = Platform.OS === 'web';
|
||||
|
||||
/**
|
||||
* useHover Hook
|
||||
* @param options 配置选项
|
||||
* @returns 悬停状态和事件处理器
|
||||
*/
|
||||
export function useHover(options: UseHoverOptions = {}): UseHoverReturn {
|
||||
const { enterDelay = 0, leaveDelay = 0 } = options;
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
const enterTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
||||
const leaveTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
||||
|
||||
// 清理定时器
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (enterTimeoutRef.current) {
|
||||
clearTimeout(enterTimeoutRef.current);
|
||||
}
|
||||
if (leaveTimeoutRef.current) {
|
||||
clearTimeout(leaveTimeoutRef.current);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
const handleMouseEnter = useCallback(() => {
|
||||
if (!isWeb) return;
|
||||
|
||||
if (leaveTimeoutRef.current) {
|
||||
clearTimeout(leaveTimeoutRef.current);
|
||||
leaveTimeoutRef.current = null;
|
||||
}
|
||||
|
||||
if (enterDelay > 0) {
|
||||
enterTimeoutRef.current = setTimeout(() => {
|
||||
setIsHovered(true);
|
||||
}, enterDelay);
|
||||
} else {
|
||||
setIsHovered(true);
|
||||
}
|
||||
}, [enterDelay]);
|
||||
|
||||
const handleMouseLeave = useCallback(() => {
|
||||
if (!isWeb) return;
|
||||
|
||||
if (enterTimeoutRef.current) {
|
||||
clearTimeout(enterTimeoutRef.current);
|
||||
enterTimeoutRef.current = null;
|
||||
}
|
||||
|
||||
if (leaveDelay > 0) {
|
||||
leaveTimeoutRef.current = setTimeout(() => {
|
||||
setIsHovered(false);
|
||||
}, leaveDelay);
|
||||
} else {
|
||||
setIsHovered(false);
|
||||
}
|
||||
}, [leaveDelay]);
|
||||
|
||||
return {
|
||||
isHovered,
|
||||
hoverProps: {
|
||||
onMouseEnter: handleMouseEnter,
|
||||
onMouseLeave: handleMouseLeave,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default useHover;
|
||||
Reference in New Issue
Block a user