滑动验证码--前端部分

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";
			}
		})
		};
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章