如何预览 beforeinput 事件的结果?

How to preview the result of a beforeinput event?

beforeinput 事件是否提供了一种方便的方式来预览建议修改的结果,以便在必要时可以阻止它以进行验证?

我不是在寻找其他方法来进行输入验证;我已经很清楚涉及 keypressinput 事件的方法,以及 HTML5 验证等。现在,我正在专门研究 beforeinput 活动以查看它提供的内容。

到目前为止,这是我想出的最好的:

document.getElementById("phone").addEventListener("beforeinput", function(e) {
    if(!/^(\d{0,7}|\d{3}-\d{0,4}|)$/.test(e.target.value + (e.data ?? ""))) {
        e.preventDefault();
    }
    return;
});
<input id="phone">

上述代码段中的文本字段应接受一个简单的 7 位数字 phone,在第 3 位数字后带有可选的破折号。

请注意,我将事件的 data 属性 附加到输入的当前值以创建修改值的预览。如果您仅按顺序输入输入,则此方法可以正常工作。但是,例如,如果您输入所有 7 位数字,然后返回到第 3 位数字之后并尝试插入破折号,则您不能这样做,因为验证假设您位于破折号所在的末尾无效的。如果您尝试替换或删除所选内容,则会出现其他问题。

解决这些问题需要准确的预览。有没有一种简单的方法可以从 beforeinput 活动中获得一个?

您必须获取 selectionStartselectionEnd 才能计算出有多少字符被删除/替换/等等,但是,非常简单:

document.getElementById("phone").addEventListener("beforeinput", function(e) {
    const nextVal = 
      e.target.value.substring(0, e.target.selectionStart) +
      (e.data ?? '') +
      e.target.value.substring(e.target.selectionEnd)
    ;
    console.log(nextVal)
    if(!/^(\d{0,7}|\d{3}-?\d{0,4}|)$/.test(nextVal)) {
        e.preventDefault();
    }
    return;
});
<input id="phone">