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 (<div className="App"><SliderCaptcha /></div>);
}

自定義配置

// 可以輕松擴展組件以支持自定義配置
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 (<div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100 flex items-center justify-center p-4"><div className="bg-white rounded-2xl shadow-xl p-8 max-w-md w-full"><h2 className="text-2xl font-bold text-gray-800 mb-6 text-center">滑塊驗證</h2><div className="mb-6"><p className="text-gray-600 text-center mb-4">{isVerified ? "? 驗證成功!" : "請將滑塊拖拽到正確位置完成驗證"}</p></div>{/* 驗證區域 */}<divref={containerRef}className="relative bg-gray-100 rounded-lg h-12 mb-6 overflow-hidden">{/* 背景圖片或圖案 */}<div className="absolute inset-0 bg-gradient-to-r from-blue-200 to-purple-200 opacity-30"></div>{/* 目標位置指示器 */}<divclassName="absolute top-1 bottom-1 w-2 bg-green-600 rounded-lg shadow ring-2 ring-green-300 transition-opacity duration-300"style={{left: `${targetPosition}px`,opacity: isVerified ? 0 : 1,}}></div>{/* 滑塊軌道 */}<divref={trackRef}className="absolute top-0 bottom-0 left-0 bg-blue-500 transition-all duration-300 ease-out"style={{width: `${sliderPosition}px`,opacity: isVerified ? 0.8 : 0.6,}}></div>{/* 滑塊 */}{!isVerified && (<divref={sliderRef}className={`absolute top-1 bottom-1 w-8 bg-white rounded-md shadow-lg cursor-pointer transition-all duration-200 ease-out flex items-center justify-center${isDragging ? "shadow-xl scale-105" : ""}hover:shadow-lg${showError ? "animate-shake" : ""}`}style={{ left: `${sliderPosition}px` }}onMouseDown={handleStart}onTouchStart={handleStart}><svgclassName="w-4 h-4 text-gray-500"fill="currentColor"viewBox="0 0 20 20"><pathfillRule="evenodd"d="M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z"clipRule="evenodd"/></svg></div>)}{/* 成功提示 */}{showSuccess && (<div className="absolute inset-0 bg-green-500 bg-opacity-20 flex items-center justify-center"><div className="bg-white rounded-lg px-4 py-2 shadow-lg"><span className="text-green-600 font-semibold">驗證成功!</span></div></div>)}{/* 錯誤提示 */}{showError && (<div className="absolute inset-0 bg-red-500 bg-opacity-20 flex items-center justify-center"><div className="bg-white rounded-lg px-4 py-2 shadow-lg"><span className="text-red-600 font-semibold">位置錯誤,請重試</span></div></div>)}</div>{/* 操作按鈕 */}<div className="flex gap-4"><buttononClick={handleReset}className="flex-1 bg-gray-500 hover:bg-gray-600 text-white font-semibold py-3 px-6 rounded-lg transition-colors duration-200">重置驗證</button>{isVerified && (<buttononClick={() => alert("驗證通過,可以繼續操作!")}className="flex-1 bg-green-500 hover:bg-green-600 text-white font-semibold py-3 px-6 rounded-lg transition-colors duration-200">繼續</button>)}</div>{/* 狀態指示器 */}<div className="mt-4 text-center"><div className="inline-flex items-center gap-2 px-3 py-1 rounded-full text-sm">{isVerified ? (<><div className="w-2 h-2 bg-green-500 rounded-full"></div><span className="text-green-600">已驗證</span></>) : (<><div className="w-2 h-2 bg-yellow-500 rounded-full animate-pulse"></div><span className="text-yellow-600">待驗證</span></>)}</div></div></div></div>);
}

?React 極簡響應式滑塊驗證組件實現,隨機滑塊位置 - 高質量源碼分享平臺-免費下載各類網站源碼與模板及前沿動態資訊

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/913363.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/913363.shtml
英文地址,請注明出處:http://en.pswp.cn/news/913363.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

STM32第十六天藍牙模塊

一&#xff1a;藍牙模塊HC-05 1&#xff1a;硬件引腳配置&#xff1a; | 標號 | PIN | 說明 | |------|-------|---------------------------------------| | 1 | START | 狀態引出引腳&#xff08;未連接/連接輸出信號時&#xff09; |…

