JavaScript会在Firefox中过滤粘贴事件中的非数字

时间:2018-04-29 23:35:38

标签: javascript html clipboarddata

我有一个<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()的任何想法?

如果这种方法不存在,有没有办法手动&#34;粘贴&#34;过滤后的值进入右侧光标位置的input(并替换所选文本,如果有的话)而不使用隐藏的textarea ?无论是否选择了文本,我都无法在input元素中检测光标的位置; myInput.selectionStart始终为null

修改

事实证明,调用setData()并不适用于Chrome。将类型设置为number会自动过滤掉非数字字符,但&#39;&#39; - &#39; - &#39;和&#39;。& #39;,以及我正在测试它的字符串,不包括任何这些字符。调用setData()只是无声地失败。

1 个答案:

答案 0 :(得分:0)

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

<强>更新

我发现,具有讽刺意味的是,当您将input创建为type="number"而非type="text"时,将键盘输入限制为数字会更加困难。为什么?因为当您使用type="number"时,非数字输入仍然可以滑过,但您无法在输入字段的值中看到这些字符 - 该值是有效数字,或者它是空字符串。这使您无法过滤输入并保留可能存在的有效数字。

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