从 iOS/Android 上的 Web 应用调用本机日期选择器

Posted

技术标签:

【中文标题】从 iOS/Android 上的 Web 应用调用本机日期选择器【英文标题】:Invoke native date picker from web-app on iOS/Android 【发布时间】:2011-06-24 05:34:55 【问题描述】:

我正在尝试探索使用 html5 在不同平台上运行本机网络应用程序的可能性。目前,<input type="date">field 仅在 androidios 上打开标准软键盘。我想未来移动操作系统的软键盘将包括日期选择器等——就像<select>今天调用本机选择一样。

由于这不是在 Android 或 iOS 上实现的,而是在本机 UI 中实现的,网络应用程序是否可以调用本机日期选择器,即在点击时?

这将使我们有可能停止使用 jQuery mobile 和 YUI 等 javascript 库。

如果我的问题有任何不清楚的地方,请告诉我。提前谢谢你:-)

【问题讨论】:

另见***.com/questions/388814/… 我发现最简单的方法是使用input[type=text],然后在ng-click 上使用javascript 打开本机日期选择器。 @Siddharth 这是一个不错的建议......出于某种原因,在 Android 7 上,输入 type=date 会带来与原生日期选择器完全不同的选择器(您不能使用轻弹滚动它例如,您的手指)。顺便问一下,无论如何,如何在 javascript 中打开“本机”日期选择器? 【参考方案1】:

有些设备支持<input type="date">,但有些设备不支持,所以需要小心。以下是 2012 年的一些观察,今天可能仍然有效:

可以通过设置该属性然后读回其值来检测是否支持type="date"。不支持它的浏览器/设备将忽略将类型设置为date 并在读回该属性时返回text。或者,Modernizr 可用于检测。请注意,仅检查某些 Android 版本是不够的;就像 Android 4.0.3 上的三星 Galaxy S2 确实支持 type="date",但更新的 Android 4.0.4 上的 Google/Samsung Nexus S

为本地日期选择器预设日期时,请务必使用设备可识别的格式。如果不这样做,设备可能会默默地拒绝它,在尝试显示现有值时留下一个空输入字段。就像在运行 Android 4.0.3 的 Galaxy S2 上使用日期选择器一样,它本身可能会将 6 月 1 日的 <input> 设置为 2012-6-1。但是,从 JavaScript 设置值时,需要前导零:2012-06-01

当使用 Cordova (PhoneGap) 之类的东西在不支持 type="date" 的设备上显示本机日期选择器时:

确保正确检测内置支持。就像 2012 年在运行 Android 4.0.3 的 Galaxy S2 上一样,错误地使用 Cordova Android 插件会导致日期选择器连续显示两次:在第一次单击“设置”后再次显示.

当同一页面上有多个输入时,某些设备会显示“上一个”和“下一个”以进入另一个表单字段。在 iOS 4 上,这不会触发 onclick 处理程序,因此会为用户提供常规输入。使用onfocus 触发插件似乎效果更好。

在 iOS 4 上,使用 onclickonfocus 触发 2012 iOS 插件首先使常规键盘显示,然后将日期选择器放置在其顶部。接下来,使用日期选择器后,仍然需要关闭常规键盘。使用$(this).blur() 在显示日期选择器之前移除焦点对 iOS 4 有帮助,并且不会影响我测试的其他设备。但它在 iOS 上引入了一些快速闪烁的键盘,并且在第一次使用时事情可能会更加混乱,因为那时日期选择器较慢。如果有人正在使用该插件,则可以通过输入readonly 来完全禁用常规键盘,但是在同一屏幕上输入其他输入时禁用“上一个”和“下一个”按钮。 iOS 4 插件似乎也没有让原生日期选择器显示“取消”或“清除”。

在 iOS 4 iPad(模拟器)上,2012 年 Cordova 插件似乎无法正确呈现,基本上没有给用户任何输入或更改日期的选项。 (也许 iOS 4 没有很好地将其原生日期选择器呈现在 Web 视图之上,或者我的 Web 视图的 CSS 样式有一些影响,这在真实设备上肯定会有所不同:请评论或编辑! )

