【问题标题】:Best settings for HTML <input type="number">, for mobile devicesHTML <input type="number"> 的最佳设置,适​​用于移动设备
【发布时间】:2019-01-10 15:35:49
【问题描述】:

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

我需要找到一种“最干净”的方式来为移动设备创建一个 HTML input 并遵守所有这三个规则:

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

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

  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 验证错误:

pattern 属性仅在输入类型为电子邮件、密码、搜索、电话、文本或 url 时才允许使用。

解决方案 3

<input type="number" />

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

解决方案 4

我看到很多开发者都在使用这个解决方案

<input type="tel" />

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

【问题讨论】:

  • 所以要明确一点,您有一种适用于 iOS 的方式和一种适用于 Android 的方式,但不是两者兼而有之?如果是这样,您可以检测用户使用的是哪个操作系统(请参阅here),然后根据操作系统使用适当的解决方案。
  • @Alex 解决方案 2 可以在两个系统上运行,这就是我使用的系统,但它在 W3 验证器上给出了 HTML 错误。
  • 嗯,好吧,如果您打算进行 W3 的验证,我不知道有什么方法可以使选项 2 起作用。你有什么原因不能做上述系统检查吗?
  • @Alex 相应地更改输入太复杂了,因为以下所有 jQuery 函数都假定输入的特定模式。我想知道是否有可能获得“静态”解决方案
  • 啊,我明白了。那么我很抱歉,但我帮不上什么忙,抱歉。祝你好运!

标签: mobile-safari html-input android-keypad numeric-keypad iphone-keypad


【解决方案1】:

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

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

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

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

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

&lt;input inputmode="numeric" pattern="[0-9]*" type="text"/&gt;

查看哪些浏览器支持输入模式click here

祝你好运

【讨论】:

  • pattern 是否支持正则表达式?如果是这样,为什么不也添加点?类似[0-9.]*
  • 嗨 João,由于某种原因,当您向正则表达式添加任何其他内容时,苹果会显示一个普通的键盘。重要的是要注意认为有一个区别,区别在于如果您使正则表达式模式 [0-9.]* IOS 设备将打开到全键盘的数字和字符部分,这对于 ux 来说仍然很糟糕.使用全屏数字键盘获取逗号和句点的唯一其他方法是使用上面已经建议的 type="tel"。最好的问候
【解决方案2】:

还有另一种选择:&lt;input type="text" inputmode="numeric" pattern="[0-9]*"&gt;

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

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

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

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

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

【讨论】:

    【解决方案3】:

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

    解决方案

    // iOS detection from: stackoverflow.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 上,我们有这种可能性。如果您想使用带有浮点数的数字键盘,那么您必须为 iOS 编写额外的解决方案,如下所示:

     <input type="number" />
    

    【讨论】:

    • 如果“仅当输入类型为电子邮件、密码、搜索、电话、文本或 url 时才允许使用属性模式”,为什么会通过 W3 验证器?或者为什么不默认使用type="number",然后在代码中添加pattern
    • @JoãoPimentelFerreira,因为 W3 验证器不检查 JavaScript。 W3 验证仅用于检查您的代码。这可以帮助您找到代码中的错误,但这不是规定。对于第二个问题:这是相同的解决方案 - 你也可以这样做,这是一个偏好问题。
    • pattern="\d*" 修复似乎不再适用于 iPad(我在 iOS12.2 的 Beta 版中注意到了这一点),因此我们改用 type=tel。
    • manymanymanymanymany 资源告诉你为什么永远不应该进行用户代理检测。主要原因之一:当引入新浏览器并且现有浏览器变得更好时,您将不得不不断更新代码,而浏览器需要不断寻找技巧来解决未更新的检测代码。
    【解决方案4】:

    根据@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: http://stackoverflow.com/a/9039885/177710
        if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
            return "iOS";
        }
    
        return "unknown";
    }
    

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

    【讨论】:

    • jQuery 从来没有比纯 JS 快。这就像 C++ 和汇编语言的例子。你必须考虑在浏览器内存中加载 100 KB 的 jQuery 库代码和大量来自 jQuery 的对象。 jQuery 代码并不优雅。
    • 不要忘记,这个赏金来自您和you cannot award a bounty to your own answer。由于这一切,我不明白为什么您提供与我相同的解决方案,但您不想用赏金奖励我的答案?这不公平!
    • @Bharata 我非常清楚我不能将赏金奖励给自己。我对你的方法的问题是你总是运行代码,而使用这种方法你只需在 iOS 操作系统上运行它。
    • 但是这背后(总是运行代码)有一个非常重要的意义: 1.你无法通过客户端知道哪个操作系统——可能不是Android或iOS。我们有很多这样的客户,可能他们有同样的问题,就像在 iOS 上一样。 2.此代码很小,您可以节省服务器和客户端资源以传输附加代码以检查操作系统。转移它是没有意义的。 3. 在你的任务中没有提到操作系统的检查。但如果你想要它,我可以在我的代码中添加对操作系统的检查。我应该这样做吗?
    • 为什么要多加一个类?
    【解决方案5】:

    正如 cmets 中所述,由于没有直接的方法来完成此操作,因此最好的解决方法是始终使用带有 if 语句的 input type="number",如果设备是 iOS 设备,则代码将添加类型的正确模式属性。

    【讨论】:

    • 为了全面起见,您可以添加完整的代码吗?
    • 请注意type=number 不允许在 iPhone 上输入小数点,即使使用了step=any。 (对于某些版本的 Android 或 Chrome 或 Android 键盘,step=any 会在手机上显示小数点)。您也可以尝试为 Chrome 设置 inputmode=decimal - developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/…
    猜你喜欢
    • 2014-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多