JavaScript实现仿支付宝风格的6位数字密码输入框

作者:拾光时间:2026-10-21 19:24:35浏览:502

本文介绍如何使用JavaScript、CSS和HTML实现一个仿支付宝风格的6位数字密码输入框。核心思路是通过隐藏的真实输入框与6个视觉假输入框重叠,利用CSS定位和opacity属性处理层级,并通过JS监听input事件同步值与光标位置。特别指出使用type="tel"以触发移动端数字键盘,并结合正则处理PC端兼容性问题。

JavaScript实现仿支付宝风格的6位数字密码输入框

近期项目中遇到一个需求,需要实现类似支付宝支付密码的输入效果,因此整理并编写了这篇技术笔记,供后续参考。

以下是具体的实现代码:

HTML结构部分:

HTML结构实现


<div>
  <div>请在下方输入6位数字</div>
  <div class="ipt-box-nick">
  <input type="tel" maxlength="6" class="ipt-real-nick"/>
  <div class="ipts-box-nick">
   <div class="ipt-fake-box">
   <input type="text" >
   <input type="text" >
   <input type="text" >
   <input type="text" >
   <input type="text" >
   <input type="text" >
   </div>
  </div>
  <div class="ipt-active-nick"><img src="https://t.alipayobjects.com/images/rmsweb/T1nYJhXalXXXXXXXXX.gif"></div>
  </div>
 </div>

通过上述HTML结构,我们可以梳理出大致的实现逻辑:

该功能的核心在于一个真实存在的输入框与6个用于展示的假输入框之间的配合。

在布局上,将真实输入框与假输入框容器进行重叠定位,并设置真实输入框具有更高的z-index层级,以确保用户交互时能正确触发真实输入框。

为了达到“假输入框在输入”的视觉效果,需要将真实输入框隐藏,这里推荐使用opacity属性将其透明度设为0,而非直接display:none,以便保留其交互能力。

在交互层面,通过JavaScript监听真实输入框的输入事件,将实时获取的值分割并分配给对应的6个假输入框进行展示。

在输入过程中,还需控制假输入框的光标显示效果。此处引用了支付宝风格的图片作为光标指示,实际上假输入框并未真正获取焦点,光标效果由JS动态控制。

需要注意的关键点:

真实输入框的type属性应设置为tel而非number。这是因为number类型在部分浏览器中会显示增减箭头,而tel类型在移动端点击时会自动弹出数字键盘,体验更佳。

CSS样式部分:

CSS样式处理


.ipt-box-nick {
 height: 40px !important;
 line-height: 40px !important;
 position: relative !important; }
 .ipt-box-nick .ipt-real-nick {
 position: absolute !important;
 top: 0 !important;
 left: 0 !important;
 width: 100%;
 height: 40px !important;
 line-height: 40px !important;
 opacity: 0 !important;
 z-index: 3 !important; }
 .ipt-box-nick .ipts-box-nick {
 position: absolute !important;
 top: 0 !important;
 left: 0 !important;
 z-index: 1 !important;
 width: 100%;
 height: 40px !important;
 line-height: 40px !important;
 overflow: hidden; }
 .ipt-box-nick .ipts-box-nick .ipt-fake-box {
  height: 40px !important;
  line-height: 40px !important;
  display: flex !important;
  justify-content: space-between !important; }
  .ipt-box-nick .ipts-box-nick .ipt-fake-box input {
  width: 40px !important;
  height: 40px !important;
  border: 1px solid #D7D7D7 !important;
  color: #810213 !important;
  font-weight: bold !important;
  font-size: 18px !important;
  text-align: center !important;
  padding: 0 !important; }
 .ipt-box-nick .ipt-active-nick {
 width: 40px !important;
 height: 40px !important;
 line-height: 40px !important;
 text-align: center;
 position: absolute !important;
 top: 0;
 left: 0;
 z-index: 2; }
 .ipt-box-nick .ipt-active-nick img {
  vertical-align: middle; }

样式主要涉及定位重叠和真实输入框的隐藏处理,此处不再赘述。CSS使用Sass编写,编译后的CSS代码可能略显繁杂,请读者谅解。

JavaScript行为逻辑部分:

JavaScript交互逻辑


$(".ipt-real-nick").on("input", function() {
  //console.log($(this).val());
  var $input = $(".ipt-fake-box input");
  if(!$(this).val()){//无值光标顶置
   $('.ipt-active-nick').css('left',$input.eq(0).offset().left-parseInt($('.ipt-box-nick').parent().css('padding-left'))+'px');
  }
  if(/^[0-9]*$/g.test($(this).val())){//有值只能是数字
   //console.log($(this).val());
   var pwd = $(this).val().trim();
   for (var i = 0, len = pwd.length; i < len; i++) {
   $input.eq(i).val(pwd[i]);
   if($input.eq(i).next().length){//模拟光标,先将图片容器定位,控制left值而已
    $('.ipt-active-nick').css('left',$input.eq(i+1).offset().left-parseInt($('.ipt-box-nick').parent().css('padding-left'))+'px');
   }
   }
   $input.each(function() {//将有值的当前input后的所有input清空
   var index = $(this).index();
   if (index >= len) {
    $(this).val("");
   }
   });
   if (len == 6) {
   //执行其他操作
   console.log('输入完整,执行操作');
   }
  }else{//清除val中的非数字,返回纯number的value
   var arr=$(this).val().match(/\d/g);
   $(this).val($(this).val().slice(0,$(this).val().lastIndexOf(arr[arr.length-1])+1));
   //console.log($(this).val());
  }
  });