虽然在 2012 年,Android 日期选择器插件尝试使用与 iOS 插件相同的 JavaScript API,并且其示例使用了allowOldDates,但 Android 版本实际上并不支持。此外,它返回的新日期为2012/7/2,而iOS 版本返回Mon Jul 02 2012 00:00:00 GMT+0200 (CEST)

即使支持<input type="date">,事情也可能看起来很混乱:

iOS 5 可以很好地以本地化格式显示 2012-06-01,例如 1 Jun. 2012June 1, 2012(甚至在仍在操作日期选择器的同时立即更新)。然而,运行 Android 4.0.3 的 Galaxy S2 显示丑陋的 2012-6-12012-06-01,无论使用哪种语言环境。

当触摸日期输​​入时键盘已经可见时,或者在另一个输入中使用“上一个”或“下一个”时,iPad(模拟器)上的 iOS 5 不会隐藏键盘。然后它同时显示输入下方的日期选择器和底部的键盘,并且似乎允许来自两者的任何输入。但是,尽管它确实改变了可见值,但实际上忽略了键盘输入。 (在读回值或再次调用日期选择器时显示。)当键盘尚未显示时,触摸日期输​​入仅显示日期选择器,而不是键盘。 (这在真实设备上可能会有所不同,请评论或编辑!)

设备可能会在输入字段中显示光标,长按可能会触发剪贴板选项,可能还会显示常规键盘。单击时,某些设备甚至可能会在瞬间显示常规键盘,然后再更改为显示日期选择器。

【讨论】:

你能确认插件确实触发了原生控件(与渲染原生控件的 JS 仿真相比)吗? 最初的问题是关于在网络浏览器本身中执行此操作。不过,您的回答涉及 PhoneGap 领域,并且“陷阱”似乎暗示 PhoneGap 可能没有触发本机控件,而是使用 JavaScript 来模仿本机控件。但是,如果我理解您的回复,PhoneGap 插件确实会触发移动 safari 之外的本机设备操作系统日期选择器。 我对PhoneGap 插件触发的内容仍然有些困惑。例如,您说 iPad 存在渲染问题。为什么它会错误地呈现本机控件? (我也会回答我以前的问题......) 为什么 iPad(模拟器)在从我不知道的插件触发时无法显示自己的本机日期选择器,不幸的是。也许插件Objective C代码中的某些东西是错误的,或者可能以某种方式在Web视图顶部显示日期选择器很麻烦,或者甚至可能是我使用的网页的CSS样式以某种方式影响它(虽然它不应该)。但一切都是关于本地日期选择器的;看看the Java,它很小。 一个警告:在 iOS 上,当您更改日/月/年的 3 个控件中的一个时,会触发“onchange”事件。这还为时过早,因为用户可能会更改多个,然后点击“完成”以确认新日期。我不得不改用“onblur”事件。【参考方案2】:

试试Mobiscroll。 滚动样式的日期和时间选择器是专门为触摸设备上的交互而创建的。 它非常灵活,并且易于定制。它带有 iOS/Android 主题。

【讨论】:

嗯,这基本上与我使用的相反。它速度不快,维护起来也不容易,而且除了 iOS、默认的 Android 和 Sense 外,它看起来一点也不像。不过,感谢您的贡献:-) 我发现 mobiscroll 在 HTC Desire 原生浏览器上非常错误且不可靠。充其量它看起来很迟钝,但滚动条经常卡住,所以它只是不断地在日期之间飞来飞去。 它在 iOS 上效果更好。但是...我在 HTC Desire HD 上使用它,并且 2.0 似乎有所改进。它似乎在其他安卓浏览器上运行得更好,例如 Dolphin。 请注意,mobiscroll 不支持 WP7,并且此错误票已开放一年多:code.google.com/p/mobiscroll/issues/… Windows Phone 支持在哪里?见帖子:blog.mobiscroll.com/where-is-the-windows-phone-support【参考方案3】:

在 HTML 中:

  <form id="my_form"><input id="my_field" type="date" /></form>

在 JavaScript 中

   // test and transform if needed
    if($('#my_field').attr('type') === 'text')
        $('#my_field').attr('type', 'text').attr('placeholder','aaaa-mm-dd');  
    ;

    // check
    if($('#my_form')[0].elements[0].value.search(/(19[0-9][0-9]|20[0-1][0-5])[- \-.](0[1-9]|1[012])[- \-.](0[1-9]|[12][0-9]|3[01])$/i) === 0)
        $('#my_field').removeClass('bad');
     else 
        $('#my_field').addClass('bad');
    ;

【讨论】:

【参考方案4】:

在您的表单元素上使用input type="time"。它将为您省去尝试使用数据选择器库的所有麻烦。

【讨论】:

【参考方案5】:

我的回答过于简单化了。 如果您喜欢编写跨平台的简单代码,请使用 window.prompt 方法向用户询问日期。显然您需要使用正则表达式进行验证,然后创建日期对象。

function onInputClick(e)
var r = window.prompt("Give me a date (YYYY-MM-DD)", "2014-01-01");
if(/[\d]4-[\d]1,2-[\d]1,2/.test(r))
    //date ok
    e.value=r;
    var split=e.value.split("-");
    var date=new Date(parseInt(split[0]),parseInt(split[1])-1,parseInt(split[2]));
else
    alert("Invalid date. Try again.");


在你的 HTML 中:

<input type="text" onclick="onInputClick(this)" value="2014-01-01">

【讨论】:

不错。但另请参阅Detecting an “invalid date” Date instance in JavaScript。 (您可以尝试使正则表达式更好一些,例如不接受大于 12 的月份,但最大天数仍然很难。)【参考方案6】:

iOS5 支持此功能 (Reference)。如果您想调用本机日期选择器,您可能有一个使用 PhoneGap 的选项(我自己没有测试过)。

【讨论】:

您可以使用带有 PhoneGap/Cordova 的原生 pickerView 和以下插件:github.com/mgcrea/cordova-pickerview【参考方案7】:

您可以使用 Trigger.io's UI 模块来使用带有常规 HTML5 输入的原生 Android 日期/时间选择器。但是,这样做确实需要使用整体框架(因此不能用作常规的移动网页)。

你可以在这篇博文中看到之前和之后的截图:date time picker

【讨论】:

【参考方案8】:

iOS 5 现在更好地支持 HTML5。 在你的网络应用中做

<input type="date" name="date" />

从 4.0 开始,Android 缺少这种类型的原生菜单支持。

【讨论】:

您的回答与 Eirik Hoem 的回答一样正确。 Android 4.0 仍然不支持这是一场灾难。真丢脸,谷歌! 现在,三星 Galaxy S2 上的 Android 4.0.3 支持此功能,但 Nexus S 上的 4.0.4 不支持,@hnilsen。 呃,不:我不是说 Android 4.0.3 支持它,但是:Android 4.0.3 在 Galaxy S2 上 确实... 我在 ionic 应用程序中将其用于 android。它工作正常,但我将此输入设置为隐藏并在用户单击 div 时触发单击事件,因此它不起作用。有什么想法吗?

以上是关于从 iOS/Android 上的 Web 应用调用本机日期选择器的主要内容,如果未能解决你的问题,请参考以下文章

无法从 Flutter Web 读取 Firestore 中的数据(适用于 iOS 和 android)

如何从托管在另一台服务器上的 Web 应用程序调用客户端计算机托管的 Wcf 服务?

iOS/Android 上的音译

Adobe出品(支持IOS,android,web调用)免费插件编辑图片

Python +Appium 实现app自动化测试

Cordova 上的 AngularJS $resource POST 调用不能在 iOS/Android 设备上运行,但可以在浏览器上运行