React 极简响应式滑块验证组件实现,随机滑块位置

滑块验证组件 (Slider Captcha)

一个现代化、响应式的滑块验证组件,专为 React 应用设计,提供流畅的用户体验和强大的安全验证功能。

✨ 功能特性

核心功能

  • 智能滑块拖拽 – 支持鼠标和触摸屏操作,响应灵敏
  • 随机目标位置 – 每次验证生成不同的目标位置,提高安全性
  • 实时位置验证 – 精确的位置检测,支持容错范围设置
  • 状态反馈 – 清晰的视觉反馈,包括成功、错误和待验证状态

用户体验

  • 流畅动画 – 平滑的过渡动画和微交互效果
  • 响应式设计 – 完美适配桌面端和移动端
  • 直观界面 – 简洁美观的 UI 设计,操作简单明了
  • 即时反馈 – 实时显示验证状态和结果

技术特性

  • React Hooks – 使用最新的 React Hooks API
  • TypeScript 支持 – 完整的类型定义(可扩展)
  • Tailwind CSS – 现代化的样式框架
  • 事件处理 – 完善的鼠标和触摸事件处理
  • 性能优化 – 使用 useCallback 优化事件处理函数

产品亮点

  • 拖拽体验 – 滑块跟随鼠标/手指移动,提供真实的拖拽感
  • 视觉引导 – 绿色指示器显示目标位置,用户一目了然
  • 状态动画 – 成功时的庆祝动画,错误时的震动反馈
  • 触摸支持 – 完美支持移动端触摸操作
  • 响应式布局 – 自适应不同屏幕尺寸
  • 浏览器兼容 – 支持主流浏览器

使用场景

1. 用户注册/登录

  • 防止机器人注册 – 在用户注册时验证人类用户
  • 登录安全 – 在敏感操作前进行身份验证
  • 密码重置 – 重置密码流程中的安全验证

2. 表单提交

  • 评论系统 – 防止垃圾评论和恶意提交
  • 联系表单 – 保护网站免受垃圾邮件攻击
  • 调查问卷 – 确保问卷数据的真实性

3. 内容保护

  • 下载验证 – 下载敏感文件前的身份验证
  • 内容访问 – 访问付费或限制内容前的验证
  • API 调用 – 防止 API 接口被恶意调用

4. 电商应用

  • 下单验证 – 防止恶意下单和刷单行为
  • 优惠券领取 – 限制优惠券的领取频率
  • 评价系统 – 确保评价的真实性

5. 管理后台

  • 敏感操作 – 管理员执行危险操作前的确认
  • 数据导出 – 导出大量数据前的安全验证
  • 系统设置 – 修改关键系统设置时的验证

快速开始

使用组件

import SliderCaptcha from "./components/SliderCaptcha";

function App() {
  return (
    
); }

自定义配置

// 可以轻松扩展组件以支持自定义配置
const captchaConfig = {
  tolerance: 15, // 容错范围
  sliderWidth: 40, // 滑块宽度
  trackHeight: 48, // 轨道高度
  theme: "dark", // 主题样式
};

源码

import { useState, useRef, useEffect, useCallback } from "react";

