原生JS自定义6位数密码框

本文介绍了一种使用原生JavaScript实现6位数密码框的方法,通过重叠真实与虚拟输入框,利用CSS定位及动画效果,解决了光标定位、数字输入限制等问题。

原生JS 自定义6位数密码框
九月 18, 20190 条评论
今天要搞一个 6 位数的密码框 , 我百度了个遍, 就是没找到适合的, 不是一堆bug ,就是看不懂的命名 ,一点注释都没有, 或者,用jquery写的特高深的那种 , 看我的是一愣一愣的 ,然后, 我决定自已写了 ~~~

分析下大概思路:

本功能就是一个真实输入框和6个假输入框的故事。

将真实输入框和假输入框容器都定位重叠,注意将真实输入框的优先级设置较高,不然就输入不了咯。
为了做成看似假输入框在输入,则将真实输入框隐藏,用opacity隐藏哦。
用户输入时,通过行为层js将真实输入框的值分配给每个假输入框。
输入的同时,控制假输入框光标的效果,我用的是给每个元素都添加一个span,这样子能最大程度保证居中.实际上 ,我们输入的input是没有光标聚焦的,这个光标是假的.

解决途中也是困难重重

如何定位光标
光标如何显示
数字如何输入到下面的框框并且显示出来
输入了其他的字符会报错
输入了超过6位数会报错,而且按删除键按好多次(超出部分的次数)才能删除,
定位问题,样式问题 .
总结下来,我觉得 ,还是光标问题才是个重点, 其他的问题都是不足为题了.
还有一些许小小的bug ,但是我不打算解决了 ,因为在项目中我还要改, 所以这个案例就先这样子做着先
为了不出现我上面讲的哪个 看人家代码看都看不懂的问题 ,我特意的将每一行代码都注释的清清楚楚的, 我可真的是 ( );

废话不多说, 贴代码 (我发现代码很长 ,所以就分开贴吧)

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        body, html {
            background: #999;
        }

        .wrap-in {
            width: 300px;
            height: 50px;
            margin: 50px auto;
            text-align: center;
            position: relative;
        }

        .topInput {
            width: 100%;
            height: 100%;
            position: relative;
            opacity: 0;
            z-index: 999;
            overflow: hidden;
        }

        .bottomInputs {
            width: 100%;
            height: 100%;
            border: 1px solid #333;
            position: absolute;
            top: 0;
            border-radius: 5px;
            box-sizing: border-box;
            background: #fff;
            display: flex;
        }

        input {
            outline: none;
            border: none;
        }

        .bottomInputs > div {
            flex: 1;
            height: 100%;
            display: inline-block;
            border-right: 1px solid #333;
            position: relative;
            box-sizing: border-box;
        }

        .bottomInputs > div:last-of-type {
            border: none;
        }

        .bottomInputs input {
            width: 100%;
            height: 100%;
            background: transparent;
            text-align: center;
        }

        .cursor {
            height: 24px;
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            color: #333;
            animation: blink 1s infinite steps(1, start);
            opacity: 0;
            display: none;
        }

        /*这里设置动画blink*/
        @keyframes blink {
            0%, 100% {
                opacity: 0;
            }
            50% {
                opacity: 1;
            }
        }

    </style>
</head>
<body>
<div class="wrap">
    <div class="wrap-in">
        <input type="tel" maxlength="6" class="topInput">
        <div class="bottomInputs">
            <div>
                <span class="cursor">|</span>
                <input type="tel" maxlength="1">
            </div>
            <div>
                <span class="cursor">|</span>
                <input type="tel" maxlength="1">
            </div>
            <div>
                <span class="cursor">|</span>
                <input type="tel" maxlength="1">
            </div>
            <div>
                <span class="cursor">|</span>
                <input type="tel" maxlength="1">
            </div>
            <div>
                <span class="cursor">|</span>
                <input type="tel" maxlength="1">
            </div>
            <div>
                <span class="cursor">|</span>
                <input type="tel" maxlength="1">
            </div>
        </div>
    </div>
    <!--无用区域-->
    <p style="color: #ccc;text-align: center;margin-top: 10px;">
        输入六位数数字
    </p>
    <p style="text-align: center;margin-top: 20px;"><a href="https://www.yanat.top" style="color: #ccc;;">Y''am - 愿你日后归来仍少年</a></p>
    <!--无用区域-->
</div>
<script>
    //获取最上面的input
    let topInput = document.querySelector(".topInput");
    //获取div下面的所有input
    let bottomInputs = document.querySelectorAll(".bottomInputs input");
    //获取所有的光标
    let cursors = document.querySelectorAll(".cursor");
    //点击输入框后, 光标的位置
    topInput.onclick = function () {
        if (topInput.value.length === 0) {
            //初始位置为第一个
            cursors[0].style.display = "block";
        } else if (topInput.value.length === topInput.value.length) {
            //判断文本的长度是否超出光标
            cursors[topInput.value.length - 1].style.display = "block";
        } else {
            //如果再点击的时候 ,光标位置等于文本长度
            cursors[topInput.value.length].style.display = "block";
        }
    };
    //监听键盘输入
    topInput.oninput = function () {
        //判断输入框输入
        for (let i = 0; i < bottomInputs.length; i++) {
            //如果为数字,那么就添加
            if ((/^[0-9]*$/).test(topInput.value)) {
                //控制输入内容,直接输入到最顶部的input中,然后显示在下面的输入框
                bottomInputs[i].value = topInput.value.substr(i, 1);
                //每次输入把所有的光标置空
                cursors[i].style.display = "none";
                //判断光标位置
                if (topInput.value.length === topInput.value.length) {
                    //判断最小值
                    if (topInput.value.length === 0) {
                        cursors[0].style.display = "block";
                        //判断最大值
                    } else if (topInput.value.length === 6) {
                        cursors[topInput.value.length - 1].style.display = "block";
                        //如果不是最大或者最小
                    } else {
                        cursors[topInput.value.length].style.display = "block";
                    }
                }
            } else {
                //不为数字就返回
                return;
            }
        }
    };
    //移出输入框事件
    topInput.onblur = function () {
        for (let i = 0; i < cursors.length; i++) {
            //将所有的光标删除
            cursors[i].style.display = "none";
        }
    }
</script>
</body>
</html>

博客请移步 : Y’'am - 愿你日后归来仍少年

原文请移步 : Y’'am - 愿你日后归来仍少年

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值