很多时候我们登录页面的密码框都是密文的,那么在用户输入时其实是不知道自己输入的是什么的,基于此如果当前输入是明文操作,同时我们在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);
}); //监听并更新当前数据位置