简体   繁体   English

是否有可接受的跨平台方法在基于触摸的设备上以标准Web表单显示数字小键盘?

[英]Is there an acceptable cross-platform method for displaying a numeric keypad in standard web forms on a touch-based device?

The goal : To find a cross-platform solution for displaying numeric keyboards on mobile touch-based devices, with a minimum of hacks. 目标 :找到一个跨平台解决方案,用于在移动触摸设备上显示数字键盘,并且只需最少的黑客攻击。

The problem : 问题

I have a regular web application using data input forms, containing primarily numeric data. 我有一个使用数据输入表单的常规Web应用程序,主要包含数字数据。 When a user interacts with my site on a mobile device, I would like to display a numeric virtual keypad as most standard keyboards require a second press to switch from alphas to numbers. 当用户在移动设备上与我的网站进行交互时,我想显示数字虚拟键盘,因为大多数标准键盘需要第二次按下才能从alpha切换到数字。 I know that i can trigger different keyboard by setting the "type" attribute of input element: 我知道我可以通过设置input元素的“type”属性来触发不同的键盘:

type=number : This works great under iOS/Safari. type=number :这在iOS / Safari下运行良好。 I am unsure about other browsers on the platform. 我不确定该平台上的其他浏览器。

On Android, this does not consistently raise the correct keyboard on various browsers and often results in unwanted elevator buttons on the input. 在Android上,这并不能在各种浏览器上持续提升正确的键盘,并且通常会在输入上产生不需要的电梯按钮。 I have yet to find a clean way to turn these off in CSS. 我还没有找到一种干净的方法来在CSS中关闭它们。

type=tel : This almost works on iOS/Safari, but the telephone keyboard lacks a decimal button. type=tel :这几乎适用于iOS / Safari,但电话键盘没有小数点按钮。

Seems to work great across multiple android browsers, without any extraneous UI elements added to the page. 似乎在多个Android浏览器中运行良好,没有任何无关的UI元素添加到页面。

My current solution is hacky and simplistic. 我目前的解决方案是hacky和简单。 Based on a class that I'm already using for numeric validation, I replace each text element that should contain a number with a new input that is either a number or a tel type based on the detected OS/browser. 基于我已经用于数字验证的类,我将基于检测到的OS /浏览器替换应该包含数字的每个文本元素,其中新输入是numbertel类型。

var isAndroid = navigator.userAgent.match(/android/i) ? true : false;
var isIOS = navigator.userAgent.match(/(ipod|ipad|iphone)/i) ? true : false;

