我正在开发这个工具提示,如果您将鼠标悬停在它上面,它会显示一个工具提示:
但是如果您(用手指)点击它,它将显示全屏(用于移动支持):
代码如下所示:
export default function Tooltip({ message, children }: Props) {
const [showSmallTip, setShowSmallTip] = useState(false);
const [showBigTap, setShowBigTip] = useState(false);
const ref = useRef(null);
const pos = useBoundingBox(ref);
const handleMouseEnter = useCallback(() => {
setShowSmallTip(true);
}, [setShowSmallTip]);
const handleMouseLeave = useCallback(() => {
setShowSmallTip(false);
}, [setShowSmallTip]);
const handleTap = useCallback(() => {
console.log("TAP!")
setShowBigTip(true);
setShowSmallTip(false);
}, [setShowBigTip]);
const closeFullscreen = useCallback((ev:MouseEvent<HTMLElement>) => {
console.log('CLOSE!!!')
ev.stopPropagation();
setShowBigTip(false);
setShowSmallTip(false);
}, [setShowBigTip]);
const onTap = useTap(handleTap);
return <>
<Wrapper ref={ref} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave} {...onTap}>
{children}
</Wrapper>
{showSmallTip ? <End container={SCROLL_ROOT}><StyledTooltip style={{ top: pos.bottom, left: (pos.left + pos.right) / 2 }}>{message}</StyledTooltip></End> : null}
{showBigTap ? <End><FullscreenTip onClick={closeFullscreen}><FullscreenText>{message}</FullscreenText></FullscreenTip></End>:null}
</>
}
哪里useTap
是:
export default function useTap<T = Element>(callback: VoidCallback, options?: Options): TouchEvents<T> {
const data = useRef<TouchData>(Object.create(null));
return useMemo<TouchEvents<T>>(() => {
const opt = { ...DEFAULT_OPTIONS, ...options } as Required<Options>;
return {
onTouchStart(ev) {
data.current = {
time: ev.timeStamp,
x: ev.changedTouches[0].screenX,
y: ev.changedTouches[0].screenY,
}
},
onTouchEnd(ev) {
const mx = ev.changedTouches[0].screenX - data.current.x;
const my = ev.changedTouches[0].screenY - data.current.y;
const moved = Math.sqrt(mx**2 + my**2);
const elapsed = ev.timeStamp - data.current.time;
if (moved < opt.moveThreshold && elapsed < opt.pressDelay) {
// setTimeout(() => {
callback();
// }, 0);
}
}
}
}, [callback, options])
}
我遇到的问题是,当您点击它打开的图标并立即关闭全屏工具提示时。即,它打印
TAP!
CLOSE!!!
只需轻轻一按。
现在我知道了touchend
click
之前发生火灾,但我不明白为什么这很重要?如果你看看我的 {...onTap}
的位置和onClick={closeFullscreen}
管理员,他们是 sibling 。事件不应该以这种方式冒泡(无论是在 native DOM 中还是 React's VDOM ),而且我当然没有单击 <FullscreenTip>
。那么到底怎么样closeFullscreen
开火?
<End>
是一个门户。
最佳答案
尝试在 onTouchEnd
上调用 ev.preventDefault()
。
根据spec touchend
事件是“可取消”,这意味着您可以使用 .preventDefault()
来阻止鼠标事件。
If the preventDefault method is called on this event, it should prevent any default actions caused by any touch events associated with the same active touch point, including mouse events or scrolling.
关于javascript - 为什么不相关的元素会触发此点击事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60698406/