考虑到tel类型在PC端浏览器的兼容性问题,代码中加入了正则表达式进行值校验和处理。

整体逻辑并不复杂,关键细节已在代码中添加注释说明。

完整代码示例如下:

完整代码示例


<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <title>仿支付宝数字密码输入框</title>
 <style>
  .ipt-box-nick {
   width:300px;
   height: 40px !important;
   line-height: 40px !important;
   position: relative !important; }
  .ipt-box-nick .ipt-real-nick {
   position: absolute !important;
   top: 0 !important;
   left: 0 !important;
   width: 100%;
   height: 40px !important;
   line-height: 40px !important;
   opacity: 0 !important;
   z-index: 3 !important; }
  .ipt-box-nick .ipts-box-nick {
   position: absolute !important;
   top: 0 !important;
   left: 0 !important;
   z-index: 1 !important;
   width: 100%;
   height: 40px !important;
   line-height: 40px !important;
   overflow: hidden; }
  .ipt-box-nick .ipts-box-nick .ipt-fake-box {
   height: 40px !important;
   line-height: 40px !important;
   display: flex !important;
   justify-content: space-between !important; }
  .ipt-box-nick .ipts-box-nick .ipt-fake-box input {
   width: 40px !important;
   height: 38px !important;
   border: 1px solid #D7D7D7 !important;
   color: #810213 !important;
   font-weight: bold !important;
   font-size: 18px !important;
   text-align: center !important;
   padding: 0 !important;
   border-radius:2px;}
  .ipt-box-nick .ipt-active-nick {
   width: 40px !important;
   height: 40px !important;
   line-height: 40px !important;
   text-align: center;
   position: absolute !important;
   top: 0;
   left: 0;
   z-index: 2; }
  .ipt-box-nick .ipt-active-nick img {
   vertical-align: middle; }
 </style>
</head>
<body>
<div>
 <div class="lh40-nick h40-nick fwb-nick">请在下方输入6位数字</div>
 <div class="ipt-box-nick mb15-nick">
  <input type="tel" maxlength="6" class="ipt-real-nick"/>
  <div class="ipts-box-nick">
   <div class="ipt-fake-box">
    <input type="text" >
    <input type="text" >
    <input type="text" >
    <input type="text" >
    <input type="text" >
    <input type="text" >
   </div>
  </div>
  <div class="ipt-active-nick"><img src="https://t.alipayobjects.com/images/rmsweb/T1nYJhXalXXXXXXXXX.gif"></div>
 </div>
</div>
<script src="https://cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
<script>
 $(".ipt-real-nick").on("input", function() {
  //console.log($(this).val());
  var $input = $(".ipt-fake-box input");
  if(!$(this).val()){//无值光标顶置
   $('.ipt-active-nick').css('left',$input.eq(0).offset().left-parseInt($('.ipt-box-nick').parent().css('padding-left'))+'px');
  }
  if(/^[0-9]*$/g.test($(this).val())){//有值只能是数字
   //console.log($(this).val());
   var pwd = $(this).val().trim();
   for (var i = 0, len = pwd.length; i < len; i++) {
    $input.eq(i).val(pwd[i]);
    if($input.eq(i).next().length){//模拟光标,先将图片容器定位,控制left值而已
     $('.ipt-active-nick').css('left',$input.eq(i+1).offset().left-parseInt($('.ipt-box-nick').parent().css('padding-left'))+'px');
    }
   }
   $input.each(function() {//将有值的当前input后的所有input清空
    var index = $(this).index();
    if (index >= len) {
     $(this).val("");
    }
   });
   if (len == 6) {
    //执行其他操作
    console.log('输入完整,执行操作');
   }
  }else{//清除val中的非数字,返回纯number的value
   var arr=$(this).val().match(/\d/g);
   $(this).val($(this).val().slice(0,$(this).val().lastIndexOf(arr[arr.length-1])+1));
   //console.log($(this).val());
  }
 });
</script>
</body>
</html>

效果演示:

JavaScript实现仿支付宝风格的6位数字密码输入框

以上即为基于JavaScript实现的仿支付宝6位数字密码输入框的完整方案,希望能对读者有所帮助。如有疑问欢迎留言,小编会及时回复。感谢支持。

作者最新文章