if (isAndroid || isIOS) {
    var useNumberType = (isIOS ? true : false); //iOS uses type=number, everyone else uses type=tel
    jQuery("input.num").each(function () {
        var type = (useNumberType ? "number" : "tel");
        var html = this.outerHTML;
        html = html.replace(/(type=\"?)text(\"?)/, "$1" + type + "$2");
        this.outerHTML = html;
    });
}

I would prefer to not use browser detection and to not change out the inputs on the fly at run time. 我宁愿不使用浏览器检测,也不希望在运行时动态更改输入。 I could possibly introduce an http module on the server side that did basically the same thing, but that is not substantially better. 我可能会在服务器端引入一个基本相同的http模块,但这并不是更好。 I'm shocked that there isn't a CSS call for this. 我很震惊,因为没有CSS调用。

Is there a better way to get a numeric keyboard with a decimal button, that works on all or most touch-based mobile devices without adding weird UI elements to the page? 有没有更好的方法来获得带有小数点按钮的数字键盘,适用于所有或大多数基于触摸的移动设备,而无需向页面添加奇怪的UI元素?

-------------- update --------------更新

I don't think there is a way to do what I really want to do, which is to setup a single input style or type that will work well across desktop browsers and all major mobile touch-based platforms. 我认为没有办法做我真正想做的事情,那就是设置一种能够在桌面浏览器和所有主要的基于移动触摸的平台上运行良好的单一输入样式或类型。 I settled on changing the type of the input through a direct DOM call rather through jQuery instead of rewriting the entire input via outerHTML. 我决定通过直接DOM调用来改变输入的类型,而不是通过jQuery而不是通过outerHTML重写整个输入。 I suspect there isn't much difference in effect, but the code is a little cleaner. 我怀疑效果没有太大区别,但代码更清晰一些。 Since I'm not changing input types on the desktop, I shouldn't have to worry about IE's read only restriction on the attribute. 由于我没有更改桌面上的输入类型,所以我不必担心IE对该属性的只读限制。

Ideally, I'd probably handle this on the server side so everything got sent to the browser in the format desired for the device making the request. 理想情况下,我可能会在服务器端处理此问题,因此所有内容都以发出请求的设备所需的格式发送到浏览器。 But for now the new code looks more like this: 但是现在新代码看起来更像是这样的:

var isAndroid = navigator.userAgent.match(/android/i) || navigator.platform.match(/android/i) ? true : false;
var isIOS = navigator.userAgent.match(/(ipod|ipad|iphone)/i) ? true : false;

if (isAndroid || isIOS) {
    var useNumberType = (isIOS ? true : false); //iOS uses type=number, everyone else uses type=tel
    jQuery("input.num").each(function () {
        var type = (useNumberType ? "number" : "tel");
        if (this.type == "text") {
            this.type = type;
        }
    });
}

Protip: when working with mobile, do NOT interfere with the user experience. Protip:使用移动设备时,请勿干扰用户体验。 This means keeping the built-in keypads as they are. 这意味着保持内置键盘不变。

Some users may even have Javascript disabled on their mobile devices/browsers! 有些用户甚至可能在他们的移动设备/浏览器上禁用Javascript!

What you should do here is include an HTML hint to the browser. 你应该在这里做的是包括浏览器的HTML提示。 This way, mobile browsers should know what kind of content they are interacting with. 这样,移动浏览器就应该知道他们正在与哪种内容进行交互。

HTML5 includes several new <input> content types that should be supported on all modern mobile devices (and most modern browsers) HTML5包含几种新的<input>内容类型,应该在所有现代移动设备(以及大多数现代浏览器)上支持

You can find the full list here . 您可以在此处找到完整列表。

What you want specifically is the following: 你想要具体的是以下内容:

Old code: 旧代码:

Phone number: <input type="text" name="phone" />

New code: 新代码:

Phone number: <input type="tel" name="phone" />

I don't know that any browsers currently support "tel" , so you could use something like the following: 我不知道任何浏览器目前都支持"tel" ,所以你可以使用如下内容:

Phone number: <input type="number" name="phone" min="1000000000" max="9999999999" />

This is a bit of a hack, but is another option for you. 这有点像黑客,但对你来说是另一种选择。

This is a MUCH simpler and more maintainable way of doing things, and better for the user. 这是一种更简单,更易于维护的方式,对用户来说更好。

Please let me know if you have any questions. 请让我知道,如果你有任何问题。 I know this isn't directly answering the question, but it is a better way of doing things for now, in my opinion. 我知道这不是直接回答这个问题,但在我看来,这是现在更好的做事方式。 :) :)

EDIT: 编辑:

A possible way to get around this for each browser is by checking the user agent using JS/Jquery. 解决每个浏览器的可能方法是使用JS / Jquery检查用户代理。 I'm not sure exactly how to do this, but here is a tutorial on how to do so in .NET and changing the CSS for each element using JQuery. 我不确定如何做到这一点,但这里有一个关于如何在.NET中使用JQuery更改每个元素的CSS 的教程

EDIT EDIT!: 编辑编辑!:

Try just modifying your code as such: 尝试修改代码:

var isAndroid = navigator.userAgent.match(/android/i) ? true : false;
var isIOS = navigator.userAgent.match(/(ipod|ipad|iphone)/i) ? true : false;

if(isIOS)
    $(.phoneInput).attr("type", "tel");
if(isAndroid)
{
    $(.phoneInput).attr("type", "number");
    $(.phoneInput).attr("min", "1000000000");
    $(.phoneInput).attr("max", "9999999999");
}

I hope this out of everything works! 我希望这一切都有效! You might have to switch the two if statements, depending on how your testing turns out. 您可能必须切换两个if语句,具体取决于您的测试结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM