javascript - 反应:移动(iPhone)上的onClick需要2次点击?
问题描述
我有一堆可点击的组件,当点击它们时,会在一行中添加一个“卡片”。在台式机上,它工作正常,但在移动设备上(在 iPhone 上测试,似乎对 Android 平板电脑不是问题),它需要连续点击同一按钮 2 次才能触发该onClick
功能。
这些组件也对它们有onMouseEnter
/onMouseLeave
效果,以控制全局状态,这反过来又决定是否应该应用额外的 CSS 几个组件(所以我不能让它成为一个简单的 CSS 悬停效果)。
我相信鼠标效果会干扰点击事件,但我不知道如何解决这个问题。这是该组件的相关代码:
const CardSource = ({ addCard, note, setHoveredNote, hoveredNote }) => {
return (
<Source
onClick={() => addCard(note)}
onMouseEnter={() => setHoveredNote(note)}
onMouseLeave={() => setHoveredNote(null)}
className={
hoveredNote && hoveredNote.index === note.index ? "highlight" : null
}
>
{note.letters[0]}
</Source>
);
};
此外,一旦一个按钮被点击了两次,悬停效果 CSS 就会“粘”在那个按钮上,并且永远不会移动到另一个按钮上。这似乎发生在 iPhone 和 Android 平板电脑上。我也希望不再发生这种情况。
我在沙箱中创建了此问题的工作演示,如果在移动设备上查看,您应该能够重新创建这些问题:https ://codesandbox.io/s/mobile-requires-2-taps-i9zri?file= /src/Components/CardSource/CardSource.js
解决方案
您的代码可能存在问题,您使用的鼠标事件是non-bubbling。例如 mouseenter 事件。
您可能想尝试使用事件冒泡解决方案,onMouseOver
而不是onMouseEnter
,而onMouseOut
不是onMouseLeave
。
const CardSource = ({ addCard, note, setHoveredNote, hoveredNote }) => {
return (
<Source
onClick={() => addCard(note)}
onMouseOver={() => setHoveredNote(note)}
onMouseOut={() => setHoveredNote(null)}
className={
hoveredNote && hoveredNote.index === note.index ? "highlight" : null
}
>
{note.letters[0]}
</Source>
);
};
如果上述方法不起作用,您可以使用事件类型进行调试并基于它执行事件处理。例如
const CardSource = ({ addCard, note, setHoveredNote, hoveredNote }) => {
const eventHandler = (event) => {
const { type, bubbles } = event;
switch(type) {
case "mouseover":
case "mouseenter":
setHoveredNote(note);
break;
case "mouseout":
case "mouseleave":
setHoveredNote(null);
case "click":
addCard(note);
if (bubbles) { // handle hover state
setHoveredNote(note);
}
break;
default:
break;
}
}
const onClick = (event) => eventHandler(event);
const onMouseOver = (event) => eventHandler(event);
const onMouseOut = (event) => eventHandler(event);
return (
<Source
onClick={onClick}
onMouseOver={onMouseOver}
onMouseOut={onMouseOut}
className={
hoveredNote && hoveredNote.index === note.index ? "highlight" : null
}
>
{note.letters[0]}
</Source>
);
};
另请注意,提供箭头函数作为道具会在每次渲染时创建该函数的新实例。所以最好在这种情况下使用 bind 或者只是捕获参数的函数引用。
推荐阅读
- c++ - cudaMemcpy 仍然无法托管设备分配的内存?
- nmea - 将 GPGSV 转换为 GPRMC 或 Google 地图位置?
- spring - Spring JPA 版本化实体休眠错误
- api - 使用谷歌应用脚本调用 UPS API 时获得截断的 JSON 响应
- java - Java,App Insights:“I/O 异常:无效参数或无法分配请求的地址”仅当我使用 docker 运行时。使用gradle本地没有错误
- ios - 表格视图标题、情节提要、Xcode 11?
- ionic4 - Ionic 4 - 如何减少离子列表项的高度
- c# - Accord.Video.FFMPEG 创建质量非常低的视频
- c# - 如何在 c# 中将当前文化发送到我的 Grpc 服务器?
- c# - C#将动态对象数组添加到动态对象列表中