使用 HTML + JavaScript 实现滑动验证码

使用 HTML + JavaScript 实现滑动验证码

文章目录

一、滑动验证码

在现代网络安全体系中,人机验证机制扮演着至关重要的角色。传统的文本验证码由于识别困难、用户体验差等问题逐渐被更先进的验证方式取代。滑动验证码作为一种新型的人机验证手段,凭借其直观的操作体验和良好的安全性,广泛应用于各类网站和应用程序中。本文将详细介绍如何使用 HTML、CSS 和 JavaScript 构建一个完整的滑动验证码系统。

二、效果演示

滑动验证码的核心交互流程包括图像加载、拼图生成、用户拖拽和验证判断四个阶段,用户通过拖拽右侧滑块向右移动,使拼图块与背景图像中的缺口对齐,验证成功时显示绿色成功提示,失败则显示红色错误信息并自动重置。

在这里插入图片描述


在这里插入图片描述
在这里插入图片描述

三、系统分析

1、页面结构

整个滑动验证码系统采用简洁清晰的 HTML 结构设计,主要包括图像显示区(verify-img)、滑动控制区(erify-bar-box)和结果显示区(verify-result)三个核心部分。

<divclass="verify-container"><divclass="verify-box"><divclass="verify-img"><imgclass="back-img"src=""style="width:100%;height:100%;"/><divclass="loading-indicator"id="backImgLoading"style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#666;font-size:14px;display:none;">加载中...</div></div><divclass="verify-bar-box"><spanclass="verify-msg">向右滑动完成验证</span><divclass="verify-left-bar"></div><divclass="verify-move-block"><span>&gt;</span><divclass="verify-sub-block"><imgclass="block-img"src=""style="width:100%;height:100%;"/></div></div></div></div><divclass="verify-result"id="verifyResult"></div></div>

2、核心功能实现

2.1 初始化流程

主要实现了随机位置生成、图像加载和拼图绘制三个步骤。

