惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Y
Y Combinator Blog
有赞技术团队
有赞技术团队
J
Java Code Geeks
H
Hackread – Cybersecurity News, Data Breaches, AI and More
美团技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Hugging Face - Blog
Hugging Face - Blog
人人都是产品经理
人人都是产品经理
酷 壳 – CoolShell
酷 壳 – CoolShell
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
C
Check Point Blog
博客园 - 【当耐特】
The GitHub Blog
The GitHub Blog
Recent Announcements
Recent Announcements
The Cloudflare Blog
Microsoft Azure Blog
Microsoft Azure Blog
腾讯CDC
Vercel News
Vercel News
IT之家
IT之家
MyScale Blog
MyScale Blog
博客园_首页
Martin Fowler
Martin Fowler
WordPress大学
WordPress大学
罗磊的独立博客

张鑫旭-鑫空间-鑫生活

1分钟速度了解text-align match-parent声明 « 张鑫旭-鑫空间-鑫生活 光标的形状也能设置了,就是CSS caret-shape属性 « 张鑫旭-鑫空间-鑫生活 pretext与文字四面环绕效果的实现 « 张鑫旭-鑫空间-鑫生活 JSON.rawJSON方法的作用是什么? « 张鑫旭-鑫空间-鑫生活 如何使用CSS判断鼠标从哪个方向进入元素? « 张鑫旭-鑫空间-鑫生活 借助mediabunny纯JS实现视频水印、剪裁、合成等功能 « 张鑫旭-鑫空间-鑫生活 务必谨慎使用JS WeakRef弱引用 « 张鑫旭-鑫空间-鑫生活 CSS六边形头像的实现与蜂巢布局 « 张鑫旭-鑫空间-鑫生活 CSS corner-shape与背景底纹技术 « 张鑫旭-鑫空间-鑫生活 浅学WebTransport API:下一代Web双向通信技术 « 张鑫旭-鑫空间-鑫生活 HTML dialog元素新支持了closedBy属性 « 张鑫旭-鑫空间-鑫生活 HTML interestfor属性与悬停popover交互效果 « 张鑫旭-鑫空间-鑫生活 CSS3模拟window7炫酷界面效果展示 « 张鑫旭-鑫空间-鑫生活 图片旋转+剪裁js插件(兼容各浏览器) « 张鑫旭-鑫空间-鑫生活 纯js无图片无外链CSS图片幻灯片播放插件 « 张鑫旭-鑫空间-鑫生活 CSS border三角、圆角图形生成技术简介 « 张鑫旭-鑫空间-鑫生活 CSS “渐进增强”在web制作中常见应用举例 « 张鑫旭-鑫空间-鑫生活 让IE6/IE7/IE8浏览器支持CSS3属性 « 张鑫旭-鑫空间-鑫生活 jQuery – 高亮动态显示页面HTML代码插件 « 张鑫旭-鑫空间-鑫生活 翻译 – 逐渐消失的Flash网站 « 张鑫旭-鑫空间-鑫生活 CSS reset的重新审视 – 避免样式重置 « 张鑫旭-鑫空间-鑫生活 新浪微博插入话题后部分文字选中的js实现 « 张鑫旭-鑫空间-鑫生活 JavaScript实现http地址自动检测并添加URL链接 « 张鑫旭-鑫空间-鑫生活 CSS实现兼容性的渐变背景(gradient)效果 « 张鑫旭-鑫空间-鑫生活 CSS content内容生成技术以及应用 « 张鑫旭-鑫空间-鑫生活 CSS gradient渐变之webkit核心浏览器下的使用 « 张鑫旭-鑫空间-鑫生活 CSS渐变之CSS3 gradient在Firefox3.6下的使用 « 张鑫旭-鑫空间-鑫生活 区分IE8/IE7/IE6及其他浏览器-CSS “\9″hack « 张鑫旭-鑫空间-鑫生活 CSS实现跨浏览器兼容性的盒阴影效果 « 张鑫旭-鑫空间-鑫生活 CSS3&HTML5各浏览器支持情况一览表 « 张鑫旭-鑫空间-鑫生活
分享下input time输入框的细节知识 « 张鑫旭-鑫空间-鑫生活
张鑫旭,zhangxinxu · 2021-03-31 · via 张鑫旭-鑫空间-鑫生活

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=9906
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。

空中钓鱼-占位图

最近与type=”time”类型的input输入框打了不少交道,学到了不少知识,和大家分享下。

一、关于兼容性和UI表现

1. Safari浏览器

Safari桌面端浏览器目前并不支持time输入框,14之后的版本貌似会支持,兼容性图如下:

input类型输入框

2. Chrome浏览器

Chrome浏览器的兼容性相当不错,各个操作系统,以及移动端均支持。

并且Chrome浏览器点击输入框右侧的图标会显示下拉选择。

Chrome win下的UI

但是,很奇怪的是,根据我在多个设备上测试。

Chrome浏览器在windows系统下,time是使用的24小时表示法,比较符合中国人看时间的习惯。

但是Chrome浏览器在OS X系统下,time居然使用的是12小时表示法。

Chrome Mac表示法

3. Firefox浏览器

但是在Windows系统下的Firefox浏览器,居然又是12小时表示法,如下图所示:

Firefox浏览器下效果

并且没有下拉列表,只能通过上下键修改时间或者分钟。


上面这几个浏览器UI上的差异给开发带来了不小的困扰。

需求是这样的,所有浏览器均支持下拉的小时和分钟选择,同时保持input的输入框是time类型,这样有最佳的语义。

但是时间格式的不一致,使得开发的时候无法确定,下拉应该是12小时表示还是使用24小时表示。

这个问题的解决是本文重点介绍的内容。

二、时间表示法是无法统一的

我花了大量的时间去研究能够通过设置某些属性,例如lang属性,或者datetimeformat属性修改日期时间的显示格式。

结论是time/date等类型等时间输入框等时间格式是无法改变等。

如果大家有办法可以设置,我请大家吃饭。

既然没法保持一致,那就时间输入框是什么时间格式,UI组件实现的时候就是什么格式。

所以下面的问题就变成了,如何判断当前浏览器下的time输入框是24小时表示的,还是12小时表示的呢?

二、24小时表示还是12小时表示的判断

是这样的,虽然视觉上,Mac设备下是12小时制的,也即是“上午 11:23”,但是使用 input.value 返回的依然是24小时表示的。

也就是下面的HTML代码:

<input type="time" value="13:14">

在windows Chrome浏览器下显示的是 13:14,在windows Firefox浏览器和OS X Chrome浏览器下显示的是 下午 01:14 ,但是使用value属性获取,返回的全部都是 13:14,完全没有办法通过值来判断当前浏览器支持的是24小时表示H:mm,还是12小时表示ah:mm。

//zxx: 如果你看到这段文字,说明你现在访问是体验糟糕的垃圾盗版网站,你可以访问原文获得很好的体验:https://www.zhangxinxu.com/wordpress/?p=9906(作者张鑫旭)

我有想过基于操作系统和浏览器判断,但是这样的判断是不安全的,容易出错的,因为英文 windows语言操作系统下的Chrome不见得是24小时表示。

怎么办呢,有没有什么比较精确的,与操作系统无关的判断方法呢?后来使用了自己还觉得不错的一招。

字符个数导致尺寸变化差异不同

浏览器如果支持time类型输入框,则输入框的尺寸是跟着里面的字符个数走的。

如果输入框显示的是 13:14,则输入框的宽度是 13:14 外加一个图标尺寸。如下图所示:

输入框UI示意

如果输入框显示的是 下午 01:14,则输入框的宽度是字符“下午 01:14”宽度外加一个图标尺寸。如下图所示:

12小时表示的输入框

由于字符个数不同,因此,当改变输入框的字号大小之后,输入框的尺寸变化也会有所不同。

例如文字从20px -> 30px,则5个字符变化的宽度显然要比7个字符变化的宽度小。

于是,我们就可以根据前后输入框尺寸变化大小预估输入框内字符的个数,这样我们就能知道输入框是24小时表示的,还是12小时表示的了。

基于上面原理,写了个判断方法:

// 默认是24小时类型,不支持time类型输入框的浏览器会使用此类型,例如Safari
let datetimeformat = 'H:mm';
// 根据尺寸判断
let eleInputTmp = document.createElement('input');
eleInputTmp.setAttribute('type', 'time');
eleInputTmp.value = '00:00';
document.body.append(eleInputTmp);
// 默认不可见
eleInputTmp.style.position = 'absolute';
eleInputTmp.style.left = '-999px';
eleInputTmp.style.fontFamily = 'revert';
// 如果浏览器不支持time类型输入框,例如Safari,则使用H:mm格式
if (eleInputTmp.type == 'time') {
    eleInputTmp.style.fontSize = '20px';
    // 获取此时输入框的尺寸
    let numWidthOrigin = eleInputTmp.clientWidth;
    // 修改尺寸
    eleInputTmp.style.fontSize = '30px';
    // 比较前后尺寸变化的差异
    let numDiffWidth = eleInputTmp.clientWidth - numWidthOrigin;
    // 可以判断输入框字符个数
    let numLetters = Math.ceil(numDiffWidth / 10);
    if (numLetters &gt;= 5) {
        datetimeformat = 'ah:mm';
    }
    eleInputTmp.remove();
}

