在所有 JS 事件处理程序完成之前,浏览器不会处理文本框中的击键 (
<input type="text">
)。
不过,在我的应用程序中,我有一个嵌套在外部小部件内的文本框。外部小部件不知道文本框的存在,但如果文本框能够处理相同的击键,我想阻止它处理击键。所以我想做这样的事情:
function onInputKeyDown(e) {
const textbox = e.target as HTMLInputElement;
const selStart = textbox.selectionStart, selEnd = textbox.selectionEnd;
const content = textbox.textContent;
e.invokeDefault() // doesn't exist
if (selStart !== textbox.selectionStart || selEnd !== textbox.selectionEnd
|| content !== textbox.textContent)
e.stopPropagation();
}
我尝试用
e.preventDefault(); e.target.dispatchEvent(new KeyboardEvent('keydown', e))
模拟“invokeDefault”,但事实证明 dispatchEvent
不会导致默认行为,它只是调用事件处理程序(重新输入当前事件处理程序),因此文本字段不会改变。还有别的办法吗?
是的。翻转过来:
function onInputKeyDown(e) {
if (e.isTrusted) { // ignore synthetic events
const textbox = e.target as HTMLInputElement;
const selStart = textbox.selectionStart, selEnd = textbox.selectionEnd;
const content = textbox.textContent;
// Stop propagation to wait until the browser's default handler
// has processed the key and updated the text field. Then, if the
// text field has not changed, "resume" propagation with
// `dispatchEvent`. The new event will be "untrusted" so the
// browser's default processing will not happen again.
e.stopPropagation();
setTimeout(() => {
if (selStart === textbox.selectionStart
&& selEnd === textbox.selectionEnd
&& content === textbox.textContent) {
textbox.dispatchEvent(new KeyboardEvent('keydown', e as any));
}
});
}
}