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

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


当前回答

这里最上面的答案对我来说不适用,有几个原因(未注释的代码带有死链接和不完整的解决方案)。所以我花了几个小时尝试了所有的版本,得到了我能得到的最好的:这里是我的,包括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版本被关闭为重复,所以这就是为什么我在这里发布这两个问题。

其他回答

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

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

我写了一个名为capsLock的库,它完全是你想要它做的。

只要把它包括在你的网页上:

<script src="https://rawgit.com/aaditmshah/capsLock/master/capsLock.js"></script>

然后像这样使用它:

alert(capsLock.status);

capsLock.observe(function (status) {
    alert(status);
});

参见演示:http://jsfiddle.net/3EXMd/

按下“Caps Lock”键更新状态。它只使用Shift键来确定Caps Lock键的正确状态。最初状态为false。所以要小心。

反应

onKeyPress(event) { 
        let self = this;
        self.setState({
            capsLock: isCapsLockOn(self, event)
        });
    }

    onKeyUp(event) { 
        let self = this;
        let key = event.key;
        if( key === 'Shift') {
            self.shift = false;
        }
    }

    <div>
     <input name={this.props.name} onKeyDown={(e)=>this.onKeyPress(e)} onKeyUp={(e)=>this.onKeyUp(e)} onChange={this.props.onChange}/>
                {this.capsLockAlert()}
</div>

function isCapsLockOn(component, event) {
        let key = event.key;
        let keyCode = event.keyCode;

        component.lastKeyPressed = key;

        if( key === 'Shift') {
            component.shift = true;
        } 

        if (key === 'CapsLock') {
            let newCapsLockState = !component.state.capsLock;
            component.caps = newCapsLockState;
            return newCapsLockState;
        } else {
            if ((component.lastKeyPressed !== 'Shift' && (key === key.toUpperCase() && (keyCode >= 65 && keyCode <= 90)) && !component.shift) || component.caps ) {
                component.caps = true;
                return true;
            } else {
                component.caps = false;
                return false;
            }
        }
    }

还有另一个版本,清晰而简单,处理移位的capsLock,并且不受ascii限制,我认为:

document.onkeypress = function (e)
{
    e = e || window.event;
    if (e.charCode === 0 || e.ctrlKey || document.onkeypress.punctuation.indexOf(e.charCode) >= 0)
        return;
    var s = String.fromCharCode(e.charCode); // or e.keyCode for compatibility, but then have to handle MORE non-character keys
    var s2 = e.shiftKey ? s.toUpperCase() : s.toLowerCase();
    var capsLockOn = (s2 !== s);
    document.getElementById('capslockWarning').style.display = capsLockOn ? '' : 'none';
}
document.onkeypress.punctuation = [33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,91,92,93,94,95,96,123,124,125,126];

编辑:意义上的capsLockOn被逆转,多,固定。

编辑#2:在进一步检查之后,我做了一些更改,不幸的是,代码更详细了一些,但它可以适当地处理更多的操作。

Using e.charCode instead of e.keyCode and checking for 0 values skips a lot of non-character keypresses, without coding anything specific to a given language or charset. From my understanding, it's slightly less compatible, so older, non-mainstream, or mobile browsers may not behave as this code expects, but it's worth it, for my situation anyway. Checking against a list of known punctuation codes prevents them from being seen as false negatives, since they're not affected by caps lock. Without this, the caps lock indicator gets hidden when you type any of those punctuation characters. By specifying an excluded set, rather than an included one, it should be more compatible with extended characters. This is the ugliest, special-casiest bit, and there's some chance that non-Western languages have different enough punctuation and/or punctuation codes to be a problem, but again it's worth it IMO, at least for my situation.

最近在hashcode.com上有一个类似的问题,我创建了一个jQuery插件来处理它。它还支持对数字的大写锁定识别。(在标准德语键盘布局上,大写锁定对数字有影响)。

你可以在这里查看最新版本:jquery.capsChecker