检测可打印按键

21

我需要检测刚刚按下的键是否是可打印字符,例如字母、可能带重音的字符、数字、空格、标点符号等,还是不可打印的键,例如 ENTER、TAB 或 DELETE。

除了列出所有不可打印的键并希望不要遗漏任何键之外,是否有一种可靠的方法在 JavaScript 中实现此功能?

4个回答

37

幸运的是,在现代浏览器中这个任务要容易得多。您现在可以使用KeyboardEvent.key来通过其长度检测可打印的按键。

test.onkeydown = e => {
  let isPrintableKey = e.key.length === 1;
  alert(`Key '${e.key}' is printable: ${isPrintableKey}`);
}
<input id="test">

除此之外,您还可以从列表中检测任何其他按键,例如EnterDeleteBackspaceTab等。

这种方法更加可靠,因为与event.which不同,event.key已经标准化。


4
需要注意的是,在旧版浏览器中会出现不稳定的崩溃,因为 e.key 是未定义的。更安全的做法是检查 e.key && e.key.length === 1。即使在2018年,全球对于 key 的支持率仅有约80%:https://caniuse.com/#feat=keyboardevent-key - Thomas
4
很遗憾,它并不是很可靠。例如,在IE11中,如果你按下数学运算符键或小键盘上的逗号键,你会得到“除”,“乘”,“减”,“加”和“小数点”。 - BooFar
如果您在使用e.preventDefault()时要小心,因为这也会阻止键盘快捷键(例如CMD+R)。 - claviska
2
是否确实定义了可打印键的事件始终具有“键长度”为1?我可以想象在某些语言中,某些键可能会导致多个字符。 - JojOatXGME

18

昨天我回答了一个类似的问题。请注意,您必须使用 keypress 事件来处理与字符相关的任何内容;keydown 无法做到这一点。

顺便说一句,我认为 Enter 是可打印的,而这个函数也认为是。如果您不同意,可以修改它以过滤掉 whichkeyCode 属性设置为13的按键事件。

function isCharacterKeyPress(evt) {
    if (typeof evt.which == "undefined") {
        // This is IE, which only fires keypress events for printable keys
        return true;
    } else if (typeof evt.which == "number" && evt.which > 0) {
        // In other browsers except old versions of WebKit, evt.which is
        // only greater than zero if the keypress is a printable key.
        // We need to filter out backspace and ctrl/alt/meta key combinations
        return !evt.ctrlKey && !evt.metaKey && !evt.altKey && evt.which != 8;
    }
    return false;
}

var input = document.getElementById("your_input_id");
input.onkeypress = function(evt) {
    evt = evt || window.event;

    if (isCharacterKeyPress(evt)) {
        // Do your stuff here
        alert("Character!");
    }
});

MDN建议我们不要使用window.event属性,因为它是非标准的,可能存在不兼容性问题,链接。你有什么看法? - Segmentation
1
@分段: 我完全同意。我只会将它用于与IE <= 8的兼容性,这在2010年比现在更为重要。在任何现代浏览器中,window.event仅会在旧版IE中使用,因为事件对象将被传递到所有现代浏览器的事件处理程序中。 - Tim Down
2
keypress事件已被弃用:https://developer.mozilla.org/zh-CN/docs/Web/API/Document/keypress_event - Trevor
"which"事件也已被弃用:https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/which - Ferares

2
如果您需要为更改检测而识别可打印的密钥,因为用户更改了输入,则可以使用 oninput 事件。

2
let isPrintableKey = event.key.length === 1 || event.key === 'Unidentified';

如果您不包括:|| event.key === 'Unidentified',您的代码将无法在移动浏览器上运行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接