You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React横向滚动菜单onClick事件无法触发问题求助

问题原因分析
  1. 事件绑定错误:ScrollMenu上的onMouseDown={() => dragStart}和onMouseUp={() => dragStop}写法错误,仅返回函数未执行,导致拖拽逻辑的状态(clicked、dragging)无法正确更新,进而干扰点击事件判断。
  2. 点击事件被拖拽逻辑误拦截:即使修正绑定后,若未在点击逻辑中区分「纯点击」和「拖拽结束后的误触」,也会导致正常点击被阻止。
解决方案

1. 修正ScrollMenu的事件绑定

先创建ref获取ScrollMenu实例,同时修正事件绑定,确保拖拽函数能接收事件对象并执行:

import React from 'react';
import { ScrollMenu } from 'react-horizontal-scrolling-menu';

const YourComponent = () => {
  const scrollMenuRef = React.useRef(null);
  // ... 其他状态和拖拽逻辑

  // 处理滚动的回调
  const handleScrollBy = (diff) => {
    scrollMenuRef.current?.scrollBy(diff);
  };

  return (
    <ScrollMenu
      LeftArrow={LeftArrow}
      RightArrow={RightArrow}
      onWheel={onWheel}
      onMouseDown={dragStart} // 直接绑定函数,自动传递事件
      onMouseUp={dragStop}
      onMouseMove={(e) => dragMove(e, handleScrollBy)} // 传递事件和滚动回调
      ref={scrollMenuRef}
    >
      {items.map(({ id }) => (
        <Card
          title={id}
          itemId={id}
          key={id}
          onClick={handleItemClick(id)}
          selected={id === selected}
        />
      ))}
    </ScrollMenu>
  );
};

2. 调整拖拽逻辑,精准区分点击与拖拽

修改dragMove和dragStop,确保只有鼠标移动超过阈值时才标记为拖拽状态:

const [clicked, setClicked] = React.useState(false);
const [dragging, setDragging] = React.useState(false);
const position = React.useRef(0);

const dragStart = React.useCallback((ev) => {
  position.current = ev.clientX;
  setClicked(true);
  setDragging(false); // 初始化为未拖拽状态
}, []);

const dragStop = React.useCallback(() => {
  // 用requestAnimationFrame延迟重置状态,避免拖拽结束后误触点击
  window.requestAnimationFrame(() => {
    setClicked(false);
    setDragging(false);
  });
}, []);

const dragMove = React.useCallback((ev, cb) => {
  if (!clicked) return;
  
  const newDiff = position.current - ev.clientX;
  const movedEnough = Math.abs(newDiff) > 5;

  if (movedEnough) {
    setDragging(true);
  }

  if (dragging && movedEnough) {
    position.current = ev.clientX;
    cb(newDiff);
  }
}, [clicked, dragging]);

3. 在Card的点击逻辑中添加拖拽判断

确保只有纯点击(未触发拖拽)时才执行跳转逻辑:

const handleItemClick = (id) => () => {
  if (!dragging) {
    // 这里写入你的跳转或点击逻辑
    console.log('触发正常点击:', id);
    // navigate(`/your-target-path/${id}`);
  }
};

额外注意事项

  • 确认Card组件的onClick是返回函数的形式(你的当前写法是正确的,handleItemClick(id)返回一个函数)。
  • 若Card内部的CTA按钮也有独立点击事件,同样需要添加!dragging的判断,避免拖拽过程中误触。

内容的提问来源于stack exchange,提问作者shubham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 22:51:04