纯JS实现大小写锁定提示

1,687 阅读3分钟

背景

输入密码时经常忘记大小写已锁定,如果在大小写锁定能提示,这样对站点的体验会好很多。

实现

网上实现方式有很多种,参考其中一种记录下,以组件方式实现。

本来想输入文本框了聚焦就判断大小锁定的,但是查询了很久,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

思路

  1. 获取输入文本框对象,给这个文本框加一个父元素div并设置position: relative
  2. 创建一个包含提示信息的元素并设置position: absolute,加到div里,这样不管文本框在哪里,提示信息都会在文件框下面。
  3. 给文本框绑定事件,这里绑定keypress,监听字符输入;keyup,监听Caps Lock键。也可以只绑定一个keydown
  4. 根据事件判断大小写是否绑定了。大小写锁定有两种情况:
    • 输入字母的键值是65-90且shift键没有按住。
    • 输入字母的键值是97-122且shift键按住。
  5. 判断完大小写最后就是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);
            }
        })();

最后

匆匆而过,什么都没有,留点痕迹。