我可以让浏览器默认处理程序在事件传播之前运行吗?

问题描述 投票:0回答:1

在所有 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
不会导致默认行为
,它只是调用事件处理程序(重新输入当前事件处理程序),因此文本字段不会改变。还有别的办法吗?

javascript typescript
1个回答
0
投票

是的。翻转过来:

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));
            }
        });
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.