JS实现图片验证码
新手第一次发博客,还请多多关照
前言
前几天Net老师布置了一道实验作业,用JS实现文字验证码和简单的图片验证码,要求使用阿里巴巴矢量并且至少能更换三张图片完成
一、实验效果如图
解锁之前解锁成功
示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
二、实现步骤
1.body部分
代码如下(示例):
<!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" href="iconfont.css"><link rel="stylesheet" href="jichu.css"><script src="scripts/yzm.js"></script>
</head>//文字部分
<body><div class="wenzi"><input type="text" name="yzm"><span id="code_box" >Af3D</span>
</div>//图片部分
<div id="slideVerify"><div class="image"><div class="chip2"></div><div class="chip"></div></div><div class="box" onselectstart="return false;"><div class="bgColor"></div><div class="txt" >请拖动滑块解锁</div><!--给i标签添加上相应字体图标的类名即可--><div class="slider"><i class="icon iconfont iconicon-doubleright-line"></i></div></div>
</div><script type="text/javascript">var slideVerify = new SlideVerify("img/",4);
</script>//实现文字验证码的js代码
<script>var code_box = document.getElementById("code_box");function refreshCode() {//62个字符 随机选择4位var code = '0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM',char = '',result = '';for (var i = 0; i < 4; i++) {//随机选择一位 (0,61) 写出0到61的随机的索引数字var code_index = Math.round(Math.random() * 61);//得到随机的索引 取出随机地字符var char = code[code_index];//随机取出的字符 存在几个相同重复的问题 ,而且对于字母,不能区分大小写。// 避免重复的思路是:取出字符之后,和最后的result对比一下,看看里边是不是已经存在了,如果存在本次循环就终止,进行下一次if (result.toUpperCase().indexOf(char.toUpperCase()) > -1)//indexOf() == -1 说明结果里边没有要找的字符 那么 > -1 就是 里边有重复的字符{i--;//为什么会 --? 因为如果条件成立,那么本轮循环就结束进行下一轮循环(自然i就加1了),那么本轮本应该取出的字符就没有了//到最后会少一个字符 缺席continue;//终止本轮循环 进行下一轮}result += char;}code_box.innerHTML = result;
}
//点击事件
code_box.onclick = refreshCode;
</script></body>
</html>
2.Css格式
1.阿里巴巴矢量格式 iconfont.css
代码如下:
@font-face {font-family: "iconfont";src: url('iconfont.eot?t=1604237221659'); /* IE9 */src: url('iconfont.eot?t=1604237221659#iefix') format('embedded-opentype'), /* IE6-IE8 */url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAMgAAsAAAAAB1wAAALSAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDBgqCLIF5ATYCJAMMCwgABCAFhG0HUBtZBhEVlJ9kPwvsZpfLcRsUgIxI22wDfXo50zWDZbHB//+Ih//2o903M1/WtKk2bWLEJXFIRNOQPHsoNNqGSEh0vImGvD6xv3prV2dHIW0EMF13bsq7jgeF9uvFi5wOaXVqcfi4AemFFW/5Hu11znLlOHsB4PNcTq8lPr9lOa21beNRL8B4a2B7YpvsAskDwYaxmwge4HkCncatikN/IAimAkwLxM1aJQdmIaIoTr4V6oa1BfEcNG1aJO+BZ/zz8ZcpWkiqDDD3/GVfEc4f9bM7ytz/nCQlIF3OBWcTGasoxKVGz0UUmVmVdUYqalxNrQhpqfj/P5fEuvqgf7xE1ACF3WBRzyZ+1LGA4MfdBglkUGu9J+D2Ak+kSMEVCgcGrvAPvoeOziOHZ+H9k5CitywLdeak0tdL8nB3flKW0YqE3KioNIeapU6/SOXK1lCRiHdH26tZu+x/lvpxEj6SrqJUlo/ZwtMToiKrfH01ZA2iKW1+ioGGN0yiLKtcXlRkTe1Hy5eXTSm2Pwj7mDPBse88dfTjN92rdkffebJwGrwAIJZPyJd//TvepoWHjMD6yuRQAZ93j1f5hLMHBfkBoL0nb/CPpQNrSiwH1lxCCZak3mwtF5LQRa7fGRAY9G26bmRwIaE1kiFpjCFrzdIKaxWVLuuotXbQacW5zV2G3EcRhQWWPdUQ+p0i6fUOWb/3tML6isqo/6j1R0anCyHZs8t8OIzwEG6MJ+w/MEcMEtlZiOIrquI2yss5+4mUTRz6pivnZwxISyzIbzUwS5AUPUzaZehchETxhQc3mjmNbSub3tQc0VeCh3BjPGH/gTlikLQxiwr1V1TFbdRBGgk/kbLpH/qmG0CbNWEQ6VGuyW81MEuQFD1M2ih0LkJqHvXCgxs9IZXGFtaTQzXN9jr/f5ugE6jOkSJHwX/0Ycu3bOGvY1CX/DH1GcvukIzSXDsTsKoAAAA=') format('woff2'),url('iconfont.woff?t=1604237221659') format('woff'),url('iconfont.ttf?t=1604237221659') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */url('iconfont.svg?t=1604237221659#iconfont') format('svg'); /* iOS 4.1- */
}.iconfont {font-family: "iconfont" !important;font-size: 16px;font-style: normal;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;
}.iconicon_xuanzhong:before {content: "\e66a";
}.iconicon-doubleright-line:before {content: "\e6ee";
}
2.整体格式 jichu.css
代码如下
*{padding: 0;margin: 0;
}.wenzi{position: relative;width: 300px;height: 20px;margin: 0 auto;margin-top: 5px;
}
#code_box{cursor: pointer;
}.image{position: relative;width: 300px;height: 130px;margin: 0 auto;margin-top: 10px;
}
#slideVerify .chip{width: 40px;height: 40px;position: absolute;
}
#slideVerify .chip2{width: 40px;height: 40px;position: absolute;filter: brightness(0.5) opacity(0.5);/*改变滤镜亮度、透明度 */
}.box{position: relative;width: 300px;height: 40px;margin: 0 auto;margin-top: 5px; background-color: #e8e8e8;box-shadow: 1px 1px 5px rgba(0,0,0,0.2);
}.bgColor{position: absolute;left:0;top:0;width:40px;height: 40px;background-color: #75CDF9;
}
.txt{position: absolute;width: 100%;height: 40px;line-height: 40px;font-size: 14px;color: #000;text-align: center;
}
.slider{position: absolute;left:0;top:0;width: 50px;height: 38px;border: 1px solid #ccc;background: #fff;text-align: center;cursor: move;
}
.slider>i{position: absolute;top:50%;left:50%;transform: translate(-50%,-50%);
}
.slider.active>i{color:green;
}
3.图片验证码的JS代码
代码如下
var SlideVerify = function (path, num) {var slideVerify = document.getElementById("slideVerify"),chip = slideVerify.getElementsByClassName("chip")[0], //图片小块chip2 = slideVerify.getElementsByClassName("chip2")[0],box = slideVerify.getElementsByClassName("box")[0],bgColor = slideVerify.getElementsByClassName("bgColor")[0], //背景色txt = slideVerify.getElementsByClassName("txt")[0], //文本slider = slideVerify.getElementsByClassName("slider")[0], //滑块icon=slideVerify.getElementsByClassName("icon iconfont iconicon-doubleright-line")[0],image = slideVerify.getElementsByClassName("image")[0],successMoveDistance = box.offsetWidth - slider.offsetWidth, //解锁需要滑动的距离downX, //用于存放鼠标按下时的位置offsetX,isSuccess = false, //是否解锁成功的标志,默认不成功distance,imgAt = Math.floor(Math.random() * num)+1;image.style.background = "url(" + path + imgAt + ".jpg)";//二、获取到需要用到的DOM元素var getisSuccess = function () {return isSuccess;}//三、给滑块添加鼠标按下事件slider.onmousedown = mousedownHandler;//3.1鼠标按下事件的方法实现function mousedownHandler(e) {bgColor.style.transition = "";slider.style.transition = "";var e = e || window.event || e.which;downX = e.clientX;//在鼠标按下时,分别给鼠标添加移动和松开事件ry = Math.floor(Math.random() * 80) + 20;rx = Math.floor(Math.random() * 150) + 120;chip.style.background = "url(" + path + imgAt + ".jpg)";chip.style.top = ry + "px";chip.style.backgroundPositionX = -rx + "px";chip.style.backgroundPositionY = -ry + "px";chip2.style.background = "url(" + path + imgAt + ".jpg)";chip2.style.top = ry + "px";chip2.style.left = rx + "px";chip2.style.backgroundPositionX = -rx + "px";chip2.style.backgroundPositionY = -ry + "px";chip2.style["box-shadow"] = "5px 5px 10px black";distance = rx;document.onmousemove = mousemoveHandler;document.onmouseup = mouseupHandler;//四、定义一个获取鼠标当前需要移动多少距离的方法function getOffsetX(offset, min, max) {if (offset < min) {offset = min;} else if (offset > max) {offset = max;}return offset;}//3.1.1鼠标移动事件的方法实现function mousemoveHandler(e) {var e = e || window.event || e.which;var moveX = e.clientX;offsetX = getOffsetX(moveX - downX, 0, successMoveDistance);bgColor.style.width = offsetX + "px";slider.style.left = offsetX + "px";chip.style.left = offsetX + "px";// if (offsetX == successMoveDistance) {// success();// }//如果不设置滑块滑动时会出现问题(目前还不知道为什么)//e.preventDefault();}//3.1.2鼠标松开事件的方法实现function mouseupHandler(e) {if (offsetX - distance < 8 && offsetX - distance > -8) {success();} else {bgColor.style.width = 0 + "px";slider.style.left = 0 + "px";bgColor.style.transition = "width 0.8s linear";slider.style.transition = "left 0.8s linear";//imgAt = Math.floor(Math.random() * num);//image.style.background = "url(" + path + imgAt + ".jpg)";chip.style.background = null;chip2.style.background = null;chip2.style["box-shadow"] = null;}document.onmousemove = null;document.onmouseup = null;}//五、定义一个滑块解锁成功的方法function success() {isSuccess = true;txt.innerHTML = "解锁成功";bgColor.style.backgroundColor = "lightgreen";slider.className = "slider active";icon.className = "icon iconfont iconicon_xuanzhong";bgColor.style.width=successMoveDistance+"px";slider.style.left=successMoveDistance+"px";//滑动成功时,移除鼠标按下事件和鼠标移动事件slider.onmousedown = null;document.onmousemove = null;image.onmousedown = "null";//成功解锁后的回调函数setTimeout(function () {alert("解锁成功!");}, 100);}}
return getisSuccess;
};