在beforeinput事件中,deleteWordForward和 deleteWordBackward的范围是如何确定的?
在处理 beforeinput 事件时,如何确定由 inputType 的 "deleteWordForward" 或 "deleteWordBackward" 影响的范围?当用户执行 ctrl+Delete 还是 ctrl+Backspace 时,会出现这些情况。
目标输入的 selectionStart 和 selectionEnd 位于光标的位置,而不是浏览器认定的“单词”边界。
对空白字符似乎有特殊处理。某些情况下,“单词”会包含前导或尾随的空格,但有时又不会(单个空格与多个空格之间的行为不同)。
这种行为在各浏览器之间是否标准化?它们是否都在使用我可以使用的某种正则表达式?如果是,是否有相关文档?
解决方案
在一个 contenteditable 元素中,你可以调用 InputEvent 的 getTargetRanges() 方法,它返回一个 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导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。