背景
输入密码时经常忘记大小写已锁定,如果在大小写锁定能提示,这样对站点的体验会好很多。
实现
网上实现方式有很多种,参考其中一种记录下,以组件方式实现。
本来想输入文本框了聚焦就判断大小锁定的,但是查询了很久,JS 不能实现获取键盘的状态,只能通过事件来触发了。只有字符输入后触发键盘事件才能知道是否大小锁定。这里就用到键盘事件了,键盘事件记得差不多了,这次也顺便总结下。
键盘事件
键盘事件有三个,按键,按下、松开,子符键三个事件。如下:
keydown按下任意键触发,按住不放一直触发此事件。keypress按下字符键(有打印输出的键)触发,按住不放一直触发此事件。keyup释放按键触发
这三个事件触发顺序是 keydown, keypress, keyup。 其中keydown, keypress在文本框变化前触发,keyup变化后触发。每个事件都有一个对象 event。
这个对象包含了很多属性,常用的有,shiftKey, altKey, ctrlKey对应键上三个功能键,还有keyCode属性,这个属性值与键盘值一一对应,其中数字字母的值又和ASCII对应。数字:48-57,大写字母:65-90,小写字母:97-122。在这有个关键的键就是Caps Lock 对应值是 20。
思路
- 获取输入文本框对象,给这个文本框加一个父元素
div并设置position: relative。 - 创建一个包含提示信息的元素并设置
position: absolute,加到div里,这样不管文本框在哪里,提示信息都会在文件框下面。 - 给文本框绑定事件,这里绑定
keypress,监听字符输入;keyup,监听Caps Lock键。也可以只绑定一个keydown。 - 根据事件判断大小写是否绑定了。大小写锁定有两种情况:
- 输入字母的键值是
65-90且shift键没有按住。 - 输入字母的键值是
97-122且shift键按住。
- 输入字母的键值是
- 判断完大小写最后就是
keyup判断Caps Lock键的切换是否提示咯。
代码
var CapsLock = (function(){
var isCapital = false;
function keyup(event, callback) {
if (event.keyCode === 20 && isCapital) {
callback && callback();
}
}
// keyCode a-z 97 - 122 A-Z 65 - 90
function keypress(event, callback) {
var keyCode = event.keyCode,
shiftKey = event.shiftKey || (keyCode === 16);
if ( ((keyCode >= 65 && keyCode <= 90) && !shiftKey) || // CapsLock 锁定 未按 shiftKey
((keyCode >=97 && keyCode <= 122) && shiftKey) ) { // CapsLock 锁定 已按 shiftKey
isCapital = true;
callback && callback('block');
} else {
callback && callback('none');
}
}
function bindEvent(element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent['on' + type] = handler;
} else {
element['on' + type] = handler;
}
}
function tipDivFn(tipEl) {
return function(display) {
var style = tipEl.style;
if (display) {
style.display = display;
} else {
style.display = style.display === 'none' ? '' : 'none';
}
}
}
function createTipEl(options) {
var div = document.createElement('div');
var style = div.style;
div.className = options.className || '';
div.innerText = options.msg || '大小已锁定';
style.display = 'none';
style.position = 'absolute';
style.backgroundColor = '#fff';
style.border = '1px solid #e2e2e2';
style.padding = '3px 8px';
style.marginTop = '5px';
return div;
}
function createWraper() {
var div = document.createElement('div');
div.style.position = 'relative';
div.style.display = 'inline-block';
return div;
}
function wraperFn(wrapEl, srcEl) {
var parentNode = srcEl.parentNode;
parentNode.insertBefore(wrapEl, srcEl);
wrapEl.appendChild(srcEl);
return srcEl;
}
function init(options) {
var tip = createTipEl(options),
wraper = createWraper();
var el = wraperFn(wraper, options.el);
wraper.appendChild(tip);
var toggleDisplay = tipDivFn(tip);
bindEvent(el, 'keypress', function(event) {
keypress(event, toggleDisplay);
});
bindEvent(el, 'keyup', function(event) {
keyup(event, toggleDisplay);
});
}
return function(options) {
if (!options) return;
if (!options.el) return;
init(options);
}
})();
最后
匆匆而过,什么都没有,留点痕迹。