700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 实现拼图滑动验证码

实现拼图滑动验证码

时间:2023-01-22 19:11:13

相关推荐

实现拼图滑动验证码

实现拼图滑动验证码

拼图滑动验证码的纯前端简单实现,重要部分都已标注注释,如果需要配合后端可以参考此思路,后端处理图片生成一个带缺口的背景图与一个符合缺口的拼图,并将取得拼图块的位置记录到SESSION,将图片与拼图传给前端展示,当用户拖动并松开鼠标后将鼠标轨迹与停留位置发送到后端,后端从SESSION中取得位置信息并与前端传递的位置进行对比,有需要的话可以分析此用户轨迹用以区分人机,如果位置偏差小于一定阈值则认为拼图成功。

实例

<!DOCTYPE html><html><head><title>滑动拼图验证码</title><link rel="stylesheet" type="text/css" href="/t/font_1582902_u0zm91pv15i.css"><style type="text/css">.verify-slide-con{/* 滑动拼图容器块 */width: 360px;padding: 10px 20px;border: 1px solid #eee;}.img-con{/* 图片容器块 */width: 100%;height: 200px;display: flex;justify-content: center;align-items: center;overflow: hidden;border: 1px solid #eee;position: relative;}.img-con > .slide-block{/* 图片区域的滑块 */top: 0;left: 0;position: absolute;height: 40px;width: 40px;display: none;background-repeat: no-repeat;background-attachment: scroll;background-size: 360px 200px;z-index: 10;box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.4), 0 0 10px 0 rgba(90, 90, 90, 0.4);}.img-con > .slide-block-mask{/* 图片区域的空缺区域 */top: 0;left: 0;position: absolute;height: 40px;width: 40px;display: none;background-color: rgba(0, 0, 0, 0.4);}.img-con > .img{/* 图片 */width: 100%;height: 100%;}.img-con > .loading{/* 加载中样式 */width: unset;height: unset;}.slide-con{/* 滑块容器 */height: 40px;margin: 10px 0;position: relative;border: 1px solid #eee;}.slide-con > .slide-btn{/* 滑动按钮 */height: 40px;width: 40px;position: absolute;background: #4C98F7;display: flex;justify-content: center;align-items: center;cursor: pointer;}.icon-arrow-right{/* 右箭头 */font-size: 30px;color: #fff;}.operate-con{/* 操作容器块 */border-top: 1px solid #eee;height: 30px;padding: 5px 0 0 5px;display: flex;align-items: center;}.icon-shuaxin1{/* 刷新按钮 */color: #777;font-size: 20px;cursor: pointer;}</style></head><body><div class="verify-slide-con"> <!-- 滑动拼图容器块 --><div class="img-con"> <!-- 图片容器块 --><img class="img"> <!-- 图片 --><div class="slide-block"></div> <!-- 拼图 --><div class="slide-block-mask"></div> <!-- 缺口 --></div><div class="slide-con"> <!-- 滑块容器 --><div class="slide-btn"> <!-- 滑动按钮 --><i class="iconfont icon-arrow-right"></i> <!-- 图标 --></div></div><div class="operate-con"> <!-- 操作容器块 --><i id="refresh" class="iconfont icon-shuaxin1"></i> <!-- 刷新按钮 --></div></div></body><script type="text/javascript">(function(){var imgList = [ // 图片组"http://www./__local/9/7A/B1/F29B84DEF72DD329997E8172ABA_664BA3EF_32466.jpg","http://www./__local/B/F3/E4/693AB931C9FFB84646970D53BFE_C506394A_4282CA.jpg","http://www./__local/F/7A/AA/E1459849AA8AB0C89854A41BD41_BF3BD857_BC0D8.jpg","http://www./__local/1/95/CB/EDC1450B8FD1B8A25FAAC726AA4_A36D4253_16C91.jpg",];var imgCon = document.querySelector(".img-con"); // 图片容器元素引用var img = document.querySelector(".img-con > .img"); // 图片元素引用var slideBlock = document.querySelector(".img-con > .slide-block"); // 滑块元素引用var slideBlockMask = document.querySelector(".img-con > .slide-block-mask"); // 缺口元素引用var slideCon = document.querySelector(".slide-con"); // 滑动容器引用var slideBtn = document.querySelector(".slide-con > .slide-btn"); // 滑块按钮引用var refreshBtn = document.querySelector("#refresh"); // 刷新按钮引用function randomInt(min=0, max=1) {// 生成随机数return min + ~~((max-min)*Math.random()) // min <= random < max }function initSlider(){var maxTop = imgCon.offsetHeight - ~~(window.getComputedStyle(slideBlock).getPropertyValue("height").replace("px","")); // 获取最大Y轴偏移距离var maxRight = imgCon.offsetWidth - ~~(window.getComputedStyle(slideBlock).getPropertyValue("width").replace("px","")); // 获取最大X轴偏移距离var randPosY = randomInt(0, maxTop); // 随机Y轴偏移var randPosX = randomInt(60, maxRight); // 随机X轴偏移slideBtn.onmousedown = function(e){slideBlock.style.display = "block"; // 显示拼图slideBlock.style.top=`${randPosY}px`; // 拼图Y轴偏移slideBlock.style["background-position"] = `-${randPosX}px -${randPosY}px`; // 指定背景图位置slideBlockMask.setAttribute("style", `display:block;top:${randPosY}px;left:${randPosX}px`); // 显示缺口并指定位置var edgeX = e.clientX; // 鼠标点击位置document.onmousemove = event => {var relativeX = event.clientX - edgeX; // 鼠标移动距离if(relativeX<0 || relativeX>imgCon.offsetWidth-this.offsetWidth) return void 0; // 判断是否超出滑动容器块 超出则不移动slideBlock.style.left = relativeX + "px"; // 移动拼图this.style.left = relativeX + "px"; // 移动滑块按钮}document.onmouseup = function() {this.onmousemove = null; // 撤销事件this.onmouseup = null; // 撤销事件if(Math.abs(slideBlock.offsetLeft - slideBlockMask.offsetLeft)<=2) alert("验证成功"); // 偏移距离小于2则认为成功else alert("验证失败"); // 否则失败slideBlock.style.left = 0; // 拼图归位slideBtn.style.left = 0; // 滑块按钮归位};}}function switchImg(){slideBlock.style.display = "none"; // 不显示拼图slideBlockMask.style.display = "none"; // 不显示缺口img.classList.add("loading"); // 指定图片加载中样式img.src="/gh/sentsin/layui@15d7241/dist/css/modules/layer/default/loading-2.gif"; // 加载动画var newSrc = imgList[randomInt(0, 4)]; // 随机加载图片var tmp = new Image(); // 隐式加载图片tmp.src = newSrc; // 指定srctmp.onload = function(){img.classList.remove("loading"); // 撤销loadingimg.src = newSrc; // 指定src 此时从缓存加载图片slideBlock.style["background-image"] = `url(${newSrc})`; // 拼图背景initSlider(); // 初始化滑块}}(function(){switchImg(); // 加载图片refreshBtn.addEventListener("click", e => switchImg()); // 刷新按钮绑定事件})();})();</script></html>

每日一题

/WindrunnerMax/EveryDay

参考

/p/42082496/himushroom/verify-slide/xiaoshen666/p/10968750.html

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。