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;
};
总结
第一次发博客,好多地方都不会用,还请多多关照