時序數據庫IoTDB用戶自定義函數(UDF)使用指南

1. 編寫UDF時序數據庫IoTDB為用戶提供了編寫UDF的JAVA API&#xff0c;用戶可以自主實現UDTF&#xff08;用戶自定義轉換函數&#xff09;類&#xff0c;IoTDB將通過類加載機制裝載用戶編寫的類。Maven依賴如果使用Maven&#xff0c;可以從Maven庫中搜索以下依賴&#xff0c;并…

Linux國產與國外進度對壘

Linux國產與國外進度對壘 引言國產Linux的發展現狀國外Linux的發展現狀技術對比國產Linux的挑戰與機遇國外Linux的優勢與局限結論 引言 簡述Linux在全球操作系統市場中的地位國產Linux的發展背景與意義國外主流Linux發行版的現狀 國產Linux的發展現狀 主要國產Linux發行版介…

Jenkins-Email Extension 插件插件

Editable Email Notification Editable Email Notification 是 Jenkins 的 Email Extension 插件的核心功能&#xff0c;用于自定義郵件通知&#xff0c;包括郵件主題、內容、收件人、發件人等 屬性 1.Project From 項目發件人&#xff0c;設置郵件的發件人地址 **注意&…

windows系統下將Docker Desktop安裝到除了C盤的其它盤中

windows系統下安裝docker會自動安裝到C盤&#xff0c;可以采用下面的方法將其安裝到其它盤中1、先下載Docker Desktop安裝程序Docker Desktop Installer.exe&#xff0c;比如你下載到了C:\Users\YourUsername\Downloads 文件夾中。 2、打開 PowerShell 進入C:\Users\YourUser…

視頻工具箱 1.1.1 |小而美的視頻處理工具,支持多種常用功能

VideoTools是一款基于FFmpeg的小而美的視頻處理工具&#xff0c;專為需要快速高效地進行視頻編輯的用戶設計。這款工具無需安裝&#xff0c;體積僅約200KB&#xff0c;提供了視頻壓縮、格式轉換、轉GIF、修改分辨率、加速播放以及音頻提取等多種常用功能。其用戶界面簡潔直觀&a…

無人機集群搜索技術全面解析

無人機集群搜索是指通過多架無人機協同工作&#xff0c;實現對目標區域的高效覆蓋與快速探測。這項技術通過模擬自然界生物群體的集體行為&#xff0c;利用分布式控制和自主決策算法&#xff0c;使無人機集群能夠自組織地完成復雜搜索任務。下面從核心技術、應用場景、算法實現…

【Elasticsearch】深度分頁及其替代方案

深度分頁及其替代方案 1.深度分頁2.為什么不推薦深度分頁2.1 性能問題&#xff08;核心原因&#xff09;2.2 資源消耗對比2.3 實際限制 3.深度分頁的替代方案3.1 方案一&#xff1a;Search After&#xff08;推薦&#xff09;3.1.1 為什么 Search After 性能更高3.1.2 技術原理…

論文閱讀筆記——VGGT: Visual Geometry Grounded Transformer

VGGT 論文 輸入是 N 個 RGB 圖像 I i ∈ R 3 H W I_i\in\mathbb{R}^{3HW} Ii?∈R3HW 的序列 ( I i ) i 1 N (I_i)^N_{i1} (Ii?)i1N?&#xff0c;觀察相同 3D 場景。 VGGT 的 Transformer 是一個映射函數&#xff0c;將此序列映射為一組對應的 3D 標注&#xff0c; f ( …

【嵌入式電機控制#11】PID控制入門:對比例算法應用的深度理解

接下來內容需要數學功底&#xff0c;并且有現成結論的內容不做推導&#xff0c;重在講解工程實踐中的方法論&#xff0c;建議控制類專業或學習過相關理論的人閱讀 一、開閉環系統 &#xff08;1&#xff09;開環控制系統&#xff1a;被控對象輸出對控制器的輸出沒有影響 &…

多視圖幾何:本質矩陣與基礎矩陣

