SpringBoot前后端分离实现拼图滑动验证码(前端)

接上文 SpringBoot前后端分离实现拼图滑动验证码(后端)

效果

SpringBoot前后端分离实现拼图滑动验证码(前端)_第1张图片

主要结构

没做可插拔处理,直接在html里写标签了。主要包括包含了背景和拼图的模块slide_img_content,包含滑动条的模块slider。其中slider_mark用来做滑动条的进度显示,开始宽度为0随着箭头移动改变。

    <div class="slide_img_content">
        <img id="before_img" class="slide_img_mark" src="/static/after_image/sample_after_mark.png">
        <img id="back_img" src="/static/after_image/sample_after.png">
    div>
    <div class="slider">
        <div class="slider_arror" onselectstart="return false;">
            <img style="margin-top: 5px;" id="arror_icon" src="/static/icon/right_arror.png" draggable="false" width="30px" height="30px">
        div>
        <div class="slider_mask">
        div>
        <span class="slider_tip" onselectstart="return false;">滑动来移动拼图span>
    div>

样式实现

因为图片是固定大小,所以也没做自适应,基本都是绝对布局加宽高写死。

.slide_img_content{
    position: relative;
    margin: auto;
    height: 150px;
    width: 300px;
}
.slide_img_mark{
    position: absolute;
    height: 50px;
    width: 50px;
    margin-top: 50px;
    margin-left: 0;
}
.slider{
    position: relative;
    margin: 10px auto auto;
    height: 40px;
    width: 300px;
    border: 1px solid #c6cbd1;
    background-color: #f9fbfc;
}

.slider_arror{
    position: absolute;
    margin-left: 0;
    height: 40px;
    width: 50px;
    border-left: 1px solid #252627;
    border-right: 1px solid #252627;
    text-align: center;
}
.slider_arror:hover{
    background-color: #deee97;
}

.slider_mask{
    position: absolute;
    margin-left: 0;
    margin-top: 0;
    width: 0;
    height: 40px;
    background-color: #deee97;
}
.slider_tip{
    position: absolute;
    margin-left: 100px;
    margin-top: 10px;
}

js实现

分析一下前端要做的事情,主要是这几点:
获取并显示对应图片,记录坐标信息。
点击滑块开始,变色并记录鼠标开始位置。
滑动鼠标事件,记录鼠标位移信息,修改滑块位置和拼图位置,修改进度条块大小。
鼠标松开结束,判断成功与否,成功更改样式,失败提示后重置。

var sliderStart = false;
var x,y; // 鼠标最初位置
var back_width = 300;
var mask_width = 50;
var ly;
var lx;
var backImg;
var frontImg;
var yArray;

$(function(){
    // 初始化验证码
    $.ajax({
        type : "get",// 请求方式
        url : "/getImgInfo",// 发送请求地址
        dataType : "json",
        async : false,
        // 请求成功后的回调函数有两个参数
        success : function(data) {
            lx = data.xLocation;
            ly = data.yLocation;
            backImg = "/after/" + data.backName;
            frontImg = "/after/" + data.markName;
            initImg(backImg, frontImg, ly);
            initMovement()
        },
        error : function(){
            alert("error")
        }
    });
});

// 拼图验证码用---计算和
function sum(x1, x2){
    return x1 + x2
}

// 拼图验证码用---初始化图片
function initImg(backgroundImg, markImg, yLocation){
    $('#back_img').prop('src', backgroundImg);
    $('#before_img').prop('src', markImg);
    $('.slide_img_mark').css('margin-top', yLocation);
}

// 拼图验证码用---设置回调
function initMovement(){
    $('.slider_arror')[0].addEventListener('mousedown', sliderPush);
    window.addEventListener('mousemove', sliderDrug);
    window.addEventListener('mouseup', sliderEnd);
}

// 拼图验证码用---按下滑动按钮回调方法
function sliderPush(e){
    sliderStart = true
    x = e.clientX || e.touches[0].clientX;
    y = e.clientY || e.touches[0].clientY;
    $('.slider_tip').hide();
    $('.slider_mask').css('background-color', '#deee97');
    $('#arror_icon').prop('src', '/static/icon/right_arror.png');
    yArray = []
}

// 拼图验证码用---开始滑动回调方法, 改变arror位置和mask大小
function sliderDrug(e){
    if (!sliderStart)
        return false;

    // 获取鼠标移动位置
    const eventX = e.clientX || e.touches[0].clientX;
    const eventY = e.clientY || e.touches[0].clientY;
    const moveX = eventX - x;
    const moveY = eventY - y;

    // 存放y轴坐标,便于后续判断
    yArray.push(moveY);

    // 确保边界
    if(moveX < 0|| moveX + parseInt(mask_width) > back_width)
        return false;

    // 改变slider_arror的位置和mask大小
    $('.slider_arror').css('margin-left', moveX);
    $('.slider_mask').css('width', moveX);
    $('.slide_img_mark').css('margin-left', moveX);
}

// 拼图验证码用---结束时进行判断回调方法
function sliderEnd(e){
    if (!sliderStart)
        return false;

    sliderStart = false;
    finalX = $('.slide_img_mark').css('margin-left');
    // 5像素的误差
    finalX = finalX.toString().slice(0, -2);
    if(finalX < (lx - 5) || finalX > (lx + 5)){
        failed()
    }
    else if(yVerify()){
        console.log("verify success");
        success()
    }
    else{
        console.log("verify failed");
        failed()
    }
}

// 拼图验证码用---检测y轴变化
function yVerify(){
    if(yArray.length < 1)
        return false;
    var sumY = yArray.reduce(sum);
    var average = sumY / yArray.length;
    // 简单看看,y没变过算不对劲
    var same = true;
    for (let i = 0;i < yArray.length; i++){
        if(yArray[i] != average)
            same = false
    }
    return !same
}

// 拼图验证码用---验证成功回调方法
function success(){
    console.log("success");

    $('#arror_icon').prop('src', '/static/icon/green_correct.png');
    $('.slider_mask').css('background-color', '#79e77e');

    function successLink(){
        window.open('/index')
    }

    setTimeout(successLink, 1000)
}

// 拼图验证码用---失败重置
function failed(){
    console.log("failed");

    $('#arror_icon').prop('src', '/static/icon/red_error.png');
    $('.slider_mask').css('background-color', '#e73c4a');

    setTimeout(reset, 1000)
}

// 拼图验证码用---修改位置和重置颜色
function reset(){
    $('.slider_mask').css('background-color', '#deee97');

    $('.slider_arror').css('margin-left', 0);
    $('.slider_mask').css('width', 0);
    $('.slide_img_mark').css('margin-left', 0);

    $('#arror_icon').prop('src', '/static/icon/right_arror.png');
    $('.slider_tip').show()
}

通过初始位置和鼠标现在位置差值来判断位移信息。
最终判断位置成功与否时,给出了10像素大小的容错。
yVerify函数做了个简单的防脚本测试,总的来说这demo安全性基本没有,大家笑一笑就好。

项目开源地址:
https://github.com/huiluczP/verification_code_demo

你可能感兴趣的:(前端,js,css)