
html原生`
在React(或纯JavaScript)开发中,常有需求——当用户将鼠标移至下拉菜单的某个
因此,直接在
✅ 正确方案:监听
虽然无法监听
以下是优化后的React实现(含防抖与边界处理):
import { useState, useRef, useEffect } from 'react';
function HoverableSelect({ nodes, selectedValue, onChange }: {
nodes: Array<{ text: string }>;
selectedValue: string;
onChange: (value: string) => void;
}) {
const selectRef = useRef(null);
const [hoveredOption, setHoveredOption] = useState(null);
const handleMouseMove = (e: React.MouseEvent) => {
const select = e.currentTarget;
// 防止因快速移动导致频繁计算
if (!select.options.length) return;
// 获取当前选中索引(注意:仅当下拉展开时,selectedIndex 才反映视觉悬停位置;
// 但多数现代浏览器在展开状态下会实时更新 selectedIndex)
const index = select.selectedIndex;
if (index >= 0 && index < select.options.length) {
const option = select.options[index];
// 确保不是初始未选择状态,且值已变更
if (option.value && option.value !== hoveredOption) {
setHoveredOption(option.value);
console.log('Hovering over:', option.value);
// ? 此处可触发自定义逻辑:如 fetch preview, update tooltip, etc.
}
}
};
// 可选:鼠标离开时重置状态
const handleMouseLeave = () => {
setHoveredOption(null);
};
return (
);
} ⚠️ 注意事项与局限性
- 浏览器兼容性差异:selectedIndex 在下拉展开时是否实时响应鼠标悬停,取决于浏览器实现(Chrome/Edge 较可靠,Safari 行为略有不同)。不可用于需要像素级精准定位的场景。
- 移动端无效:触摸设备无“hover”概念,此方案仅适用于桌面端。
- 无障碍考量:该交互不属于WAI-ARIA推荐模式,若需满足无障碍标准(WCAG),应优先使用键盘导航(ArrowUp/Down)+ onChange 事件,并辅以aria-live区域播报。
-
更健壮的替代方案:如需完全可控的悬停体验,建议使用自定义下拉组件(如基于+ usePopper + useState构建),可自由绑定所有事件、支持动画、无障碍及样式定制。
✅ 总结
原生










