js 验证码输入框
名字起太长会有傻子跟着念 人气:0前言
验证码输入框应该是很常见的需求吧,不知道各位小伙伴在在遇到的时候是选择找一找插件还是自己动手撸一个呢?我花了点时间撸了一个出来,实际体验还不错,分享给大家。
思路
我在实现之前肯定也是上网搜了一下的,网上的方式大多是使用多个input标签来实现,但我觉得不太优雅,就自己想了一个方法。使用了6个div标签和一个input标签。验证码长度一般是4位或6位,我这里用6位做演示。
- 先将6个div使用flex布局平铺。
- 再将input使用绝对定位覆盖在6个div上面。
- 监听input元素的input、focus、blur事件,对用户的输入进行处理。
遇到的问题
上述布局在pc端是ok的,但是在移动端会有问题,移动端的光标底部会有个控件,你能够拖动调整光标位置。大概长这个样子,如下图:
不过解决方法也很简单,红色背景是box,蓝色背景是input
- input宽度设置大一点,同时使用position: absolute; right: 0; top: 0;右对齐
- box设置overflow: hidden;将左侧多余部分隐藏,这样就看不到光标啦。
为了方便理解,我将top设置为48px,如下图
实际应该是top: 0,如下图
下面是代码,聪明的你一看就明白。
HTML
<div class="box"> <div class="field-list"> <div class="field-item"></div> <div class="field-item"></div> <div class="field-item"></div> <div class="field-item"></div> <div class="field-item"></div> <div class="field-item"></div> </div> <input class="field-input" type="text" maxlength="6"> </div>
CSS
.box { position: relative; width: 338px; overflow: hidden; } .field-list { display: flex; justify-content: space-between; } .field-item { box-sizing: border-box; width: 48px; height: 48px; line-height: 46px; font-size: 24px; text-align: center; font-weight: bold; border: 1px solid #ccc; border-radius: 3px; } .field-item-focus { border-color: #409EFF; } .field-item-focus::before { content: ''; display: block; width: 2px; height: 30px; margin: 8px auto; background: skyblue; animation: blink 1s steps(1) infinite; } @keyframes blink { 50% { opacity: 0; } } .field-input { box-sizing: border-box; position: absolute; top: 0; right: 0; width: calc(100% + 60px); height: 48px; padding: 0; border: none; outline: none; opacity: 0; background: transparent; }
JS
// 获取dom const fieldList = document.querySelectorAll('.field-item'); const fieldInput = document.querySelector('.field-input'); // 监听input输入事件,只支持输入数字,过滤非数字字符 fieldInput.addEventListener('input', function (e) { const v = e.target.value.replace(/[^\d]/g, ''); e.target.value = v; // 考虑粘贴情况,循环赋值 for (let i = 0; i < 6; i++) { fieldList[i].innerHTML = v[i] || ''; } // 移除旧光标 removeCursor(); // 计算新光标出现位置 calcCursorPosition(); }); // focus fieldInput.addEventListener('focus', function (e) { calcCursorPosition(); }); // blur fieldInput.addEventListener('blur', function (e) { removeCursor(); }); // 计算光标出现位置 function calcCursorPosition() { const length = fieldInput.value.length; if (length < 6) { fieldList[length].classList.add('field-item-focus'); } } // 移除光标 function removeCursor() { // 最后一位没有光标,?.操作符避免报错 document.querySelector('.field-item-focus')?.classList.remove('field-item-focus'); }
实现效果
加载全部内容