asyncfunctioninit(){// 显示加载指示器showLoading() targetX = Math.floor(Math.random()*(imgWidth - bolckSize -60))+30; targetY = Math.floor(Math.random()*(imgHeight - bolckSize -20))+10;var img =awaitloadImg(imgUrl+'?'+Math.random());// 创建背景画布并绘制带缺口的图像var backCanvas = document.createElement('canvas') backCanvas.width = imgWidth; backCanvas.height = imgHeight;var backCtx = backCanvas.getContext('2d'); backCtx.drawImage(img,0,0,380,190,0,0, imgWidth, imgHeight); backCtx.fillStyle ='#FFFFFF'; backCtx.fillRect(targetX, targetY,50,50); backImg.src = backCanvas.toDataURL('image/png');// 创建拼图块var canvas = document.createElement('canvas') canvas.width =50; canvas.height =50;var ctx = canvas.getContext('2d'); ctx.drawImage(img, targetX, targetY, bolckSize, bolckSize,0,0, bolckSize, bolckSize) blockImg.src = canvas.toDataURL('image/png'); subBlock.style.top =(-201+ targetY)+'px';// 隐藏加载指示器hideLoading()}

2.2 拖拽交互处理

通过鼠标事件监听实现流畅的拖拽体验,当用户在滑块上按下鼠标并移动时,滑块滑块会随鼠标移动;当用户释放鼠标时,进行位置校验,如果失败滑块会变为红色并平滑的回到起点位置。

// 鼠标按下事件 - 开始拖拽 moveBlock.addEventListener('mousedown',function(e){ isDragging =true; startX = e.clientX; moveBlock.style.backgroundColor ='#337AB7'; moveBlock.style.color ='#FFFFFF'; verifyLeftBar.style.border ='1px solid #337AB7';});// 鼠标移动事件 - 拖拽过程 document.addEventListener('mousemove',function(e){if(!isDragging)return;var newLeft = e.clientX - startX -2;// 限制滑块移动范围if(newLeft <0) newLeft =0;if(newLeft > maxWidth) newLeft = maxWidth; moveBlock.style.left = newLeft +'px'; verifyLeftBar.style.width = newLeft +'px'; verifyLeftBar.style.border ='1px solid #337AB7';});// 鼠标释放事件 - 结束拖拽 document.addEventListener('mouseup',function(){if(!isDragging)return; isDragging =false;var currentPosition = moveBlock.offsetLeft;if(Math.abs(currentPosition - targetX)<= tolerance){ moveBlock.style.backgroundColor ='#5CB85C'; moveBlock.style.color ='#FFFFFF'; verifyLeftBar.style.border ='1px solid #5CB85C';// 显示成功提示 verifyResult.textContent ='验证成功!'; verifyResult.className ='verify-result success';return;} moveBlock.style.backgroundColor ='#D9534F'; moveBlock.style.color ='#FFFFFF'; verifyLeftBar.style.border ='1px solid #D9534F'; verifyLeftBar.style.backgroundColor ='#fff0f0';// 显示失败提示 verifyResult.textContent ='验证失败,请重试'; verifyResult.className ='verify-result fail';// 滑块回弹动画 moveBlock.style.transition ='left 0.8s'; moveBlock.style.left ='0px'; verifyLeftBar.style.transition ='width 0.8s'; verifyLeftBar.style.width ='0px';// 动画结束后清除过渡效果setTimeout(()=>{init() moveBlock.style.transition =''; verifyLeftBar.style.transition =''; moveBlock.style.backgroundColor ='#FFFFFF'; moveBlock.style.color ='#999'; verifyLeftBar.style.backgroundColor ='#F0FFF0';// 清除验证结果提示 verifyResult.className ='verify-result';},800);});

四、扩展建议

  • 添加服务器端验证,防止客户端伪造结果
  • 增加行为特征检测,识别自动化工具攻击
  • 添加个性化拼图形状设计,丰富视觉表现
  • 增加重试次数限制机制,防止无限重试

五、完整代码

<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>滑动验证码</title><style>*{margin: 0;padding: 0;box-sizing: border-box;}body{background: #f5f5f5;}.container{display: flex;padding: 20px;justify-content: center;}.verify-container{background: #fff;width:400px;padding: 10px;border: 1px solid #ddd;user-select: none;}.verify-img{width: 380px;height: 190px;margin-bottom: 10px;position: relative;}.verify-bar-box{width: 380px;height: 50px;line-height: 50px;position: relative;background: #FFFFFF;text-align: center;box-sizing: content-box;border: 1px solid #ddd;border-radius: 4px;color: #999;}.verify-left-bar{background: #f0fff0;position: absolute;top: 0;left: 0;height: 50px;}.verify-move-block{position: absolute;top: 0;left: 0;background: #fff;cursor: pointer;box-sizing: content-box;box-shadow: 0 0 2px #888888;border-radius: 1px;width: 50px;height: 50px;}.verify-sub-block{position: absolute;border: 1px solid #ddd;height: 50px;left: -2px;top: -201px;}.verify-result{margin-top: 10px;padding: 8px 12px;text-align: center;border-radius: 4px;font-weight: bold;display: none;}.verify-result.success{background-color: #dff0d8;color: #3c763d;border: 1px solid #d6e9c6;display: block;}.verify-result.fail{background-color: #f2dede;color: #a94442;border: 1px solid #ebccd1;display: block;}.loading-indicator{padding: 5px 10px;border-radius: 4px;}</style></head><body><divclass="container"><divclass="verify-container"><divclass="verify-box"><divclass="verify-img"><imgclass="back-img"src=""style="width:100%;height:100%;"/><divclass="loading-indicator"id="backImgLoading"style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#666;font-size:14px;display:none;">加载中...</div></div><divclass="verify-bar-box"><spanclass="verify-msg">向右滑动完成验证</span><divclass="verify-left-bar"></div><divclass="verify-move-block"><span>&gt;</span><divclass="verify-sub-block"><imgclass="block-img"src=""style="width:100%;height:100%;"/></div></div></div></div><divclass="verify-result"id="verifyResult"></div></div></div><script>var verifyBarBox = document.querySelector('.verify-bar-box');var moveBlock = document.querySelector('.verify-move-block');var verifyLeftBar = document.querySelector('.verify-left-bar');var backImg = document.querySelector('.back-img');var subBlock = document.querySelector('.verify-sub-block');var blockImg = document.querySelector('.block-img');var verifyResult = document.getElementById('verifyResult');var backImgLoading = document.getElementById('backImgLoading');var startX =0;var isDragging =false;var maxWidth = verifyBarBox.offsetWidth - moveBlock.offsetWidth;var imgUrl ='https://picsum.photos/380/190';var imgWidth =380;var imgHeight =190;var bolckSize =50;var targetX =0;var targetY =0;var tolerance =5;init();asyncfunctioninit(){// 显示加载指示器showLoading() targetX = Math.floor(Math.random()*(imgWidth - bolckSize -60))+30; targetY = Math.floor(Math.random()*(imgHeight - bolckSize -20))+10;var img =awaitloadImg(imgUrl+'?'+Math.random());// 创建背景画布并绘制带缺口的图像var backCanvas = document.createElement('canvas') backCanvas.width = imgWidth; backCanvas.height = imgHeight;var backCtx = backCanvas.getContext('2d'); backCtx.drawImage(img,0,0,380,190,0,0, imgWidth, imgHeight); backCtx.fillStyle ='#FFFFFF'; backCtx.fillRect(targetX, targetY,50,50); backImg.src = backCanvas.toDataURL('image/png');// 创建拼图块var canvas = document.createElement('canvas') canvas.width =50; canvas.height =50;var ctx = canvas.getContext('2d'); ctx.drawImage(img, targetX, targetY, bolckSize, bolckSize,0,0, bolckSize, bolckSize) blockImg.src = canvas.toDataURL('image/png'); subBlock.style.top =(-201+ targetY)+'px';// 隐藏加载指示器hideLoading()}functionshowLoading(){ backImgLoading.style.display ='block'; subBlock.style.display ='none' backImg.style.display ='none'}functionhideLoading(){ backImgLoading.style.display ='none'; subBlock.style.display ='block' backImg.style.display ='block'}// 绘制拼图块functionloadImg(url){returnnewPromise((res,rej)=>{const im =newImage(); im.crossOrigin='anonymous'; im.onload=()=>res(im); im.onerror= rej; im.src = url;});}// 鼠标按下事件 - 开始拖拽 moveBlock.addEventListener('mousedown',function(e){ isDragging =true; startX = e.clientX; moveBlock.style.backgroundColor ='#337AB7'; moveBlock.style.color ='#FFFFFF'; verifyLeftBar.style.border ='1px solid #337AB7';});// 鼠标移动事件 - 拖拽过程 document.addEventListener('mousemove',function(e){if(!isDragging)return;var newLeft = e.clientX - startX -2;// 限制滑块移动范围if(newLeft <0) newLeft =0;if(newLeft > maxWidth) newLeft = maxWidth; moveBlock.style.left = newLeft +'px'; verifyLeftBar.style.width = newLeft +'px'; verifyLeftBar.style.border ='1px solid #337AB7';});// 鼠标释放事件 - 结束拖拽 document.addEventListener('mouseup',function(){if(!isDragging)return; isDragging =false;var currentPosition = moveBlock.offsetLeft;if(Math.abs(currentPosition - targetX)<= tolerance){ moveBlock.style.backgroundColor ='#5CB85C'; moveBlock.style.color ='#FFFFFF'; verifyLeftBar.style.border ='1px solid #5CB85C';// 显示成功提示 verifyResult.textContent ='验证成功!'; verifyResult.className ='verify-result success';return;} moveBlock.style.backgroundColor ='#D9534F'; moveBlock.style.color ='#FFFFFF'; verifyLeftBar.style.border ='1px solid #D9534F'; verifyLeftBar.style.backgroundColor ='#fff0f0';// 显示失败提示 verifyResult.textContent ='验证失败,请重试'; verifyResult.className ='verify-result fail';// 滑块回弹动画 moveBlock.style.transition ='left 0.8s'; moveBlock.style.left ='0px'; verifyLeftBar.style.transition ='width 0.8s'; verifyLeftBar.style.width ='0px';// 动画结束后清除过渡效果setTimeout(()=>{init() moveBlock.style.transition =''; verifyLeftBar.style.transition =''; moveBlock.style.backgroundColor ='#FFFFFF'; moveBlock.style.color ='#999'; verifyLeftBar.style.backgroundColor ='#F0FFF0';// 清除验证结果提示 verifyResult.className ='verify-result';},800);});</script></body></html>

Read more

OpenClaw 快速上手: 从0到1 完整教程 (Clawdbot)—— 2026 革命性的开源个人AI智能体(Personal AI Agent)

OpenClaw 快速上手:从 0 到 1 完整技术教程 前言:什么是OpenClaw? OpenClaw是一款革命性的开源个人AI智能体(Personal AI Agent),它代表了人工智能助手领域的一次重大突破。与传统的云端AI助手不同,OpenClaw采用本地优先(Local-first)架构,所有数据和处理都在用户自有设备上完成,确保了绝对的隐私安全。这款工具的核心优势在于其系统级执行能力和全渠道交互特性,用户可以通过Telegram、WhatsApp、iMessage等日常聊天工具下达指令,AI助手则能够自动完成文件整理、代码部署、日程同步等复杂任务。 OpenClaw最初名为Clawdbot,由开发者@steipete创建,自发布以来迅速在技术社区引起轰动。截至2026年1月,该项目在GitHub上的星标数已突破4万,支持Windows、Mac、Linux及云服务器多平台部署。它的设计理念是让AI助手真正成为用户的数字同事,具备24/7全天候工作能力,能够主动处理各种任务,而不仅仅是被动响应指令。 文章目录 * OpenClaw 快速上手:从 0 到 1

By Ne0inhk
央妈推荐!2026年AI提效实战宝典《AI提效手册》深度解读与资源分享

央妈推荐!2026年AI提效实战宝典《AI提效手册》深度解读与资源分享

大家好,最近在人工智能工具应用领域,一本由人民邮电出版社出版的新书《AI提效手册》受到了广泛关注,并获得了权威媒体的推荐。 作为一名常年关注效率工具的技术爱好者,我第一时间对其内容进行了研读。这本书旨在为普通用户提供一站式的AI工具实战指南,特别聚焦于目前市面上主流的五款应用。 本文将为大家梳理该手册的核心内容与实用价值。手册核心内容概览这本《AI提效手册》是一本面向大众的实操性指南,它系统性地整合了以下五款热门AI工具的教学: * 豆包:侧重于智能对话与各类文本内容的创作。 * 即梦:专注于图像生成与平面设计方面的辅助。 * 剪映:讲解其在视频剪辑流程中集成的AI赋能功能。 * 飞书:探讨如何利用其智能特性提升办公与团队协作效率。 * 扣子:服务于编程开发场景的效率提升工具。 内容亮点与特色该书之所以值得推荐,在于其极强的实战性和丰富的学习资源,具体体现在: 1. 案例驱动,场景丰富:书中提供了超过100个实战案例,覆盖了工作汇报、学习笔记与生活规划等多个核心场景,便于读者即学即用。 2. 提示词(Prompt)模板库:附有1000余条开箱即用的提示词模板,能

By Ne0inhk

如何借助AI完成测试用例的生成?实测高效落地指南

作为一名测试从业者,想必你也有过这样的困扰:重复编写常规功能的测试用例,耗时又耗力;面对复杂业务逻辑,容易遗漏边缘场景;需求频繁迭代时,用例更新跟不上节奏,常常陷入“加班写用例、熬夜改用例”的内耗里。 而现在,生成式AI的爆发的已经彻底改变了测试用例生成的传统模式——它能快速批量生成用例、覆盖更多人工易忽略的场景,还能适配需求迭代快速更新,将测试人员从重复劳动中解放出来,转向更核心的质量策略设计。但很多人尝试后却反馈:“把需求丢给AI,生成的用例驴唇不对马嘴”“看似全面,实际很多无法执行”。 其实,AI生成测试用例的核心不是“输入→输出”的简单操作,而是“人机协同”的高效配合:AI负责规模化生产,人负责搭建框架、把控质量。今天就结合我的实测经验,手把手教你如何借助AI高效生成测试用例,避开常见坑,真正实现提效不内耗。 一、先搞懂:AI生成测试用例的底层逻辑(避免踩错第一步) 很多人用不好AI的核心原因,是误以为AI能“读懂所有需求”,其实它的本质是“基于已有规则和数据,模仿人类测试思维生成用例”。其底层主要依赖三大技术,

By Ne0inhk
2026 毕业论文 AI 大横评我把 8 款主流工具,从“开题到交稿”完整跑了一遍

2026 毕业论文 AI 大横评我把 8 款主流工具,从“开题到交稿”完整跑了一遍

2026 年再看论文 AI,我基本确认了一件事: 90% 的工具,只能帮你“写几段话”; 能真正把论文“做完”的,非常少。 这次我不看宣传、不看名气,只做一件事: 👉 把一篇论文,从 0 跑到“可提交状态”。 统一评测流程👇 选题 → 大纲 → 正文 → 引用 → 格式 → 导出 并且给每款工具打分(满分 100): 维度 权重 论文结构能力 25 学术严谨性 20 文献 & 引用 20 格式与排版 20 实用完成度 15 🥇 第一名|雷小兔(总分:92 / 100) 定位:

By Ne0inhk