1.原理
後端預先保存n張圖片用來做滑動驗證碼的素材,然後在圖片上面隨機取一塊固定大小的小圖片作爲滑動的素材,然後記錄小圖片相對於大圖的位置,也就是小圖上邊距和大圖上邊距之前的距離(x座標),小圖左邊距和大圖左邊距的距離(y座標)。
前端先請求圖片資源,後端返回大圖、小圖和小圖的(y座標),當用戶拖動小圖後,獲取到小圖的x座標,將此時小圖的x,y座標返給後端做驗證。
<!--html-->
<!--滑動驗證碼-->
<div class="img_bg" v-if="showImgContent">
<!--滑動容器-->
<div class="sliderImg" >
<!--大圖-->
<img :src="save_big_url" alt="" class="big_img">
<!--小圖-->
<img :src="save_small_url"
alt="" class="small_img"
ref="small_img"
@mousedown="move"
>
<div class="img_tip">請滑動驗證碼進行驗證。</div>
</div>
</div>
//js
data() {
return {
showImgContent: false,//是否展示圖片驗證碼
isCheckImg: false,// 是否使用滑動驗證碼
positionX: 0, // 小圖相對大圖的左邊距
positionY: 0,// 小圖相對大圖的上邊距
save_big_url: "",//小圖url
save_small_url: "",//大圖url
}
}
methods:{
// 獲取驗證圖片和參數
async mixVerifyCode(x = "") { // x爲空,請求圖片和參數,驗證時傳x座標
let result;
await httpServer("獲取驗證碼圖片和y座標", {
xvalue: x
})
.then((res) => {
result = res;
})
.catch((err) => {
})
return result;
},
// 渲染圖片
showImg() {
this.mixVerifyCode().then((res) => {
// 給圖片URL賦值
this.save_big_url = res.save_big_url
this.save_small_url = res.save_small_url
// 初始化小圖的位置
this.$refs.small_img.style.top = `${res.yvalue}px`;
this.$refs.small_img.style.left = `10px`;
});
},
// 滑動驗證碼
move(e) {
let odiv = e.target; //獲取目標元素(小圖)
//算出鼠標相對元素的位置
let disX = e.clientX - odiv.offsetLeft;
let disY = e.clientY - odiv.offsetTop;
// 鼠標移動時
document.onmousemove = (e) => { //鼠標按下並移動的事件
if (e.preventDefault) e.preventDefault();
//用鼠標的位置減去鼠標相對元素的位置,得到元素的位置
let left = e.clientX - disX;
let top = e.clientY - disY;
//綁定元素位置到positionX和positionY上面
this.positionX = left;
this.positionY = top;
let bigImg = document.getElementsByClassName("big_img")[0];
const bigX = bigImg.clientWidth - odiv.offsetWidth;
left = Math.min(Math.max(0, left), bigX);
//移動當前元素
odiv.style.left = left + 'px';
};
// 鼠標按鍵釋放時
document.onmouseup = (e) => {
if (e.stopPropagation) e.stopPropagation();
if (e.preventDefault) e.preventDefault();
e.cancelBubble = true;
document.onmousemove = null;
document.onmouseup = null;
// 計算小圖x值
const xvalue = e.clientX - e.offsetX - document.getElementsByClassName("big_img")[0].getBoundingClientRect().x;
// 想後端發起驗證請求
this.mixVerifyCode(parseInt(xvalue).toString()).then((res) => {
if (res.is_success) {
// 驗證通過
this.showImgContent = false;
this.isCheckImg = true;
// 繼續你的業務邏輯
} else {
// 驗證未通過
this.isCheckImg = false;
this.showImg();// 刷新圖片驗證碼
odiv.style.left = "0px";
}
})
};
}
}