已停用的 `keypress` DOM 事件的替代方法

53

根据MDN文章keypress事件已被弃用:

输入图像描述

但我无法在其他地方找到任何关于是否应该在新项目中使用此事件的信息。 如果不应该使用,请问有什么替代方案?

能否有人提供一些见解?


2
@Barmar 对,我知道“已弃用”是什么意思。 但是正如我在问题中提到的那样,我正在寻找有关此的任何进一步信息,例如推荐的替代方法(已明确说明)。 - Alexander Abakumov
那是我几分钟前发布的答案中所包含的。 - Barmar
我猜替换是 keyup https://developer.mozilla.org/zh-CN/docs/Web/Events/keyup - Mohammed
@Barmar 我看到了。只是回复你的评论。 - Alexander Abakumov
1
@Mohammed,“keyup” 有些不同,我不确定它是否是预期的替代。从 Barmar 的 回答来看,似乎应该使用 beforeinput - Alexander Abakumov
4个回答

28

由于该事件已被废弃,您应避免在新代码中使用它,并计划从旧代码中删除它。《W3C 规范》对于已废弃的特性表示如下:

标记为已废弃的特性被包括在规范中作为对老实现或规范的参考,但是这些特性是可选的且不推荐使用的。只有那些存在或正在进行替代的特性必须在本规范中被废弃。对于尚未支持该特性的实现,可以出于与现有内容向后兼容的原因来实现已废弃的特性,但创建内容的内容作者不应使用已废弃的特性,除非没有其他解决用例的方法。引用本规范的其他规范不应使用已废弃的特性,而应指向其被废弃的替代方案。在本规范中标记为已废弃的特性应该在未来的规范中被删除。

keypress 事件 的规范说明如下:

警告:虽然此规范仍定义了键盘按下事件类型以供参考和完整性,但已不建议使用该事件类型。在编辑上下文中,作者可以订阅beforeinput事件。

您还可以使用keydown和/或keyup事件。请参见keyup、keydown、keypress和input事件之间有什么区别?

然而,由于beforeinput的支持还不够完善,如果这些其他事件都不适合您的用例,那么您现在仍需继续使用keypress(这是规范中“除非没有其他解决方案来解决用例”这个例外)。


9
没错,但 keydown 有一点不同。在这个问题中,我正在尝试找出使用 keypress 不再适用时的精确替代方法。如果规范作者打算将 beforeinput 用于此目的,我认为它应该更加精确匹配。 - Alexander Abakumov
7
完全同意你的看法。非常失望keypress被这么早地废弃,但实际上在现实世界中并没有直接替代方案,这让开发人员不得不自己做出艰难的选择。 - Alexander Abakumov
2
@AlexanderAbakumov - 这就是弃用的目的,警告用户避免使用该功能,因为它存在互操作性问题。现实情况是,当然,没有主流浏览器会停止实现keypress,因为这样做会破坏大量现有网站。目前它意味着你应该开始考虑如何使用keydown、beforeinput、input和keyup事件的组合。你可以尝试检测beforeinput支持并在可用时使用它,否则回退到keypress。 - Alohci
9
@Alohci 谢谢。为了让事情更加清楚,我并不反对这种废弃的做法。但是这个特定情况中真正令人讨厌的部分是它被过早地废除了。只有在提供一个实际可行且具有可比较努力水平的替代品之后,废弃才是好的。我相信没有任何开发团队会尝试去搞乱 keydowninputkeyup 事件,因为 beforeinput 还没有可用,而他们的 app 中已经使用了 keypress(这是限制 inputs 字符集最流行的选项)。 - Alexander Abakumov
8
这个答案没有涉及到特定的用例,比如在Windows中使用Alt键序列时,会产生一个按键事件(例如,对于Alt+137,会得到键码“ë”),但不会出现“keyup”或“keydown”的事件。只有单独的键“1”、“3”和“7”被报告为“keyup”和“keydown”,但“ë”则不是。因此,尽管他们可以放弃这种方法,但除非他们提供一个真正的替代方案,否则我们这些天真的前端开发人员别无选择,只能使用“keypress”。 - Mr Lister
显示剩余9条评论

8
 const handleKeyDown = (e: any) => {
  if (e.code === "Enter") {
  triggerBusqueda(e.target.value);
  }
};

onKeyDown={handleKeyDown}

你可以使用这段代码,它非常有效。

2

onKeyPress已经过时。

在此输入图像描述

它已被onKeyDown取代。

onKeyPress={(e) => {
  if (e.key === 'Enter') {
    createInvitationF()
  }
}}

被替换为
onKeyDown={(e) => {
  if (e.key === 'Enter') {
    createInvitationF()
  }
}}

-9

除非(你真是太不负责任了)你或者你使用的某个东西一直在任意地破坏事件冒泡,否则这并不是很难解决的问题。

像这样简单而又强大的实用程序正是为什么你应该只对 HTML 的孤立节点叶子进行操作。

在那些必须防止 keydown 冒泡的情况下,你可以简单地将以下内容包装在一个函数中,该函数以参数代替 document.body,并在停止冒泡的点上应用它,如果你仍然希望 'keypress2' 事件对该 HMTL 可用。

const keyBlacklist = [
    'Shift',
    'Alt',
    'Control',
    'Meta'
];

document.body.addEventListener('keydown',(e)=>{
    if(keyBlacklist.indexOf(e.key) === -1){
        const newKeyPress = new CustomEvent('keypress2',{detail:e});
        e.target.dispatchEvent(newKeyPress);
    }
});

document.body.addEventListener('keypress2',e=>{console.log(e.detail);});

8
这个回答没有涉及特定用例,例如在Windows中使用Alt键序列的情况,其中产生的按键码(例如Alt + 137时的 ë)只会得到一个 keypress 事件,而不是 keyupkeydown 事件。只有单独的按键 137 会被报告为 keyup 和 keydown,但不包括 ë。所以他们可以随便弃用 keypress,但除非他们提供一个真正的替代方案,否则我们这些天真的前端开发人员别无选择。 - Mr Lister

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