1

我有一个<input type="number" />并且我想防止输入任何非数字字符。

<input id="app-client-id" type="number" pattern="[0-9]+" />

为了防止常规按键,这可以通过

const validKeys = new Set([
    'home',
    'end',
    'pageup',
    'pagedown',
    'delete',
    'backspace',
    'arrowleft',
    'arrowright',
]);

function isValidKeypress(e) {
    // numeric characters
    if (e.charCode >= 48 && e.charCode <= 57) {
        return true;
    }

    if (e.key && validKeys.has(e.key.toLowerCase())) {
        return true;
    }

    // for allowing select all, copy, and paste
    if (e.ctrlKey) {
        return true;
    }

    return false;
}

$('#app-client-id').on('keypress', isValidKeypress);

现在剩下的就是防止粘贴非数字字符,或者理想情况下,过滤掉非数字字符。

function filterPastedText(e) {
    let clipboardData = e.originalEvent.clipboardData,
        text = clipboardData.getData('text').replace(/[^\d]/g, '');
    clipboardData.setData('text', text);
}

$('#app-client-id').on('paste', filterPastedText);

这适用于 Chrome/Webkit。 但是,在 Firefox 中,它会在以下位置引发错误setData()

NoModificationAllowedError:不允许修改此文档

关于如何告诉浏览器允许调用的任何想法setData()

如果这种方法不存在,有没有办法在不使用 hiddeninput的情况下手动将过滤后的值“粘贴”到正确的光标位置(并替换选定的文本,如果有的话)?无论是否选择了文本,我都无法检测光标在元素中的位置;总是。textareainputmyInput.selectionStartnull

编辑

事实证明,调用setData()实际上在 Chrome 中不起作用。将类型设置为自动过滤掉number“e”、“-”和“.”之外的非数字字符,以及我正在测试它的字符串,不包含任何这些字符。调用只是默默地失败。setData()

4

1 回答 1

0

您可以采取的一种方法是简单地允许不需要的字符暂时进入输入字段,但监视oninput事件,检查每个事件中不需要的字符的输入字段的值,如果找到,则使用过滤的更新输入字段其值的版本。

更新:

我发现,具有讽刺意味的是,当您创建inputastype="number"而不是type="text". 为什么?因为当您使用type="number"非数字输入时,仍然可以跳过,但是您不会在输入字段的值中看到这些字符——该值要么是有效数字,要么是空字符串。这使您没有机会过滤输入并保留可能存在的有效数字。

我创建了一个 Plunker,我自己尝试将文本字段限制为数字输入的当前状态:http ://plnkr.co/edit/xsVQG1EzsDLMt8POCJUX?p=preview

于 2018-04-29T23:43:43.520 回答