对 HTML 数字输入行为异常的自定义验证

Custom Validation on HTML Number Input Misbehaving

本文关键字:自定义 验证 异常 HTML 数字输入      更新时间:2023-09-26

在组装一个小型 Web 应用程序时,我试图确保最终用户无法在可以容纳签名浮点数的数字字段中放置无效字符。 我正在使用 Dojo 搜索应用的 CSS 类(在本例中为 ogInputNumber ),并在输入、键控和模糊中设置事件。

理想情况下,我希望输入type="number",并且只允许数字、连字符(用于有符号浮点数)和句点字符充当小数位。 如果用户包含多个连字符或句点字符,则 JS 应截断输入中的第二个无效字符及其后的所有字符。 不幸的是,根据输入是type="number"还是type="text",JS的行为会有所不同。

对于type="text",如果我尝试输入文本2.6a2.6很好,但a被捕获在输入事件中并阻止出现在输入中。 这是所需的行为,但我希望输入type="number"以便显示数字微调器并便于在移动设备上使用(因此默认情况下会打开数字键盘)。

对于type="number",如果我尝试输入文本2.6a,则允许保留2.6,但是一旦键入a,整个字段就会被清除。 这将防止任何无效字符,但它令人讨厌的过度热心。 我已经在Chrome,Firefox,IE11和Opera上复制了这种行为。

任何人都可以提供任何建议,说明为什么JS在具有type="text"的输入和具有type="number"的输入之间运行不同?

.HTML:

<p>
    <label for="numberInput1">Text Input</label>
    <input id="numberInput1" class="ogInputNumber" type="text" />
</p>
<p>
    <label for="numberInput2">Number Input</label>
    <input id="numberInput2" class="ogInputNumber" type="number" />
</p>

.JS:

// Checks number input fields for proper formatting
require(["dojo/domReady!", "dojo/on", "dojo/query"],
function (ready, on, query) {
    query(".ogInputNumber").forEach(function (node) {
        // Replace all the non-numeric, non-period, and non-hyphen characters with nothing while the user is typing
        on(node, "input, keyup", function () {
            this.value = this.value.replace(/[^'d'.-]/g, '');
        });
        // When the user leaves the input, format it properly as a signed float (or zero if it's something weird)
        on(node, "blur", function () {
            try {
                if (this.value) {
                    this.value = parseFloat(this.value).toString();
                } else {}
            } catch (error) {
                this.value = 0;
            }
        });
    });
});

工作 JSFiddle: http://jsfiddle.net/etehy6o6/1/

我认为

这是数字输入类型的默认行为,但我不确定。认为输入不应让用户输入任何不是数字的内容是合乎逻辑的,因此它会在触发 keyup 事件之前清除所有值。

因此,要保留最后一个有效值,请在事件范围之外声明一个变量,并将其设置为由于键输入无效而未清除的替换值。

使用小提琴中的代码:

已编辑,因为解决了评论中的错误

.HTML

<!-- I asigned default values to test other scenarios -->
<p>
    <label for="numberInput1">Text Input</label>
    <input id="numberInput2" class="ogInputNumber" type="text" value="3.1416" />
</p>
<p>
    <label for="numberInput">Number Input</label>
    <input id="numberInput" class="ogInputNumber" type="number" value="3.1416" />
</p>

爪哇语

// Checks number input fields for proper formatting
require(["dojo/domReady!", "dojo/on", "dojo/query"],
function (ready, on, query) {
    query(".ogInputNumber").forEach(function (node) {
        var validValue = this.value;
        // Replace all the non-numeric, non-period, and non-hyphen characters with nothing while the user is typing
        on(node, "input, keyup", function () {
            if (this.value == '' && validValue.length > 1) {
                this.value = validValue;
            }
            this.value = this.value.replace(/[^'d'.-]/g, '');
            validValue = this.value;
        });
        // When the user leaves the input, format it properly as a signed float (or zero if it's something weird)
        on(node, "blur", function () {
            try {
                if (this.value) {
                    this.value = parseFloat(this.value).toString();
                } else {}
            } catch (error) {
                this.value = 0;
            }
        });
    });
});