jquery
实现文字点选验证码
git地址:点击获取源码
一、功能说明(文字点选验证码)
- 词组库内存在大量3~6字随机词组,
- 从词组库内随机找出一组词组,随机展现在显示区
- 点击按钮,弹出验证码区域
- 将词组内的随机数量文字随机顺序作为验证文本进行校验
- 点击文字添加标记并计数,当点击次数与验证文本数量一致,自动校验
- 验证通过后,提示成功,关闭验证区域
- 验证失败,提示失败,刷新验证码
- 点击显示区内刷新按钮,刷新验证码
二. 效果图:
三、代码:
- 验证区
html
:index.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><!-- 引入验证区样式 --><link rel="stylesheet" type="text/css" href="css/index.css" /><style>.my-container {position: relative;top: 20px;left: 50px;}</style>
</head><body><div class="my-container"><input type="text"><button id="btn">点击触发验证码</button></div><!-- 验证码区域 --><div id="verification"><!-- 刷新 --><div class="refresh"></div><!-- 验证结果 --><div id="resultBox"></div><!-- 验证词组显示区 --><div id="box"></div></div><script src="js/jquery-1.9.1.min.js"></script><!-- 引入验证区js --><script src="js/index.js" type="text/javascript" charset="utf-8"></script><script>/*** 点击按钮显示验证区,初始化验证区*/$('#btn').click(() => {$('#verification').show()init();})</script></body></html>
- 验证区
js
:index.js
// TODO获取词库
$(function () {fetch("/js/data.json").then((response) => response.json()) // 解析JSON响应.then((response) => {textData = response.data;}).catch((error) => console.error("Error:", error));
});/*** @constant box 容器* @variate place 文字分散在容器中的随机位置* @variate textData 文字库集合* @variate verifyWord 需要校验的词组,用于渲染布局* @constant minVerifyWordLen 随机文字最小数量* @variate verifyText 需要校验的随机文字,用于展示* @variate verifyTextIdxs 需要校验的文本,取verifyText的index值* @variate verifyClickCount 点击校验文字的次数,达到verifyTextIdxs长度进行校验* @variate selectedIdxs 选中文字的index集合*/const box = $("#box");
let place = [{ left: "0px", top: "0px" },{ left: "120px", top: "0px" },{ left: "240px", top: "0px" },{ left: "0px", top: "90px" },{ left: "120px", top: "90px" },{ left: "240px", top: "90px" },
];let textData = [];
let verifyWord = "";
const minVerifyWordLen = 3;
let verifyText = "";
let verifyTextIdxs = [];
let verifyClickCount = 0;
let selectedIdxs = [];/*** @function getVerifyWord 获取随机校验词组*/function getVerifyWord() {return textData[Math.floor(Math.random() * (textData.length - 1))];
}/*** @function getVerifyText 获取随机校验文字*/
function getVerifyText() {// 随机选取校验文字数量let lenRandom = Math.ceil(Math.random() * verifyWord.length);if (lenRandom < minVerifyWordLen) {lenRandom = minVerifyWordLen;}const verifyArray = verifyWord.split("");const result = [];// 获取随机需要校验的文字for (let i = 0; i < lenRandom; i++) {let index = Math.floor(Math.random() * verifyArray.length);result.push(verifyArray[index]);verifyArray.splice(index, 1); // 移除已选的元素以避免重复}return result.join("");
}/*** @function getVerifyText 获取校验文字的idx*/
function getVerifyTextIdxs() {const wordArray = verifyWord.split("");const textArray = verifyText.split("");const result = [];for (let text of textArray) {const idx = wordArray.findIndex((word) => word === text);result.push(idx);}return result;
}/*** @function clear 重置*/
function clear() {box.empty();verifyWord = getVerifyWord();verifyText = getVerifyText();verifyTextIdxs = getVerifyTextIdxs();verifyClickCount = 0;selectedIdxs = [];$("#resultBox").html(`请依次点击: <span>${verifyText}</span>`);place.sort(() => {return Math.random() - 0.5;});
}/*** @function init 初始化*/
function init() {// 重置内容clear();verifyWord.split("").map((text, idx) => {createVerifyBox(text, idx);});/*** 创建存放每个校验文字的容器* @param {string} text 文字* @param {number} idx 索引* @attribute {number} index 文字标签的index值* @attribute {string: true | false } judge 判断标签是否被点击*/function createVerifyBox(text, idx) {//创建box分割的div容器let divEl = $('<div class="item"></div>');divEl.css({left: place[idx].left,top: place[idx].top,});//创建span标签存储校验文字let spanEl = $(`<span class="spanEl">${text}</span>`);divEl.append(spanEl);box.append(divEl);addSpanElCss(divEl, spanEl);// 添加属性,// 用于存入selectedIdxsspanEl.data("index", idx);spanEl.data("judge", "true");}/*** 添加span项样式*/function addSpanElCss(divEl, spanEl) {const lt = divEl.width() - spanEl.width() - 10;const rt = divEl.height() - spanEl.height() - 10;let left = Math.floor(Math.random() * lt);let top = Math.floor(Math.random() * rt);spanEl.css({left: left + "px",top: top + "px",});}//span点击事件$("#box .item span").click(function (e) {if ($(this).data("judge") == "true") {selectedIdxs.push($(this).data("index"));console.log(selectedIdxs, "selectedIdxs", verifyTextIdxs);$(this).data("judge", "false");verifyClickCount++;appendRadio(e);// 验证if (verifyClickCount === verifyTextIdxs.length) {getVerifyResult();}}});//点击事件,生成圆点function appendRadio(e) {const radioEl = $(`<div class='radio'>${verifyClickCount}</div>`);box.append(radioEl);const wt = radioEl.width() / 2;const ht = radioEl.height() / 2;radioEl.css({left: e.pageX - box.offset().left - wt + "px",top: e.pageY - box.offset().top - ht + "px",});}
}/*** @function getVerifyResult 获取校验结果*/
function getVerifyResult() {if (selectedIdxs.join() == verifyTextIdxs.join()) {$("#resultBox span").html("验证成功");$("#resultBox span").css("color", "#1abd6c");setTimeout(() => {$("#verification").hide();}, 500);// TODO 验证成功后操作} else {$("#resultBox span").html("验证失败");$("#resultBox span").css("color", "red");setTimeout(() => {init();}, 500);}verifyClickCount = 0;
}/*** @function 刷新*/
$(".refresh").click(() => {init();
});
- 验证区
css
:index.css
#verification {position: absolute;top: 60px;left: 50px;display: none;
}/* 刷新 */
#verification .refresh{position: absolute;top: 50px;right: 10px;z-index: 10;width: 28px;height: 28px;cursor: pointer;background-image: url("/img/refresh.png");background-size: 100% 100%;
}#box{position: relative;width: 360px;height: 180px;padding: 0 20px;border-radius: 10px;background-image: url("/img/bg.png");background-repeat: no-repeat;
}#box .item{position: absolute;width: 120px;height: 90px;
}#box .radio{position: absolute;z-index: 10;width: 30px;height: 30px;line-height: 30px;text-align: center;border-radius: 50%;color: #fff;background-color: #1abd6c;
}#box span{font-size: 40px;position: absolute;z-index: 4;color: #4463cb;font-weight: bold;
}#box span:hover{cursor: pointer;
}#resultBox{height: 40px;font-size: 18px;line-height: 40px;
}#resultBox span{font-size: 22px;font-weight: bold;color: #1f1f1f;
}
- 词库文件:
data.json
{"data": ["快乐的大脚","阖家快乐","祝福您","萌新的快乐","彩色溜","恭喜发财祝您","假期愉快","天天开心呀","今天是好天气","美丽的神话","加菲猫","小马宝利","记得加油呀","巴啦啦小魔仙","大头儿子","疯狂动物城"]
}