export default function SliderCaptcha() {
  const [isVerified, setIsVerified] = useState(false);
  const [isDragging, setIsDragging] = useState(false);
  const [sliderPosition, setSliderPosition] = useState(0);
  const [startX, setStartX] = useState(0);
  const [targetPosition, setTargetPosition] = useState(0);
  const [showSuccess, setShowSuccess] = useState(false);
  const [showError, setShowError] = useState(false);

  const sliderRef = useRef(null);
  const trackRef = useRef(null);
  const containerRef = useRef(null);

  // 生成随机目标位置
  useEffect(() => {
    const container = containerRef.current;
    if (container) {
      const containerWidth = container.offsetWidth;
      const sliderWidth = 32; // 滑块宽度 (w-8 = 32px)
      const maxPosition = containerWidth - sliderWidth;
      const randomPosition = Math.random() * (maxPosition - 50) + 25; // 避免太靠近边缘
      setTargetPosition(randomPosition);
    }
  }, []);

  // 获取客户端坐标
  const getClientX = useCallback((e) => {
    return e.touches ? e.touches[0].clientX : e.clientX;
  }, []);

  // 鼠标/触摸事件处理
  const handleStart = useCallback(
    (e) => {
      if (isVerified) return;

      e.preventDefault();
      setIsDragging(true);
      setStartX(getClientX(e) - sliderPosition);
      setShowError(false);
    },
    [isVerified, sliderPosition, getClientX]
  );

  const handleMove = useCallback(
    (e) => {
      if (!isDragging || isVerified) return;

      e.preventDefault();
      const container = containerRef.current;
      if (!container) return;

      const containerWidth = container.offsetWidth;
      const sliderWidth = 32;
      const maxPosition = containerWidth - sliderWidth;

      let newPosition = getClientX(e) - startX;
      newPosition = Math.max(0, Math.min(newPosition, maxPosition));

      setSliderPosition(newPosition);
    },
    [isDragging, isVerified, startX, getClientX]
  );

  const handleEnd = useCallback(() => {
    if (!isDragging || isVerified) return;

    setIsDragging(false);

    // 验证滑块位置
    const tolerance = 10; // 允许的误差范围
    const isCorrect = Math.abs(sliderPosition - targetPosition) <= tolerance;

    if (isCorrect) {
      setIsVerified(true);
      setShowSuccess(true);
      setTimeout(() => setShowSuccess(false), 2000);
    } else {
      setShowError(true);
      // 重置滑块位置
      setTimeout(() => {
        setSliderPosition(0);
        setShowError(false);
      }, 1000);
    }
  }, [isDragging, isVerified, sliderPosition, targetPosition]);

  // 重置验证
  const handleReset = () => {
    setIsVerified(false);
    setIsDragging(false);
    setSliderPosition(0);
    setShowSuccess(false);
    setShowError(false);

    // 重新生成目标位置
    const container = containerRef.current;
    if (container) {
      const containerWidth = container.offsetWidth;
      const sliderWidth = 32;
      const maxPosition = containerWidth - sliderWidth;
      const randomPosition = Math.random() * (maxPosition - 50) + 25;
      setTargetPosition(randomPosition);
    }
  };

  // 添加全局鼠标/触摸事件监听
  useEffect(() => {
    if (isDragging) {
      document.addEventListener("mousemove", handleMove);
      document.addEventListener("mouseup", handleEnd);
      document.addEventListener("touchmove", handleMove, { passive: false });
      document.addEventListener("touchend", handleEnd);

      return () => {
        document.removeEventListener("mousemove", handleMove);
        document.removeEventListener("mouseup", handleEnd);
        document.removeEventListener("touchmove", handleMove);
        document.removeEventListener("touchend", handleEnd);
      };
    }
  }, [isDragging, handleMove, handleEnd]);

  return (
    

滑块验证

{isVerified ? "✅ 验证成功!" : "请将滑块拖拽到正确位置完成验证"}

{/* 验证区域 */}
{/* 背景图片或图案 */}
{/* 目标位置指示器 */}
{/* 滑块轨道 */}
{/* 滑块 */} {!isVerified && (
)} {/* 成功提示 */} {showSuccess && (
验证成功!
)} {/* 错误提示 */} {showError && (
位置错误,请重试
)}
{/* 操作按钮 */}
{isVerified && ( )}
{/* 状态指示器 */}
{isVerified ? ( <>
已验证 ) : ( <>
待验证 )}
); }

 React 极简响应式滑块验证组件实现,随机滑块位置 - 高质量源码分享平台-免费下载各类网站源码与模板及前沿动态资讯

你可能感兴趣的:(react.js,前端,前端框架,javascript,ecmascript,react,开源)