datetimeformat就是最终判断的时间表示格式。

当前后变化尺寸不小于5个字符宽度的时候,则认为是12小时表示法。此时,UI组件就可以以12小时表示法的排版设计交互效果了,否则使用24小时表示法。

最终实现效果预览,Safari浏览器,以及Windows Chrome浏览器下:

24小时表示

Firefox浏览器下:

Firefox下的UI组件美化效果

这样,美化的UI交互就可以和浏览器原生行为保持一致了。

四、step属性与分秒选择的细节

默认情况下,time类型的输入框只能选择到分钟,如果想要秒也能选择,有下面2个方法。

1. 设置初始值是00:00:00格式

例如:

<input type="time" value="13:14:20">

则秒的值就会显示出来。

例如windows系统下的Chrome浏览器:

秒也能显示

从上图可以看出,虽然秒出现了,但是是置灰的,原因是此时的step是按照60来渲染的。

这就引出下一个设置秒选择的方法。

2. 设置合适的step值

time类型的输入框,只要step的值不是60的倍数,则如果value初始值是什么,一定会精确到秒进行显示。

例如下面的HTML代码:

<p><input type="time" step="1"></p>
<p><input type="time" value="13:14" step="1"></p>
<p><input type="time" step="20"></p>
<p><input type="time" value="13:14" step="20"></p>
<p><input type="time" step="61"></p>
<p><input type="time" step="9999999"></p>

最终全部都是可以选择到秒。

如下截图所示:

秒的显示

但是如果step属性值是60的倍数,则此时step会认为是分钟,此时,如果value的值不是00:00:00格式,则时间的选择会精确到分钟;如果value的值是00:00:00格式,则秒默认置灰。

例如:

<p><input type="time" step="60"></p>
<p><input type="time" value="13:14" step="120"></p>

则渲染效果如下图所示:

step是60倍数的时候

因此,要想value="13:14:20"设置后秒的值20不置灰,只需要设置step属性值为1就可以了。

<input type="time" value="13:14:20" step="1">

此时,后面的20就不是灰色的了。

20不是灰色

step不影响value值的设置

step虽然语义上表示时间的间隔,但是行为上并没有阻止value的设置,什么意思呢?

例如:

<input type="time" step="30">

表示秒的步阶是30秒,也即是00:00:00或者00:00:30才是合法的值,但是,实际上,你下拉列表选择00:00:20也是可以的,step限制的是上下键快捷选择时候的值,并没有限制点击行为,以及直接使用value赋值的限制。

这是step的另外一个细节知识。

五、其他细节、移动端、结语

其他细节

  • 无论是value属性设置的值,还是 step/min/max属性设置的值,都必须是严格的00:00或者00:00:00格式,也就是前面的0必须补全,例如下面的HTML中的value设置就是无效的:

    <p><input type=”time” value=”3:14″></p>

    渲染出来的就是4个短横线(如下图效果),value值必须写成 value="03:14" 才可以。

    4个短横线示意

  • min/max属性和step属性一样,只能影响上下键这样的快捷键选择,并不能阻止点击选择不再限制范围中的值。
  • Chrome浏览器暴露了很多伪元素,可以用来修改默认的时间选择控件的样式细节,例如::-webkit-datetime-edit::-webkit-datetime-edit-fields-wrapper::-webkit-datetime-edit-hour-field::-webkit-datetime-edit-text ::-webkit-datetime-edit-minute-field等。

移动端

在移动端,对于时间选择输入框,设备会在系统层面实现更利于移动端交互的效果,我个人的建议是可以不做UI的美化处理的,例如在iOS系统下,显示的时间选择列表和iOS的时间选择的UI和交互是一脉相承的,效果更好。

不过,移动端也有其他的小瑕疵,按照我之前开发的经验,在iOS Safari浏览器下,min max属性似乎不能对范围进行限制。

这就导致最终表单数据提交的时候,需要做下验证。

结语

学习小天地,记录下近期学到的些东西,一来备忘,二来可能可以帮到有需要的人。

感谢您的阅读与支持,比心!

本文为原创文章,欢迎分享,勿全文转载,如果实在喜欢,可收藏,永不过期,且会及时更新知识点及修正错误,阅读体验也更好。
本文地址:https://www.zhangxinxu.com/wordpress/?p=9906

(本篇完)