首页 > 技术文章 > 登录时候拖动验证

xiao-lei-ge 2022-03-17 11:37 原文

<template>
<div class="slider-captcha" :style="{width:width,height:height}" :class="activeClass">
<div class="bg"></div>
<div class="slidermask" :style="{width:maskWidth}"></div>
<span class="slider-text" v-show="showTxt" v-text="slideText"></span>
<div class="slider" @mousedown="mousedown" :style="{left:slideLeft}"></div>
<div class="img-container" v-show="showImg">
<div class="img-box">
<img :src="imgUrl" class="bg-img" :style="bgStyle" />
<img :src="blockUrl" class="slice-img" id="blockimg" :style="{left:blockLeft,top:blockTop,width:blockWidth,height:blockHeight}" />
</div>
</div>
</div>
</template>
<script>
export default {
name:"SlideVerify",
data(){
return {
imgUrl:"",
blockUrl:"",
error:false,
showImg:false,
showTxt:true,
slideText:"请按住滑块",
bgStyle:null,
slideLeft:0,
blockLeft:0,
blockTop:0,
blockWidth:0,
blockHeight:0,
activeClass:"",
maskWidth:0,
}
},
props:{
width:String,
height:String,
getApiId:String,//获取验证码的api
verifyApiId:String,//校验验证码的api
},
created(){
this.originX=this.originY=0;
this.isMouseDown = false;
this.trail=[];
this.loading=false;
this.checking=false;
this.loadImages();
},
methods:{
refresh(){
// 刷新验证码
this.getCaptcha();
this.loadImages();
},
loadImages(){
// 获取验证码图片
if(this.loading) return;
this.loading=true;
this.$http(this.getApiId,{}).then(res=>{
this.loading=false;
this.imgUrl=res.authcodeURL;
this.blockUrl=res.blockImg;
this.bgStyle={width:res.imgWidth+'px',height:res.imgHeight+"px"};
this.blockTop=res.blockY+"px";
this.blockWidth=res.blockW+"px";
this.blockHeight=res.blockH+"px";
}).catch(e=>{
console.error(e);
this.loading=false;
});
},
mousedown(e){
if(this.error) return;
this.originX = e.clientX;
this.originY = e.clientY;
this.isMouseDown = true;
this.trail=[];
this.showImg=true;
document.addEventListener("mousemove",this.mousemove);
document.addEventListener("mouseup",this.mouseup);
},
mousemove(e){
if (!this.isMouseDown) return;
var eventX = e.clientX;
var eventY = e.clientY;
var moveX = eventX - this.originX;
var moveY = eventY - this.originY;
if (moveX < 0 || moveX + 40 > 310) return false;
this.slideLeft=moveX-1+"px";

var blockLeft = (310 - 47 - 20) / (310 - 40) * moveX;
this.blockLeft=blockLeft+"px";
this.showTxt=false;
this.activeClass="sliderContainer_active";
this.maskWidth=(moveX + 4)+"px";
this.trail.push(Math.round(moveY));
this.showImg=true;
},
mouseup(e){
if (!this.isMouseDown) return false;
this.isMouseDown = false;
var eventX = e.clientX;
if (eventX === this.originX) return false;
this.activeClass="";
this.verify();
this.showImg=false;
document.removeEventListener("mousemove",this.mousemove);
document.removeEventListener("mouseup",this.mouseup);
},
reset(){
this.slideLeft=0;
this.blockLeft=0;
this.maskWidth=0;
this.showTxt=true;
this.slideText="请按住滑块";
this.activeClass="";
this.loadImages();
},
verify(){
// 校验验证码
if(this.checking) return;
this.checking=true;
var arr = this.trail;
var left = parseInt(this.blockLeft);
if(arr.length<5){
this.showTxt=true;
this.slideText="验证失败"
this.activeClass="fail";
this.$emit("verifyFail",false);
setTimeout(()=>{
this.reset();
this.checking=false;
}, 500);
}else{
this.$http(this.verifyApiId,{
imgcode:left.toString()
}).then(res=>{
this.checking=false;
this.activeClass="";
if(res&&res.verify){
this.activeClass="success";
this.showTxt=true;
this.slideText="验证通过";
this.$emit("verify",true,left.toString());
}else{
this.$emit("verify",false);
this.showTxt=true;
this.slideText="验证失败";
this.activeClass="fail";
setTimeout(()=>{
this.reset();
}, 500);
}
}).catch(e=>{
console.error(e);
this.checking=false;
});
}

},
},

}
</script>
<style>

