版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
引入问题:
我们在很多场景下都会有输入密码的情况,输入的时候,框右端会有一个眼睛,可以选择密码是否能看见。
在具体实现的过程中我发现眼睛的点击事件会和input的失去聚焦事件冲突,也就是说我们点击眼睛,切换明文的同时却失去了焦点,在正常输入下,输入框应该仍然保持聚焦状态。
当时写的代码是这样的:
input.onfocus = function() {
if (input.value == "Password") {
input.value = "";
input.type = "password";
}
names.style.display = "block";
see.style.display = "block";
}
var count = 1;
see.addEventListener('touchstart', function() {
if (count % 2) {
input.type = "text";
} else {
input.type = "password";
}
count++;
})
想要解决冲突,思路一:人为在点击事件时使其重新聚焦,思路二:取消失去焦点事件。
我们在点击事件里添加:
input.focus();
同时将事件监听的‘touchstart’改成了‘mousedown’,注意这里必须改成‘mousedown’,因为想要使用focus(),就要先‘mousedown’(鼠标按下)才行,就如同if和else一样,是配套的。原因我也不清楚,在网上也没有查到,(请教了同学告诉我)可能和计算机底层有关(先要鼠标按下,才能触发,可能是几个鼠标事件的隐式封装)。
做完这些我们发现效果仍然没有变化,这是因为focus()执行了,然后又被onblur()覆盖了效果。那我们再人为地控制一下发生顺序:
setTimeout(function(){
input.focus(); //使其聚焦
},1)
在onblur()发生之后的一毫秒,用focus()来覆盖。可以发现,这时候效果实现了,但细心观察,会发现点击眼睛的每个时刻,输入框都会闪一下。要解决这个问题,我们就在思路一的基础上结合思路二。
see.addEventListener('mousedown', function() {
input.onblur=null; //先让失去焦点事件为空
if (count % 2) {
input.type = "text";
} else {
input.type = "password";
}
count++;
setTimeout(function(){
input.focus(); //使其聚焦
input.onblur = blur; //恢复blur函数,保证以后的失去焦点事件可以正常运行
},1)
})
将失去焦点事件先置为空,后续效果实现后再恢复它的作用。
以上就很好地解决了这个问题。
附上完整的测试源代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style>
input{
text-align: center;
height:20px;
outline: none;
}
.name{
position:absolute;
top:8px;
left:12px;
}
#see{
position:absolute;
top:8px;
left:150px;
}
.seeon{
background-color: aquamarine ;
}
.seeno{
background-color: red ;
}
</style>
</head>
<body>
<input type="text" name="mima" id="pass" value="Password">
<div class="name" style="display: none;">密码</div>
<div id="see" class="seeon" style="display: none;">yan</div>
</body>
<script type="text/javascript">
var input = document.getElementById('pass');
input.onfocus = function() {
if (input.value == "Password") {
input.value = "";
input.type = "password";
}
names.style.display = "block";
see.style.display = "block";
}
function blur() {
if (input.value == "") {
input.value = "Password";
input.type = "text";
}
names.style.display = "none";
see.style.display = "none";
}
input.onblur = blur;
var see = document.getElementById('see');
var names = document.getElementsByClassName('name')[0];
var count = 1;
see.addEventListener('mousedown', function() {
input.onblur=null; //让失去焦点事件为空
if (count % 2) {
input.type = "text";
} else {
input.type = "password";
}
count++;
setTimeout(function(){
input.focus(); //使其聚焦
input.onblur = blur; //让失去焦点事件为blur函数
},1)
})
</script>
</html>