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

Web端能否实现全局鼠标点击追踪?适配React与屏幕录制场景

Web端实现全局鼠标点击追踪与录制高亮方案

注意:普通网页受浏览器沙箱安全限制,无法直接捕获浏览器外的系统级鼠标事件——这是不可绕过的安全规则。但结合你的屏幕录制需求,有三种可行的实现路径:

1. 纯Web方案:依托桌面共享API实现近似追踪

当用户开启屏幕录制时,通过MediaDevices.getDisplayMedia()获取桌面共享流,以此实现点击追踪与高亮:

  • 在共享视频流的预览层上叠加透明悬浮层,监听悬浮层的点击事件(用户点击屏幕时,实际点击的是预览流上的悬浮层)
  • 记录点击相对于预览流的比例坐标,回放时按比例映射到实际屏幕尺寸
  • 录制时将悬浮层上的点击高亮动画(比如脉冲圆圈)一同纳入录制流

React核心实现代码示例:

import { useState, useRef } from 'react';

const ScreenRecorder = () => {
  const [captureStream, setCaptureStream] = useState(null);
  const videoRef = useRef(null);
  const overlayRef = useRef(null);
  const [clickHistory, setClickHistory] = useState([]);

  // 启动桌面捕获
  const startCapture = async () => {
    try {
      const stream = await navigator.mediaDevices.getDisplayMedia({ video: true });
      setCaptureStream(stream);
      videoRef.current.srcObject = stream;
    } catch (err) {
      console.error('桌面捕获失败:', err);
    }
  };

  // 处理点击,记录坐标并生成高亮
  const handleOverlayClick = (e) => {
    const videoRect = videoRef.current.getBoundingClientRect();
    // 计算相对视频流的比例坐标,适配不同屏幕尺寸
    const relativeX = (e.clientX - videoRect.left) / videoRect.width;
    const relativeY = (e.clientY - videoRect.top) / videoRect.height;
    
    const clickRecord = { x: relativeX, y: relativeY, time: Date.now() };
    setClickHistory(prev => [...prev, clickRecord]);
    
    // 创建点击高亮元素
    const highlight = document.createElement('div');
    Object.assign(highlight.style, {
      position: 'absolute',
      left: `${e.clientX - videoRect.left - 25}px`,
      top: `${e.clientY - videoRect.top - 25}px`,
      width: '50px',
      height: '50px',
      border: '3px solid #ff3838',
      borderRadius: '50%',
      pointerEvents: 'none',
      animation: 'clickPulse 0.6s ease-out forwards'
    });
    overlayRef.current.appendChild(highlight);
    setTimeout(() => highlight.remove(), 600);
  };

  // 回放逻辑示例:根据记录的坐标生成高亮
  const replayClicks = () => {
    clickHistory.forEach(click => {
      setTimeout(() => {
        const videoRect = videoRef.current.getBoundingClientRect();
        const absX = click.x * videoRect.width;
        const absY = click.y * videoRect.height;
        const highlight = document.createElement('div');
        Object.assign(highlight.style, {
          position: 'absolute',
          left: `${absX - 25}px`,
          top: `${absY - 25}px`,
          width: '50px',
          height: '50px',
          border: '3px solid #2ed573',
          borderRadius: '50%',
          pointerEvents: 'none',
          animation: 'clickPulse 0.6s ease-out forwards'
        });
        overlayRef.current.appendChild(highlight);
        setTimeout(() => highlight.remove(), 600);
      }, click.time - clickHistory[0].time);
    });
  };

  return (
    <div style={{ position: 'relative', width: '100%', height: '100vh' }}>
      <video 
        ref={videoRef} 
        autoPlay 
        playsInline 
        style={{ width: '100%', height: '100%', objectFit: 'contain' }}
      />
      {/* 透明点击捕获层 */}
      <div 
        ref={overlayRef}
        onClick={handleOverlayClick}
        style={{ 
          position: 'absolute', 
          top: 0, 
          left: 0, 
          width: '100%', 
          height: '100%', 
          pointerEvents: 'auto' 
        }}
      />
      <div style={{ position: 'fixed', bottom: '20px', left: '20px' }}>
        <button onClick={startCapture} style={{ marginRight: '10px' }}>开始录制</button>
        <button onClick={replayClicks}>回放点击</button>
      </div>
    </div>
  );
};

export default ScreenRecorder;

配套CSS动画:

@keyframes clickPulse {
  0% { transform: scale(1); opacity: 1; }
  100% { transform: scale(2.5); opacity: 0; }
}

这种方案的局限是必须依赖用户开启桌面共享,点击追踪仅在预览流窗口内生效,但完全符合浏览器安全规范,无需额外权限。

2. 浏览器扩展方案:实现真正的全局点击追踪

如果必须捕获浏览器外的系统级鼠标事件,只能通过浏览器扩展实现:

  • 扩展申请系统输入权限,直接监听全局鼠标点击事件
  • 通过扩展与网页的消息通信,将点击坐标传递给你的React应用
  • 录制时结合坐标在视频流上叠加高亮效果

该方案需要开发并让用户安装扩展,能实现真正的全局追踪,但增加了额外的开发和推广成本。

3. Electron兼容Web方案:复用原有逻辑

如果你的“Web端”是指运行在Electron中的Web应用(而非纯浏览器环境),可以直接沿用iohook库:

  • Electron允许调用Node.js模块,无需修改核心追踪逻辑
  • 仅需适配React的状态管理,将捕获的点击事件同步到组件状态中即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 06:35:07