文章目錄 1. 前置知識1.1. 向量叉乘1.2. 混合積1.3. 引理證明 2. 本質矩陣3. 基礎矩陣4. 應用例子 1. 前置知識 1.1. 向量叉乘 假設 a ( a x a y a z ) \mathbf{a} \begin{pmatrix} a_x \\ a_y \\ a_z \end{pmatrix} a ?ax?ay?az?? ? 以及 b ( b x b y b z ) \mat…

Hive集群之間遷移的Linux Shell腳本

新舊 Hive 集群之前數據遷移單表腳本 migrate_hive_single_table.sh #!/bin/bash#配置參數 OLD_NAMENODE"hdfs://<old-namenode>:<old-port>" EXPORT_PATH"/tmp/hive-export/dm" NEW_DB"dm_events" TABLE_NAME"dm_usereventfi…

新時代的開始,華為開源倉頡編程語言!

7月30日&#xff0c;華為即將開源自研的倉頡編程語言。 倉頡這個名字很有意思。傳說中的倉頡創造了漢字&#xff0c;開啟了中華文明的文字時代。華為用這個名字&#xff0c;體現了對中華文化的致敬。從2020年開始研發&#xff0c;到去年首次亮相&#xff0c;再到現在的全面開源…

【python實用小腳本-128】基于 Python 的 Hacker News 爬蟲工具:自動化抓取新聞數據

引言 在技術社區中&#xff0c;Hacker News 是一個匯聚最新技術文章和討論的熱門平臺。許多開發者和技術愛好者依賴它來獲取行業動態和前沿資訊。然而&#xff0c;手動瀏覽和篩選這些文章可能耗時且低效。本文將介紹一個基于 Python 的 Hacker News 爬蟲工具&#xff0c;它能夠…

mac 電腦安裝Homebrew來安裝npm與node成功后,安裝nvm的流程

文章目錄 前言一、卸載node(如果沒下載可以忽略這步)1.官網下載安裝包的2. homebrew安裝的 二、安裝Homebrew(1) 命令安裝&#xff08;2&#xff09;出現上面提示&#xff0c;執行對應的命令&#xff08;3&#xff09;校驗是否安裝成功 三&#xff1a;安裝node&#xff08;Home…

根據無人機傾斜攝影osgb做的3dmax模型3dtiles制作,導出.b3dm加載到谷歌地圖cesiumlab

根據無人機傾斜攝影osgb做的3dmax模型3dtiles制作&#xff0c;導出.b3dm加載到谷歌地圖cesiumlab 根據無人機傾斜攝影osgb做的3dmax模型3dtiles制作&#xff0c;導出.b3dm加載到谷歌地圖cesiumlab

Yocto項目:嵌入式Linux開發的“萬能烹飪手冊”

目錄 一.Yocto是什么? 二.Yocto如何運作&#xff1f; 2.1 三大核心工具 2.2 實例 三.為什么開發者愛用Yocto&#xff1f; 3.1 ?自由定制&#xff0c;拒絕“全家桶”?? 3.2 跨平臺支持&#xff1a;從x86到火星芯片? 3.3 工業級可靠性? PetaLinux是Xilinx官方推出的…

【nosql】有哪些非關系型數據庫?

非關系型數據庫Nosql 分類 鍵值存儲 (Key-Value Store): 代表: Redis, DynamoDB, RocksDB, etcd核心優勢: 極致簡單、超高讀寫性能&#xff08;尤其內存型&#xff09;、高吞吐。場景: 緩存、會話存儲、配置、計數器、分布式協調、簡單消息隊列。 列式 / 寬列存儲 (Wide-Colu…

Redis存儲Cookie實現爬蟲保持登錄 requests | selenium

前言 前面已經介紹了requests和selenium這兩種方式的基礎知識和模擬登錄,但是我們需要每次都進行登錄,這明顯是很麻煩并且不合理的,所以這次我分享一下怎么可以讓我們的程序進行一次登錄之后,和普通瀏覽器一樣下次不進行登錄直接進行對網站數據的爬取 下面的我分享的內容需要…

leetcode:474. 一和零[01背包][動態規劃]

學習要點 給定背包容量&#xff0c;裝滿背包最多有多少個物品深入理解01背包深入理解動態規劃 題目鏈接 474. 一和零 - 力扣&#xff08;LeetCode&#xff09; 題目描述 解法:01背包 class Solution { public:int findMaxForm(vector<string>& strs, int m, int …