一个自封装密码框最后一位明文组件

47 阅读1分钟

很多时候我们登录页面的密码框都是密文的,那么在用户输入时其实是不知道自己输入的是什么的,基于此如果当前输入是明文操作,同时我们在input上面加上一个眼睛icon,点击眼睛icon,密码全明文,主打就是一个人性化。

举个栗子,当我输入你是帅比的时候,他的过程为: 1.你 --> 0.5s --> ● 2.●是 --> 0.5s --> ●● 3.●●帅 --> 0.5s --> ●●● 4.●●●比 --> 0.5s --> ●●●●

我们使用input type为text来实现密码框功能,组件代码如下

    <input id="password"
           type="text"
           style="color:#fff; ime-mode:disabled"
           placeholder="请输入密码" 
           ng-model="data.radioPassWord" //这里我框架是angular 其他框架换成相应的双向绑定属性
           maxlength="32" //限制密码框长度,预防xss攻击
           onpaste="return false"
           ondragenter="return false" 
           oncontextmenu="return false;" 
           ng-change="passwordChange()" //相当于其他框架的onChange
           autocomplete="off" //禁止input框的自动提示
           ng-keypress="enterLogin()" />
   <i class="icon-eye"
      ng-mousedown="clearpass('text')" //angular的mousedown
      ng-mouseleave="clearpass('password')"
      ng-mouseup="clearpass('password')"></i>

这里是组件绑定的数据代码

        //angular数据绑定 react就用state绑定
        data = {
                radioPassWord:'', //标记带有●修饰的输入字符
                password: '', //标记输入密码
                cursorPosition: 0, //用来记录当前密码输入框的光标位置
                timerObj:{
                  timer1:null,
                  timer2:null,
                  timer3:null,
                },//密码最后一位明文延时器对象
            };

这里是事件处理的函数

   //$timeout 是angular对settimeout的写法 小伙伴们可以用settimeout 
   const passwordChange = function (){ //密码最后一位明文函数
              const inputTarget = document.querySelector('#password');
              const selectPosition = inputTarget.selectionStart; //光标位置
              const inputVal = data.radioPassWord.replace(/[\u4e00-\u9fa5]/ig,'');
              const length = inputVal.length;
              const leftContent = inputVal.slice(0 , selectPosition-1); //当前光标输入的位置之前的字符串
              const inputContent = inputVal.charAt(selectPosition-1); //当前光标输入的位置
              const rightContent = inputVal.slice(selectPosition-1 , length-1); //当前光标输入位置之后的字符串
              const radioContent = leftContent.split('').map((i)=> '●').join('')+ inputContent + rightContent.split('').map((i)=> '●').join(''); //这里是拼起来带●的完整字符串
              const passwordArray = data.password.split('');
              const isInputMethod = Number(length) - Number(data.password.length) >= 2;
              data.timerObj.timer1 && $timeout.cancel(data.timerObj.timer1); //清除延时器 避免高频输入操作内存泄漏
              data.timerObj.timer2 && $timeout.cancel($scope.data.timerObj.timer2);
              data.timerObj.timer3 && $timeout.cancel($scope.data.timerObj.timer3);
              data.isActive = false;
              if(length > data.password.length){//这里判断操作是输入
                data.password = isInputMethod ? data.password + inputVal.substring(data.password.length, inputVal.length) : passwordArray.slice(0, selectPosition-1).join('') + inputContent + passwordArray.slice(selectPosition-1, passwordArray.length).join(''); //存储密码输入时的真实密码
                data.timerObj.timer1 = $timeout(function() {
                  data.radioPassWord = radioContent;
                },0);
                data.timerObj.timer2 = $timeout(function(){
                  data.radioPassWord = data.password.split('').map((i)=> '●').join('');
                },500); //0.5s变成纯密码框 内容为输入时的真实密码 方便于点击右侧眼睛查看密码
                data.timerObj.timer3 = $timeout(function() {
                    inputTarget.focus();
                    inputTarget.setSelectionRange(data.cursorPosition,data.cursorPosition);
                },501); //设置光标位置
              }else{//判断删除操作
                const delLength = data.password.length - length; //计算当前删除的长度
                data.password = data.password.slice(0, selectPosition) + data.password.slice(selectPosition+delLength, data.password.length);
              }
              data.cursorPosition = selectPosition;
            }
            

点击眼睛的函数



 const clearpass = function (txt) {
                const trunkData = data.password;
                txt==='text'?  (data.radioPassWord = trunkData , '' : ( data.radioPassWord = trunkData.split('').map((i)=> '●').join('') , data.isActive = false);
            };

监听光标数值变化触发的函数

  //我这里框架angular 其他框架小伙伴用其他方法实现监听例如 useeffect(()=>{
      //监听函数
  },[data.cursorPosition])
scope.$watch('data.cursorPosition', function(newVal){
              $timeout(function() {
                const inputTarget = document.querySelector('#userManagePwd');
                inputTarget && inputTarget.focus();
                inputTarget && inputTarget.setSelectionRange(newVal,newVal);
              },0); 
            }); //监听并更新当前数据位置