你如何告诉如果大写锁定使用JavaScript?

但有一个警告:我做了谷歌,我能找到的最好的解决方案是附加一个onkeypress事件到每个输入,然后检查每次按下的字母是否大写,如果是,然后检查shift是否也按下。如果不是,那么caps lock必须是打开的。这感觉真的很脏,而且…浪费——肯定有比这更好的办法吗?


当前回答

这是一个自定义的jquery插件,使用jquery ui,由这个页面上的所有好主意和工具提示小部件组成。大写锁定消息是自动应用于所有密码框,不需要更改您当前的html。

自定义插件代码…

(function ($) {
    $.fn.capsLockAlert = function () {
        return this.each(function () {
            var capsLockOn = false;
            var t = $(this);
            var updateStatus = function () {
                if (capsLockOn) {
                    t.tooltip('open');
                } else {
                    t.tooltip('close');
                }
            }
            t.tooltip({
                items: "input",
                position: { my: "left top", at: "left bottom+10" },
                open: function (event, ui) {
                    ui.tooltip.css({ "min-width": "100px", "white-space": "nowrap" }).addClass('ui-state-error');
                    if (!capsLockOn) t.tooltip('close');
                },
                content: function () {
                    return $('<p style="white-space: nowrap;"/>')
                        .append($('<span class="ui-icon ui-icon-alert" style="display: inline-block; margin-right: 5px; vertical-align: text-top;" />'))
                        .append('Caps Lock On');
                }
            })
            .off("mouseover mouseout")
            .keydown(function (e) {
                if (e.keyCode !== 20) return;
                capsLockOn = !capsLockOn;
                updateStatus();
            })
            .keypress(function (e) {
                var kc = e.which; //get keycode

                var isUp = (kc >= 65 && kc <= 90) ? true : false; // uppercase
                var isLow = (kc >= 97 && kc <= 122) ? true : false; // lowercase
                if (!isUp && !isLow) return; //This isn't a character effected by caps lock

                // event.shiftKey does not seem to be normalized by jQuery(?) for IE8-
                var isShift = (e.shiftKey) ? e.shiftKey : ((kc === 16) ? true : false); // shift is pressed

                // uppercase w/out shift or lowercase with shift == caps lock
                if ((isUp && !isShift) || (isLow && isShift)) {
                    capsLockOn = true;
                } else {
                    capsLockOn = false;
                }
                updateStatus();
            });
        });
    };
})(jQuery);

适用于所有密码元素…

$(function () {
    $(":password").capsLockAlert();
});

其他回答

Many existing answers will check for caps lock on when shift is not pressed but will not check for it if you press shift and get lowercase, or will check for that but will not also check for caps lock being off, or will check for that but will consider non-alpha keys as 'off'. Here is an adapted jQuery solution that will show a warning if an alpha key is pressed with caps (shift or no shift), will turn off the warning if an alpha key is pressed without caps, but will not turn the warning off or on when numbers or other keys are pressed.

$("#password").keypress(function(e) { 
    var s = String.fromCharCode( e.which );
    if ((s.toUpperCase() === s && s.toLowerCase() !== s && !e.shiftKey)|| //caps is on
      (s.toUpperCase() !== s && s.toLowerCase() === s && e.shiftKey)) {
        $("#CapsWarn").show();
    } else if ((s.toLowerCase() === s && s.toUpperCase() !== s && !e.shiftKey)||
      (s.toLowerCase() !== s && s.toUpperCase() === s && e.shiftKey)) { //caps is off
        $("#CapsWarn").hide();
    } //else upper and lower are both same (i.e. not alpha key - so do not hide message if already on but do not turn on if alpha keys not hit yet)
  });

有一个更简单的检测caps-lock的解决方案:

function isCapsLockOn(event) {
    var s = String.fromCharCode(event.which);
    if (s.toUpperCase() === s && s.toLowerCase() !== s && !event.shiftKey) {
        return true;
    }
}

这里最上面的答案对我来说不适用,有几个原因(未注释的代码带有死链接和不完整的解决方案)。所以我花了几个小时尝试了所有的版本,得到了我能得到的最好的:这里是我的,包括jQuery和非jQuery。

jQuery

注意,jQuery规范化了事件对象,因此缺少了一些检查。我还将其缩小到所有密码字段(因为这是需要它的最大原因),并添加了一条警告消息。这已经在Chrome, Mozilla, Opera和IE6-8中进行了测试。稳定的,捕获所有的大写锁状态,除非数字或空格被按下。

/* check for CAPS LOCK on all password fields */
$("input[type='password']").keypress(function(e) {

    var $warn = $(this).next(".capsWarn"); // handle the warning mssg
    var kc = e.which; //get keycode
    var isUp = (kc >= 65 && kc <= 90) ? true : false; // uppercase
    var isLow = (kc >= 97 && kc <= 122) ? true : false; // lowercase
    // event.shiftKey does not seem to be normalized by jQuery(?) for IE8-
    var isShift = ( e.shiftKey ) ? e.shiftKey : ( (kc == 16) ? true : false ); // shift is pressed

    // uppercase w/out shift or lowercase with shift == caps lock
    if ( (isUp && !isShift) || (isLow && isShift) ) {
        $warn.show();
    } else {
        $warn.hide();
    }

}).after("<span class='capsWarn error' style='display:none;'>Is your CAPSLOCK on?</span>");

没有jQuery

其他一些无jquery的解决方案缺少IE的备用方案。@Zappa打了补丁。

document.onkeypress = function ( e ) {
    e = (e) ? e : window.event;

    var kc = ( e.keyCode ) ? e.keyCode : e.which; // get keycode
    var isUp = (kc >= 65 && kc <= 90) ? true : false; // uppercase
    var isLow = (kc >= 97 && kc <= 122) ? true : false; // lowercase
    var isShift = ( e.shiftKey ) ? e.shiftKey : ( (kc == 16) ? true : false ); // shift is pressed -- works for IE8-

    // uppercase w/out shift or lowercase with shift == caps lock
    if ( (isUp && !isShift) || (isLow && isShift) ) {
        alert("CAPSLOCK is on."); // do your thing here
    } else {
        // no CAPSLOCK to speak of
    }

}

注意:查看@Borgar, @Joe Liversedge和@Zappa的解决方案,以及@Pavel Azanov开发的插件,我没有尝试过,但是个好主意。如果有人知道如何扩展a- za -z之外的范围,请编辑掉。此外,这个问题的jQuery版本被关闭为重复,所以这就是为什么我在这里发布这两个问题。

jQuery:

$('some_element').keypress(function(e){
       if(e.keyCode == 20){
             //caps lock was pressed
       }
});

这个jQuery插件(代码)实现了与Rajesh的回答相同的想法,更简洁一点。

您可以使用“是大写字母,没有shift按下”来检测caps锁定,使用在文档上的按键捕获。但是,您最好确保在事件到达文档上的处理程序之前,没有其他按键处理程序弹出事件气泡。

document.onkeypress = function ( e ) {
  e = e || window.event;
  var s = String.fromCharCode( e.keyCode || e.which );
  if ( (s.toUpperCase() === s) !== e.shiftKey ) {
    // alert('caps is on')
  }
}

您可以在支持捕获阶段的浏览器中捕获事件,但这似乎没有意义,因为它不会在所有浏览器上工作。

我想不出任何其他方法来检测caps锁定状态。检查很简单,如果输入了不可检测的字符,那么……那么检测就没有必要了。

去年有一篇关于24种方法的文章。非常好,但缺乏国际字符支持(使用toUpperCase()来解决这个问题)。