.slider-captcha{
width: 380px;
height: 44px;
box-sizing: border-box;
padding-left: 33px;
padding-right: 12px;
text-indent: 0px;
position: relative;
font-size: 14px;
color: #999;
text-align: center;
}
.slider-captcha .bg{
width: 100%;
height: 100%;
border: 1px solid #ccc;
box-sizing: border-box;
background-color: #f4f5f8;
position: absolute;
left: 0;
top: 0;
border-radius: 3px;
}
.slider-captcha .slider {
position: absolute;
left: 0;
top: 0;
width: 47px;
height: 100%;
cursor: pointer;
border: 1px solid #ccc;
box-sizing: border-box;
background-color: #fff;
z-index: 5;
line-height: 40px;
text-align: center;
background-position: center;
background-repeat: no-repeat;
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMAQMAAABsu86kAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAACVJREFUCNdjaGJgOMzAkNjAYHCAQSKBgccAiIAMIBcoCJQCKgAAiLYHlZ2Jzi8AAAAASUVORK5CYII=");
}
.slider-text{
position: relative;
line-height: 42px;
text-align: center;
user-select: none;
}
.slider-captcha.success{
border-color: #04c68d;
background-color: #d9f8ef;
color: #04c68d;
text-align: left;
}
.slider-captcha.success .slider{
border-color: #04c68d;
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASBAMAAACk4JNkAAAALVBMVEUAAAAExo0Exo0Exo0Exo0Exo0Exo0Exo0Exo0Exo0Exo0Exo0Exo0Exo3///9xt1E/AAAADXRSTlMA8ttFKPrHmgFAv6IpRSOZZgAAAH5JREFUCNdjYGDgLApVN2AAApa1d+/eveUAZE28CwKSQCFZMOuiA0PbXQjIYLCFsi4z1ILpd3evM+iCGPfe3b3EEAsWenv3KoMsUAYoBGTpAgWAQkDZvUARoNDd2wy2IFVgU9qAOsEmw207gOQCBpZcIOOaA8iBzUWB6hYMDACmPmkvNFDS3QAAAABJRU5ErkJggg==");
}
.slider-captcha.fail .slider{
border-color: #ff5c5c;
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAu0lEQVQ4jbWU0Q2DMAxEGYGROgd3H96AbERGYIMyApvABtcPkBpK4kZRa8m/L3dnO133z5JZL3IU+fzoUWZ9HQQIIjeRKvQmcvwGiQ7g2sDkKamDvGEhl4lnp2wzzayg5iFyTV6PGgZzVYlcchmcSlcBsZghMPugBPZlEEsNKCYZrm2g1E5q07WWCftmB5jOAThhm/UC9oY92m8n85OFbDyRmIVclHk2gb2o5AY7MgvnNI8GZgGh+htprRc70xqgsauBzQAAAABJRU5ErkJggg==");
}
.slider-captcha .img-container{
position: absolute;
left: 0;
z-index: 10;
bottom: 46px;
/* width: 320px; */
box-sizing: border-box;
text-align: center;
padding: 5px;
background-color: #fff;
box-shadow: 0 0 3px rgba(0,0,0,0.25);
display: none;
}
.slider-captcha:hover .img-container{
display: block!important;
}
.slider-captcha .slice-img{
position: absolute;
left: 0;
}
.slider-captcha .img-box{
display: inline-block;
max-width: 100%;
position: relative;
}
.slider-captcha .slidermask {
position: absolute;
left: 0;
top: 0;
height: 100%;
border: 0 solid #128bed;
background: #D1E9FE;
box-sizing: border-box;
}
.slider-captcha.fail .slidermask {
border: 1px solid #f57a7a;
background-color: #fce1e1;
}
.slider-captcha.success .slidermask{
border: 1px solid #04c68d;
background-color: #d9f8ef;
}
</style>

推荐阅读