我目前正在尝试使用React创建自己的下拉组件。当组件获得焦点时,它应该打开选项。而且,您还应该能够在单击时切换选项。
我创建了一个small example来重制此案。
问题是,单击未聚焦的组件时,聚焦和单击事件都将触发,这将打开和关闭选项。元素集中之后,单击事件将按预期方式工作。也使用选项卡获得焦点正在工作。
我没有很好的解决方案来防止这种行为。 event.stopPropation()
不起作用,因为这些是同一元素上的2个不同的事件。我唯一的解决方案是具有“ hasFocus”状态,并将其设置为100ms的短暂延迟,然后在onClick函数中进行检查。
当前行为:下拉菜单元素未定位。单击该元素将触发焦点并单击事件,从而导致
ShowOptions: true
ShowOptions: false
所以这些选项只是闪烁而后会被隐藏
预期的行为:触发焦点或单击事件并显示选项。
也许您对这个问题有更好的解决方案。
答案 0 :(得分:1)
如您所说:
触发焦点或单击事件并显示选项。
因此,您需要使用或||
运算符:{(isOpen.isClicked || isOpen.isFocused) && <div>Options</div>}
const Dropdown = () => {
const [isOpen, setIsOpen] = useState({ isFocused: false, isClicked: false });
const onFocus = () => {
setIsOpen(prev => ({ ...prev, isFocused: true }));
};
const onBlur = () => {
setIsOpen({ isFocused: false, isClicked: false });
};
const onClick = () => {
setIsOpen(prev => ({
isClicked: !prev.isClicked,
isFocused: false
}));
};
return (
<React.Fragment>
<Container
onFocus={onFocus}
onBlur={onBlur}
alignItems="stretch"
onClick={onClick}
>
...
</Container>
{(isOpen.isClicked || isOpen.isFocused) && <div>Options</div>}
</React.Fragment>
);
};
演示:
答案 1 :(得分:0)
我通过添加mousedown和mouseup事件解决了我的问题。在焦点事件之前触发Mousedown(以及触摸事件)。因此,我可以在单击元素时“跳过”焦点案例。
const [showValues, setShowValues] = useState(false);
const [mouseDown, setMouseDown] = useState(false);
const onFocus = e => {
if (!mouseDown) {
setShowValues(true);
console.log("focus");
}
};
const onBlur = e => {
setShowValues(false);
console.log("blur");
};
const onClick = e => {
setShowValues(!showValues);
console.log("click");
};
const onMouseDown = () => {
setMouseDown(true);
};
const onMouseUp = () => {
setMouseDown(false);
};