如果允许点击事件通过,则获取“keypress”上文本框的最终文本

Get the final text of a textbox on `keypress` if the click event is allowed to go through

我希望能够根据输入字符时文本框的文本内容来阻止用户将字符输入文本框。

最初的想法是做这样的事情:

<input type="text" id="test" />

document.getElementById("test").addEventListener("keypress", (e) => {
    // Get the current text
    const currentText = e.target.value;

    // Get the new char entered by the user
    const newChar = String.fromCharCode(e.keyCode);

    // The problem is that we don't know where the cursor is, 
    // i.e. we CANNOT guarantee that the new text will be:
    const newText = `${currentText}${newChar}`;
    
    // ...because that assumes the cursor is at the end of the current text

    // I want to check that newText is valid before allowing the event to go through
    if(!someCustomCheck(newText)) {
        e.preventDefault();
    }
});

评论解释了我的问题,但这里有一个进一步的例子:假设我们有一个输入允许添加 2 个小数位的数字:

我无法在单击事件中的 event 中找到光标位置,也无法在 e.target 中看到 属性(就像在 keyup 事件)给出输入的最终文本。

有办法吗?

对于未来的读者,答案是使用 e.target.selectionStart。这使您可以找到用户按下按键的位置,并允许您构建允许输入的最终字符串。

const newChar = String.fromCharCode(e.keyCode);
const cursorPos = e.target.selectionStart;
const inputText = e.target.value;

const proposedNewText = `${inputText.slice(0, cursorPos)}${newChar}${inputText.slice(cursorPos, inputText.length)}`;

值得注意的是,如果用户 select 编辑了一系列文本(即其中包含 5 个字符的文本框,然后用户单击并拖动到 select第 2 个 -> 第 5 个字符)然后键入。在这种情况下,您必须获得开始和结束光标位置(e.target.selectionStarte.target.selectionEnd)和 .splice() 字符串,添加用户的新字符。

然后您遇到了一个问题,即通过更改输入的值(使用 e.target.value = newText),光标会自动跳转到文本的末尾。根据您的用例,需要考虑很多因素。

希望这有助于指出正确的方向。