HTML <input type="number"> 的最佳设置,适​​用于移动设备

Best settings for HTML <input type="number">, for mobile devices

我已经阅读了许多其他问题,例如这些[1][2][3],但问题仍然存在。

我需要找到“最干净”的方式来为移动设备提供 HTML input 并且尊重所有这三个规则:

  1. 主要适用于数字、整数或浮点数

  2. 显示移动设备上的数字小键盘,Chrome Android 和 Safari iOS,以及没有奇怪的额外键

  3. 完全遵守 HTML5 条规则,由 W3C 验证器测试


我尝试了什么?

我遇到过这些解决方案,但它们都没有完全遵守上述三个规则。

解决方案 1

<input type="text" pattern="\d*" />

此解决方案尽管在 iOS 中工作并满足 W3C 验证器测试的 HTML 规则,但在 Chrome Android 中呈现了带有 QWERTY 键盘的完整键盘。

解决方案 2

<input type="number" pattern="\d*" />

此解决方案适用于 iOS 和 Android Chrome 这两个系统,在两个系统上都显示数字键盘,但它会抛出 W3C 验证器的 HTML 验证错误:

Attribute pattern is only allowed when the input type is email, password, search, tel, text, or url.

解决方案 3

<input type="number" />

此解决方案通过了 W3C HTML 测试,它在 Chrome 上显示良好,但在 iOS 键盘上显示了几个不需要的键

解决方案 4

我看到许多开发人员使用此解决方案

<input type="tel" />

但在Android Chrome中不允许点符号.(因此没有浮点数),并且按键有字母,这是多余的

如评论中所述,因为没有直接的方法来完成此操作,最好的解决方法是始终使用 input type="number" 和 if 语句,如果设备是 iOS device 然后代码将适当的模式属性添加到类型。

对于您的特定任务,我有非凡的解决方案:我们采用 type="text" 和模式的最佳解决方案,然后添加更正类型属性的 JavaScript。我们这样做是为了通过 W3 验证器。

解决方法

// iOS detection from: whosebug.com/a/9039885 with explanation about MSStream
if(/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream)
{
    var inputs = document.querySelectorAll('input[type="number"]');
    for(var i = inputs.length; i--;)
        inputs[i].setAttribute('pattern', '\d*');
}
<input type="number" />

我的解决方案尊重您的所有三个规则(包括 W3 验证程序)。

但我不得不提一下,在 iOS 上的这种情况下(带有模式)我们无法使用数字键盘输入浮点数,因为在 iOS 上我们没有任何键盘数字包括点。在 Android 我们有这种可能性。如果你想拥有带浮点数的数字小键盘,那么你必须编写 for iOS 额外的解决方案,如下所示:

 <input type="number" />

根据@Alex Charters 的建议,我提出了这个解决方案,使用 jQuery,这似乎更快,也更优雅。

将这段代码添加到页面的"onload"

//shows numeric keypad on iOS mobile devices
if(getMobileOperatingSystem() === "iOS"){
    $('input[type="number"]').attr("pattern", "\d*");
}

操作系统检测函数是这样的,taken from other SO answer:

/**
 * Determine the mobile operating system.
 * This function returns one of 'iOS', 'Android', 'Windows Phone', or 'unknown'.
 *
 * @returns {String}
 */
function getMobileOperatingSystem() {
  var userAgent = navigator.userAgent || navigator.vendor || window.opera;

      // Windows Phone must come first because its UA also contains "Android"
    if (/windows phone/i.test(userAgent)) {
        return "Windows Phone";
    }

    if (/android/i.test(userAgent)) {
        return "Android";
    }

    // iOS detection from: 
    if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
        return "iOS";
    }

    return "unknown";
}

我测试了,它符合三个规则。当操作系统为 iOS 时,它会添加 pattern 属性。默认情况下我不这样做,因为我意识到根据输入的数量,上述代码需要一些时间来处理,因此它只在假定 iOS 操作系统时运行。

还有一个选择:<input type="text" inputmode="numeric" pattern="[0-9]*">

Why the GOV.UK Design System team changed the input type for numbers绝对值得一读。

请注意,如果您仍想走 <input type="number"> 路线,第 4 点有一个很好的解决方案 - 滚动 - Turn Off Number Input Spinners.

每种解决方案似乎都有一些缺点,我认为最合适的解决方案取决于您要收集的数据类型、护照号码、某人的年龄和物品数量。

我发现此解决方案的缺点是:

  • 输入值现在是文本而不是数字,因此您可能需要在 JS 中进行额外的解析。
  • 在桌面浏览器上,输入将接受字母字符,表单将无效,但您需要处理此问题并显示相关的用户反馈(如果使用框架,可能是自动的)
  • 它仅受现代移动浏览器支持,例如iOS 12.2(2019 左右)上的 Safari(参见 spec

我遇到了这个问题,以下两个解决方案似乎是回答这个问题的最佳方式

第一个解决方案非常简单,适用于 Android 和 IOS。此解决方案将在桌面上有一个向上和向下按钮,并且在 Android 和 IOS;

上只有一个数字键盘

<form action="" method="">
<input pattern="[0-9]*"/>
</form>

此解决方案的唯一问题是,用户将无法输入 ,(逗号)或 . (句点),因为它们不会出现在键盘上。如果您更改模式,上述内容将不再适用于 IOS。

并非所有浏览器都支持第二种解决方案,但似乎适用于所有现代浏览器,包括 safari 15.1。

<input inputmode="numeric" pattern="[0-9]*" type="text"/>

查看哪些浏览器支持inputmodeclick here

祝你好运