我有一个常规的文本框:
<input type="text">
我使用jQuery来处理与键相关的事件:
$("input:text").keydown(function() {
// keydown code
}).keypress(function() {
// keypress code
}).keyup(function() {
// keyup code
});
用户专注于文本框并按下键盘上的各种键(通常的键:字母,数字,SHIFT,BACKSPACE,SPACE,......)。我需要检测用户何时按下将增加文本框值长度的键。例如,“A”键会增加它,“SHIFT”键不会。
我记得看过PPK的讲座,他提到了这两者之间的区别。它与事件有关 - keydown与keypress - 可能还有事件属性 - key,char,keyCode。
更新!
我需要知道keydown或keypress处理程序中的这些信息。我不能等待keyup事件发生。
为什么我需要这个:
我有一个文本框,其大小根据用户输入动态变化。您可以查看此演示:http://vidasp.net/tinydemos/variable-size-text-box.html
在演示中,我有一个keydown和keyup处理程序。 keyup处理程序根据输入值调整文本框大小。但是,keydown处理程序将大小设置为比输入值大1个字符。我这样做的原因是,如果我没有,那么角色将溢出文本框外,只有当用户放开键时,文本框才会展开。这看起来很奇怪。这就是我必须预测新角色的原因 - 在文字框中出现角色之前,我会在每个keydown上放大文本框ergo。正如您在演示中看到的,这种方法看起来很棒。
然而,问题是BACKSPACE和ARROW键 - 它们还会扩展keydown上的文本框,并且只有在keyup上才会更正文本框大小。
解决方法:
解决方法是手动检测BACKSPACE,SHIFT和ARROW键,并根据它进行操作:
// keydown handler
function(e) {
var len = $(this).val().length;
if (e.keyCode === 37 || e.keyCode === 39 ||
e.keyCode === 16) { // ARROW LEFT or ARROW RIGHT or SHIFT key
return;
} else if (e.keyCode === 8) { // BACKSPACE key
$(this).attr("size", len <= 1 ? 1 : len - 1);
} else {
$(this).attr("size", len === 0 ? 1 : len + 1);
}
}
这对于BACKSPACE,SHIFT,ARROW LEFT和ARROW RIGHT来说(并且看起来很棒)。但是,我希望有一个更强大的解决方案。
答案 0 :(得分:28)
我认为这将完成这项工作,或者如果不是非常接近,只需要进行微小的调整。你必须要记住的是,你无法可靠地告诉任何可能在keydown
或keyup
事件中输入的字符:所有必须在{{1处理程序。关键事件的权威资源是http://unixpapa.com/js/key.html
您还需要考虑此代码无法处理的粘贴。您需要具有单独的keypress
事件处理程序(尽管Firefox&lt; 3.0,Opera和非常旧的WebKit浏览器不支持此事件)。您需要在粘贴处理程序中使用计时器,因为在JavaScript中无法访问即将粘贴的内容。
paste
答案 1 :(得分:9)
我能找到的可能解决方案是检查事件中密钥的长度。
例如: -
<input type="text" id="testId" onkeyup="keyChecking(event)" />
<script type="text/javascript">
function keyChecking(event) {
if (event.key.length == 1) {
alert("key produced character " + event.key);
} else {
alert("Key DOES NOT produce character");
const alphabets = "AZaz09";
const key = event.key;
var notEvenASymbol = false;
for (let i = 0; i < key.length; i++) {
var charCode = key.charCodeAt(i);
if ((charCode >= alphabets.charCodeAt(0) && charCode <= alphabets.charCodeAt(1)) ||
(charCode >= alphabets.charCodeAt(2) && charCode <= alphabets.charCodeAt(3)) ||
(charCode >= alphabets.charCodeAt(4) && charCode <= alphabets.charCodeAt(5))
) {
notEvenASymbol = true;
console.log(charCode);
break;
}
}
if (notEvenASymbol) {
alert("Key DOES NOT produce even a symbol");
}
console.log(event.key);
}
}
</script>
因此,如果您按下任何字符/符号,event.key
将包含该字符,其长度将为1.如果按字符 V ,则event.key
将具有值 V ,但是如果按下回车键,则它将包含值 Enter ,如果按shift键然后按 Shift ,依此类推。因此,如果一个键没有产生一个字符,那么它的长度将大于1.
<强>更新强>
键盘中的某些特殊键产生符号,其长度可能大于1,因此我修改了代码,以便即使它不是符号也可以发出警报。例如: - 其长度为2.某些移动键盘具有此类符号的快捷键。
键盘中的非字符/符号键将始终是字母,数字字符或两者的组合,例如: - F2 , Shift 。
感谢@Vicky Chijwani引起对这种情况的关注。
答案 2 :(得分:6)
这是一个更简单的解决方案,对我来说效果很好:
if(String.fromCharCode(event.keyCode).match(/(\w|\s)/g)) {
//pressed key is a char
} else {
//pressed key is a non-char
//e.g. 'esc', 'backspace', 'up arrow'
}
这并不需要探测DOM元素(这会增加延迟和丑陋)。
答案 3 :(得分:4)
在keydown上,执行setTimeout 1毫秒,调用一个函数来检查/更改输入框的长度。
http://jsfiddle.net/rygar/e2wQM/
它似乎工作得很好,特别是在你的版本没有的几个地方(例如退格,CTRL + V,或选择一大堆文本并点击删除)
编辑:即使是延迟0毫秒的setTimeout似乎也能正常工作!
答案 4 :(得分:3)
你应该在keydown函数中使用属性keyEventArgs.Key,这将返回依赖于系统的数值。
这是一个链接,它具有不同浏览器和操作系统的不同密钥代码:
答案 5 :(得分:1)
这可能不是您要查找的方法,但您只需检查keydown函数中this.value.length
的值即可。返回值是添加新字符之前输入字段中文本的长度。因此,如果你在keyup函数中再次检查长度,如果用户按下了一个字符,它将会更大,但如果用户按下shift键则相同。
答案 6 :(得分:1)
我认为你在输入字段的长度上设置一个计数器,在这种情况下你不需要那么花哨,你可以继续将字段的长度分配给变量,当用户达到你的最大长度只允许他们像这样按下删除或退格:
$("input:text").keypress(function() {
var current = $(this).val().length;
if (current >= 130) {
if (e.which != 0 && e.which != 8) {
e.preventDefault();
}
}
}
您也可以使用当前变量来显示计数器,或者使用maxlength - current来计算剩余字符数的倒计时
答案 7 :(得分:1)
您的目标是保持文本框大于输入的文本。
我通过计划在文本框中为两个额外的字符(而不是一个)留出空间来实现这一目标。然后:
// pseudo-code....
old_len = textbox.value.length
keyUp function() {
var new_len = textbox.value.length
if (new_len != old_len) {
old_len = new_len
textbox.style.size = new_len + 2 // pseudo code.
}
}
上述优势在于您无需深入到密钥代码的下层世界。
答案 8 :(得分:1)
要在keydown
处理程序中检测按下的键是否产生单个unicode字符,可以对正则表达式使用ES6 unicode u
标志。
我们使用KeyboardEvent.key属性,该属性返回所按下键的值。根据文档:
如果按下的键具有打印的表示形式,则返回的值是一个非空的Unicode字符串,其中包含键的可打印表示形式。
inputElement.addEventListener("keydown", ({ key }) => {
if (/^.$/u.test(key)) {
// `key` matches a single unicode character
}
});
该解决方案无法处理粘贴...