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

React JS移动端OnClick事件失效问题求助

移动端点击签名组件按钮无响应,仅点击外部区域生效

问题描述

验证签名时,电脑端点击组件的确认/取消按钮能正常触发onSet()/onCancel()函数,但平板/移动端点击按钮时函数无响应,只有点击按钮以外的签名区域时,相关点击逻辑才生效。需要实现移动端点击按钮也能触发对应函数。

相关代码

DraggableSignature组件

//DraggableSignature.js
import Draggable from "react-draggable";
import { FaCheck, FaTimes } from "react-icons/fa";
import { errorColor, goodColor, primary45 } from "../utils/colors";

export default function DraggableSignature({ url, onEnd, onSet, onCancel }) {
  const styles = {
    container: {
      position: "absolute",
      zIndex: 100000,
      border: `2px solid ${primary45}`,
    },
    controls: {
      position: "absolute",
      right: 0,
      display: "inline-block",
      backgroundColor: primary45,
      // borderRadius: 4,
    },
    smallButton: {
      display: "inline-block",
      cursor: "pointer",
      padding: 4,
    },
  };
  return (
    <Draggable onStop={onEnd}>
      <div style={styles.container}>
        <div style={styles.controls}>
          <button style={styles.smallbutton} onClick={onSet}>
            <FaCheck color={goodColor} />
          </button>
          <button style={styles.smallbutton} onClick={onCancel}>
            <FaTimes color={errorColor} />
          </button>
        </div>
        <img
          alt="signature"
          src={url}
          width={200}
          style={styles.img}
          draggable={false}
        />
      </div>
    </Draggable>
  );
}

App.js中组件调用代码

{signatureURL ? (
  <DraggableSignature
    url={signatureURL}
    onCancel={() => {
      setSignatureURL(null);
    }}
    onSet={async () => {
      const { originalHeight, originalWidth } = pageDetails;
      const scale =
        originalWidth / documentRef.current.clientWidth;

      const y =
        documentRef.current.clientHeight -
        (position.y -
          position.offsetY +
          64 -
          documentRef.current.offsetTop);
      const x =
        position.x -
        160 -
        position.offsetX -
        documentRef.current.offsetLeft;

      // new XY in relation to actual document size
      const newY =
        (y * originalHeight) / documentRef.current.clientHeight;
      const newX =
        (x * originalWidth) / documentRef.current.clientWidth;

      const pdfDoc = await PDFDocument.load(pdf);

      const pages = pdfDoc.getPages();
      const firstPage = pages[pageNum];

      const pngImage = await pdfDoc.embedPng(signatureURL);
      const pngDims = pngImage.scale(scale * 0.3);

      firstPage.drawImage(pngImage, {
        x: newX,
        y: newY,
        width: pngDims.width,
        height: pngDims.height,
      });

      if (autoDate) {
        firstPage.drawText(
          `Signé électroniquement le :${dayjs().format(
            "DD/MM/YYYY à HH:mm:ss"
          )}`,
          {
            x: newX,
            y: newY - 10,
            size: 14 * scale,
            color: rgb(0.074, 0.545, 0.262),
          }
        );
      }

      const pdfBytes = await pdfDoc.save();
      const blob = new Blob([newUint8Array(pdfBytes)]);

      const URL = await blobToURL(blob);
      setPdf(URL);
      setPosition(null);
      setSignatureURL(null);
    }}
    onEnd={setPosition}
  />
) : null}

已尝试的无效方案

  • 将按钮onClick事件替换为onTouchStart
  • 调整按钮位置样式
  • 更换CSS库

解决方案

问题根源是react-draggable会优先捕获移动端的触摸事件,导致按钮的点击事件被拦截。结合代码中的拼写错误,可通过以下方式修复:

1. 修正样式拼写错误 + 利用react-draggable内置忽略规则

代码中样式属性styles.smallbutton拼写错误(定义时为smallButton),会导致按钮样式失效,影响可点击区域。同时给按钮添加data-no-drag属性,让react-draggable忽略该元素的拖拽事件:

<button style={styles.smallButton} onClick={onSet} data-no-drag>
  <FaCheck color={goodColor} />
</button>
<button style={styles.smallButton} onClick={onCancel} data-no-drag>
  <FaTimes color={errorColor} />
</button>

2. 手动阻止事件冒泡

通过在按钮点击事件中阻止事件冒泡,避免react-draggable捕获事件:

<button 
  style={styles.smallButton} 
  onClick={(e) => {
    e.stopPropagation();
    onSet();
  }}
>
  <FaCheck color={goodColor} />
</button>
<button 
  style={styles.smallButton} 
  onClick={(e) => {
    e.stopPropagation();
    onCancel();
  }}
>
  <FaTimes color={errorColor} />
</button>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 04:57:02