一个现代化、响应式的滑块验证组件,专为 React 应用设计,提供流畅的用户体验和强大的安全验证功能。
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 极简响应式滑块验证组件实现,随机滑块位置 - 高质量源码分享平台-免费下载各类网站源码与模板及前沿动态资讯