如何预览 beforeinput 事件的结果?

Doc*_*cto 11 javascript validation dom-events

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;
});
Run Code Online (Sandbox Code Playgroud)
<input id="phone">
Run Code Online (Sandbox Code Playgroud)

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

请注意,我正在附加事件的data属性附加到输入的当前值以创建修改值的预览。如果您仅按顺序输入输入,则效果很好。但是,例如,如果您输入所有 7 位数字,然后用箭头返回到第三个数字之后并尝试插入破折号,则您将无法执行此操作,因为验证假设您位于破折号所在的末尾无效的。如果您尝试替换或删除选择,则会出现其他问题。

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

dav*_*ave 9

你必须得到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;
});
Run Code Online (Sandbox Code Playgroud)
<input id="phone">
Run Code Online (Sandbox Code Playgroud)