
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构建),可自由绑定所有事件、支持动画、无障碍及样式定制。
✅ 总结
原生