原生JS 实现滑块验证和拼图验证

4,978 阅读2分钟

原生JS实现滑块验证和拼图验证

题目阐述

  • 题目一:滑动解锁
    • 让滑动到滑块到最末端,即可通过验证。
    • 效果如下 滑动解锁.gif
  • 题目二:拼图解锁
    • 让图形移动到图片中缺失的位置,即可通过验证。
    • 效果如下 拼图解锁.gif

思路解析

滑块验证

  1. 首先给滑动条绑定oninput事件,通过滑动条来控制滑块的移动,
  2. 获取容器的宽度和滑块的宽度,
  3. 通过容器的宽度和滑块的宽度,设置滑块的移动范围,
  4. 最后判断滑块位置和验证成功的位置是否一致,一般验证成功的位置设置在容器末端。

代码示例

//滑块验证代码示例
<style>
        .box {
            width: 500px;
            height: 80px;
            border: 2px solid yellowgreen;
        }

        .left {
            width: 0px;
            height: 80px;
            background-color: pink;
            float: left;
        }

        .gap {
            width: 100px;
            height: 80px;
            text-align: center;
            line-height: 80px;
            background-color: skyblue;
            float: left;

        }

        input {
            width: 420px;
            height: 80px;
            position: absolute;
            top: 9px;
            left: 44px;
            opacity: 0.1;
        }
    </style>
</head>

<body>
    <div class="box">
        <div class="left"></div>
        <div class="gap">》》》</div>
    </div>
    <input type="range" value="0" class="move">
    <script>
        var fn = () => {
            var box = document.querySelector(".box");
            var gap = document.querySelector(".gap");
            var leftColor = document.querySelector(".left");
            var ipt = document.querySelector(".move");

            // 获取容器的宽度
            var boxWidth = parseInt(window.getComputedStyle(box, null)["width"]);
            //获取滑块的宽度
            var gapWidth = parseInt(window.getComputedStyle(gap, null)["width"]);
            ipt.oninput = function () {
                leftColor.style.width = (boxWidth - gapWidth) * ipt.value / 100 + "px";

                if (leftColor.style.width == "400px") {
                    alert("验证成功");
                }
                 // 存在bug 该算法是将宽度分为100份,一份一份的修改,不能做到具体的值。下面代码永不会执行到,所以怎么解决该问题?
                if (leftColor.style.width == ((boxWidth - gapWidth)+"px")) {
                    alert("验证成功");
                }
            }
        }
        fn();
    </script>

拼图验证

  1. 获取容器宽度,滑块宽度,
  2. 设置随机数让缺口生成的范围,范围在滑块右侧与容器右侧之间,
  3. 随机生成空白缺口的同时,通过背景图片定位让滑块背景图片与缺口少的部分吻合。
  4. 给滑动条绑定oninput事件,控制滑块移动,
  5. 最后判断滑块位置和验证成功的位置是否一致,一验证成功的位置即缺口位置。

代码示例

<style>
        .box {
            width: 500px;
            height: 300px;
            background: url(./images/pic0.jpg) no-repeat;
            background-size: 100% 100%;
            position: relative;
        }

        .img {
            width: 80px;
            height: 80px;
            background: url(./images/pic0.jpg) no-repeat;
            background-size: 500px 300px;
            background-position: -0px -110px;
            position: absolute;
            top: 110px;
            left: 0px;
            z-index: 1;
        }

        .gap {
            width: 80px;
            height: 80px;
            background-color: #fff;
            position: absolute;
            top: 110px;
            left: 400px;
        }

        input {
            width: 420px;
        }
    </style>
</head>

<body>
    <div class="box">
        <div class="img"></div>
        <div class="gap"></div>
    </div>
    <input type="range" value="0" class="move">
    <button class="reset">刷新</button>
    <script>
        var box = document.querySelector(".box");
        var img = document.querySelector(".img");
        var gap = document.querySelector(".gap");
        var ipt = document.querySelector(".move");
        var rebt = document.querySelector(".reset");
        //获取容器宽度和滑块的宽度
        var boxWidth = parseInt(window.getComputedStyle(box, null)["width"]);
        var imgWidth = parseInt(window.getComputedStyle(img, null)["width"]);
        console.log(boxWidth, imgWidth);
        //缺口随机生成函数
        var fn0_0 = () => {
            //生成缺口的范围,在滑块之外,容器之内
            var _left = ~~(Math.random() * (boxWidth - 2 * imgWidth)) + imgWidth;
            //设置缺口的位置,即设置它距离容器左侧的值
            gap.style.left = _left + "px";
            //设置滑块背景图片位置,因为向左移动所以,应该是负数。
            img.style.backgroundPosition = -_left + "px";
            return gap.style.left;
        }
        //获取当前缺口距离容器左侧的值
        var gap_left = parseInt(fn0_0());
        //拖动事件绑定
        var fn0 = () => {
            ipt.oninput = function () {
                //根据滑动条滑动,设置滑块距离容器左侧的值
                img.style.left = (ipt.value / 100) * (boxWidth - imgWidth) + "px";//0-500px
                var img_left = parseInt(img.style.left);

    // 存在bug 该算法是将宽度分为100份,一份一份的修改,不能做到具体的值。故暂时用范围来判断。
                if (Math.abs(img_left - gap_left) < 5) {
                    alert("解锁成功!");
                    img.style.left = "0px";
                    ipt.value = 0;
                }
    //因为算法存在缺陷,下面代码不会被执行,怎么能做到完全的值相等呢?所以怎么解决该问题?
                if (img_left == gap_left) {
                    alert("解锁成功!")
                }
            }
        }
        fn0();
        //刷新函数
        var fn1 = () => {
            rebt.onclick = function () {
                //缺口位置重新获取,滑块位置也要定位到开头
                img.style.left = "0px";
                ipt.value = 0;
                gap_left = parseInt(fn0_0());
            }
        }
        fn1();

总结

回顾CSS同时也练到JS还挺不错的,但是我在实现的过程中遇到了滑块和缺口不能百分之百的吻合的问题呢,只能含泪换一种条件成立的判断,想问问万能的网友,这个问题怎么解决呀?