在beforeinput事件中,deleteWordForward和 deleteWordBackward的范围是如何确定的?

前端开发 2026-07-11

在处理 beforeinput 事件时,如何确定由 inputType"deleteWordForward""deleteWordBackward" 影响的范围?当用户执行 ctrl+Delete 还是 ctrl+Backspace 时,会出现这些情况。

目标输入的 selectionStartselectionEnd 位于光标的位置,而不是浏览器认定的“单词”边界。

对空白字符似乎有特殊处理。某些情况下,“单词”会包含前导或尾随的空格,但有时又不会(单个空格与多个空格之间的行为不同)。

这种行为在各浏览器之间是否标准化?它们是否都在使用我可以使用的某种正则表达式?如果是,是否有相关文档?

解决方案

在一个 contenteditable 元素中,你可以调用 InputEventgetTargetRanges() 方法,它返回一个 StaticRange 对象的列表:

document.querySelector("[contenteditable]").onbeforeinput = (evt) => {
  if (evt.inputType === "deleteWordForward" || evt.inputType === "deleteWordBackward") {
    for (const staticRange of evt.getTargetRanges()) {
      // StaticRange objects don't have the proper toString method
      // So we create a new Range. There might be a better way to do this
      const range = new Range();
      range.setStart(staticRange.startContainer, staticRange.startOffset);
      range.setEnd(staticRange.endContainer, staticRange.endOffset);
      console.log("deleting", range.toString());
    }
  }
  else console.log(evt.inputType);
}
<div contenteditable>Some text with word boundaries</div>

然而,当事件在input元素(或textarea)上触发时,该方法返回空数组,因为它用于处理对DOM的变更,而这些变更不会更新DOM。

document.querySelector("input").onbeforeinput =
document.querySelector("textarea").onbeforeinput = (evt) => {
  if (evt.inputType === "deleteWordForward" || evt.inputType === "deleteWordBackward") {
    console.log("# of ranges: ", evt.getTargetRanges().length);
  }
  else console.log(evt.inputType);
}
<textarea>Some text with word boundaries</textarea>
<input value="Some text with word boundaries">
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章