React中如何禁止图片元素长按触发onClick点击事件
问题解决思路
原生onClick事件默认不区分按压时长,只要指针在元素上按下后再松开,无论按压多久都会触发,要过滤长按场景的触发,需要手动通过按压时间差判断点击类型,替换原生点击事件的绑定逻辑。
具体实现方案
核心逻辑是通过监听按压开始、结束的事件,计算按压持续时长,仅当时长小于设定的长按阈值时,才执行短按对应的业务逻辑:
- 按压开始时(监听
mousedown/touchstart事件),记录起始状态,同时启动定时器,达到设定的长按阈值后,将长按标记置为true - 按压结束时(监听
mouseup/touchend事件),清除定时器,判断长按标记,若为false则执行短按逻辑 - 按压过程中指针移出元素、事件被打断时(监听
mouseleave/touchcancel事件),清除定时器重置状态,避免误判
可直接复用的React实现代码
import React, { useRef, useCallback } from 'react'; import './style.css'; // 长按阈值,单位:毫秒,需要拦截2秒长按就设为2000 const LONG_PRESS_THRESHOLD = 2000; export default function App() { const pressTimer = useRef(null); const isLongPress = useRef(false); // 按压开始逻辑 const handlePressStart = useCallback(() => { isLongPress.current = false; pressTimer.current = setTimeout(() => { isLongPress.current = true; }, LONG_PRESS_THRESHOLD); }, []); // 按压结束逻辑 const handlePressEnd = useCallback(() => { if (pressTimer.current) { clearTimeout(pressTimer.current); pressTimer.current = null; } // 仅非长按时执行点击逻辑 if (!isLongPress.current) { console.log('You clicked me!'); // 此处替换为你的短按业务逻辑 } }, []); // 按压中断重置逻辑 const handlePressCancel = useCallback(() => { if (pressTimer.current) { clearTimeout(pressTimer.current); pressTimer.current = null; } isLongPress.current = false; }, []); return ( <div> <h1>Try on Google Chrome Desktop</h1> <p>Open the console log to see how the event gets triggered.</p> <p>The event should not get triggered if there is a long click.</p> <img src="https://via.placeholder.com/200.png/09f/fff" // 桌面端事件 onMouseDown={handlePressStart} onMouseUp={handlePressEnd} onMouseLeave={handlePressCancel} // 移动端兼容事件 onTouchStart={handlePressStart} onTouchEnd={handlePressEnd} onTouchCancel={handlePressCancel} // 阻止长按弹出系统右键菜单,按需开启 onContextMenu={(e) => e.preventDefault()} /> </div> ); }
注意事项
- 不要尝试在原生
onClick回调里做长按判断,因为长按松开后原生click事件必然触发,无法从事件本身区分按压时长 - 定时器id、长按标记使用
useRef存储,不会触发组件重渲染,性能优于useState - 长按阈值可根据业务需求调整,通用交互场景下默认500ms即可识别为长按
- 同时绑定鼠标、触摸事件可同时兼容桌面端、移动端的交互场景
内容的提问来源于stack exchange,提问作者Viewsonic
相关产品推荐
相关产品推荐

