HTML input type time 类型

🌙
手机阅读
本文目录结构

功能介绍

类型为time的输入元素<input> ,旨在让用户轻松输入时间(小时和分钟,以及可选的秒)。

控件的用户界面因浏览器而异。在现代浏览器中,支持是很好的,因为Safari是唯一尚未实现的主要浏览器;

在Safari和任何其他不支持<time>的浏览器中,它会优雅地降级为<input type=“text”>

出现

Chrome和Opera

在chrome/opera中,选择时间很简单,根据操作系统区域设置,插槽以12或24小时格式输入小时和分钟,上下箭头用于递增和递减当前选定的组件。在某些版本中,会提供一个“x”按钮来清除控件的值。

火狐浏览器

火狐的时间选择和Chrome非常相似,只是它没有上下箭头。它还使用12或24小时格式输入时间,基于系统区域设置。提供“X”按钮以清除控件的值。

边缘

Edgede 时间选择有点复杂,打开一个小时和分钟的滚动区域。它和chrome一样,使用12或24小时格式输入时间,基于系统区域设置:

甲DOMString的时间包含该值输入到输入。

您可以通过value在创建<input>元素时在属性中包括有效时间来为输入设置默认值,如下所示:

<label for="appt-time">Choose an appointment time: </label>
<input id="appt-time" type="time" name="appt-time" value="13:30">

您还可以使用HTMLInputElement.value属性在JavaScript中获取和设置日期值,例如:

var timeControl = document.querySelector('input[type="time"]');
timeControl.value = '15:30';

时间值格式

在value所述的time在24小时的格式输入总是:hh:mm,不管输入格式,这是可能选择根据用户的语言环境(或由用户代理)的。

如果时间包括秒(请参阅使用step属性),则格式始终为hh:mm:ss。您可以在HTML中使用的日期和时间格式的时间字符串中了解有关此输入类型使用的时间值格式的更多信息。

在此示例中,您可以通过输入时间并查看之后如何更改来查看时间输入的值。

首先,看一下HTML。这很简单,带有我们之前看到的标签和输入,但添加了额外的元素p和span用来显示时间值

<form>
  <label for="startTime">Start time: </label>
  <input type="time" id="startTime">
  <p>
    Value of the <code>time</code> input: <code>
            "<span id="value">n/a</span>"</code>.
  </p>
</form>

JavaScript代码将代码添加到时间输入中以监视input事件,每次输入元素的内容更改时都会触发该事件。发生这种情况时,的内容将<span>替换为输入元素的新值。

var startTime = document.getElementById("startTime");
var valueSpan = document.getElementById("value");

startTime.addEventListener("input", function() {
  valueSpan.innerText = startTime.value;
}, false);

time提交包含输入的表单时,值先被编码,然后才包含在表单数据中。用于时间输入的表单数据输入将始终处于表单中name=hh%3Amm,或者name=hh%3Amm%3ass如果包含秒,则请参见表(请参阅使用step属性)。

其他属性

除了所有<input>元素共有的属性外,time输入还提供以下属性:

属性 描述
max 按照时间值格式下描述的语法接受的最新时间
min 最早接受为有效输入的时间
readonly 布尔属性,如果存在,则指示time输入的内容不应由用户编辑
step 用于用户界面目的和约束验证期间的步进间隔

max

一个字符串,指示接受的最晚时间,以与上述相同的时间值格式指定。如果指定的字符串不是有效时间,则不会设置最大值。

min

一个字符串,它指定了最早接受的时间,以前面描述的时间值格式给出。如果指定的值不是有效的时间字符串,则不会设置最小值。

readonly

一个布尔属性,如果存在,则表示该字段不能由用户编辑。它value可以,但是,仍然可以通过JavaScript代码直接设置改变HTMLInputElement.value属性。

注意:因为只读字段不能有值,required所以对readonly也指定了属性的输入没有任何影响。

step

该step属性是一个数字,用于指定值必须遵循的粒度或特殊值any(如下所述)。仅等于步进基础的值(min如果指定,value否则指定;如果未提供任何默认值,则为适当的默认值)有效。

字符串值any表示不暗示任何步进,并且允许任何值(除非存在其他约束,例如min和max)。

注意:当用户输入的数据不遵循步进配置时,用户代理可能会舍入到最接近的有效值,当有两个相等的接近选项时,首选在正方向上的数字。

对于time输入,的值step以秒为单位,比例因子为1000(因为基础数值以毫秒为单位)。默认值为step60,表示60秒(或1分钟,或60,000毫秒)。

目前,尚不清楚与输入一起使用时any均值的含义。确定该信息后,将对此进行更新。steptime

使用时间输入

虽然data和time输入类型中的时间具有最广泛的浏览器支持,但它尚未接近普及,因此您可能需要提供一种替代方法来输入日期和时间,以便Safari用户(和用户)其他非支持浏览器)仍然可以轻松输入时间值。

我们将研究的基本用法和更复杂的用法<input type="time">,然后在以后提供有关缓解浏览器支持问题的建议(请参阅处理浏览器支持)。

时间的基本用途

最简单的使用<input type="time">涉及基本<input><label>元素的组合,如下所示:

<form>
  <label for="appt-time">Choose an appointment time: </label>
  <input id="appt-time" type="time" name="appt-time">
</form>

控制输入​​大小

<input type="time">不支持表单大小设置属性(例如)size,因为时间总是长于相同数量的字符。您必须依靠CSS来确定大小。

使用step属性

step每当时间增加或减少时,您都可以使用该属性来改变跳跃的时间(例如,单击小箭头小部件时,时间每次移动10分钟)。

此属性在浏览器中会产生一些奇怪的影响,因此并不完全可靠。

它采用一个整数值,该值等于您要增加的秒数;默认值为60秒或一分钟。如果您指定的值小于60秒(1分钟),则time输入将在小时和分钟旁边显示一个秒输入区域:

<form>
  <label for="appt-time">Choose an appointment time: </label>
  <input id="appt-time" type="time" name="appt-time" step="2">
</form>

在Chrome和Opera(这是仅有的显示上下迭代箭头的浏览器)中,单击箭头会将秒值更改两秒钟,但不会影响小时或分钟。分钟(或小时)只能在以秒为单位指定分钟(或小时)数(例如120表示2分钟或7200表示2小时)时用于步进。

在Firefox中,没有箭头,因此step未使用该值。但是,提供它确实会在分钟部分旁边添加秒输入区域。

在Edge中,steps值似乎无效。

使用step似乎会导致验证无法正常工作(如下一节所述)。

验证方式

默认情况下,<input type="time">除了用户代理的界面通常不允许您输入时间值以外,不会对输入的值进行任何验证。

这很有用(假设time用户代理完全支持输入),但是您不能完全依赖该值作为正确的时间字符串,因为它可能是空字符串(""),这是允许的。该值也可能大致看起来像有效时间,但不正确,例如25:05。

设置最大和最小时间

您可以使用min和max属性来限制用户可以选择的有效时间。在以下示例中,我们设置的最短时间为12:00,最大时间为18:00:

<form>
  <label for="appt-time">Choose an appointment time (opening hours 12:00 to 18:00): </label>
  <input id="appt-time" type="time" name="appt-time"
         min="12:00" max="18:00">
  <span class="validity"></span>
</form>

这是上面示例中使用的CSS。在这里,我们利用:valid和:invalidCSS属性根据当前值是否有效来对输入进行样式设置。

我们必须将图标放在<span>输入的旁边,而不是输入本身,因为在Chrome中,生成的内容位于表单控件内,无法有效地设置样式或显示。

div {
  margin-bottom: 10px;
  position: relative;
}

input[type="number"] {
  width: 100px;
}

input + span {
  padding-right: 30px;
}

input:invalid+span:after {
  position: absolute;
  content: '✖';
  padding-left: 5px;
}

input:valid+span:after {
  position: absolute;
  content: '✓';
  padding-left: 5px;
}

结果是:

  • 仅在12:00和18:00之间的时间被视为有效;超出该范围的时间将被视为无效。
  • 根据您使用的浏览器,您可能会发现甚至无法在时间选择器(例如Edge)中选择超出指定范围的时间。

需要时间

此外,您可以使用该required属性来强制填写时间。因此,如果您尝试提交超出设置范围的时间或空时间字段,则支持的浏览器将显示错误。

让我们看一个例子;在这里,我们设置了最小和最大时间,并设置了必填字段:

<form>
  <div>
    <label for="appt-time">Choose an appointment time (opening hours 12:00 to 18:00): </label>
    <input id="appt-time" type="time" name="appt-time"
           min="12:00" max="18:00" required>
    <span class="validity"></span>
  </div>
  <div>
      <input type="submit" value="Submit form">
  </div>
</form>

如果您尝试以不完整的时间(或超出设置的时间)提交表单,浏览器将显示错误。现在尝试使用示例:

重要说明:HTML表单验证不能代替脚本来确保输入的数据采用正确的格式。对于某人来说,对HTML进行调整以使其绕过验证或完全删除验证太容易了。有人也可以完全绕过HTML并将数据直接提交到服务器。如果服务器端代码无法验证接收到的数据,则在提交格式不正确的数据(或太大,类型错误的数据等)时,灾难可能会发生。

处理浏览器支持

如上所述,Safari和其他一些不太常见的浏览器尚不支持本机输入时间。通常,否则,支持就很好-特别是在移动平台上,该平台往往具有用于指定时间值的非常好的用户界面。

例如,timeChrome for Android上的选择器如下所示:

不支持时间输入的浏览器会优雅地降级为文本输入,但这会在用户界面(显示的控件有所不同)和数据处理的一致性方面造成问题。

第二个问题是更严重的。如前所述,time输入的值始终标准化为hh:mm或格式hh:mm:ss。另一方面,使用文本输入时,默认情况下,浏览器不知道时间应采用哪种格式,人们可以用多种方式编写时间,例如:

  • 3.00 pm
  • 3:00pm
  • 15:00
  • 3 o’clock in the afternoon
  • 等等

解决此问题的一种方法是pattern在time输入中放置一个属性。即使time输入不使用它,text输入回退也将使用。例如,尝试在不支持时间输入的浏览器中查看以下演示:

<form>
  <div>
    <label for="appt-time">Choose an appointment time (opening hours 12:00 to 18:00): </label>
    <input id="appt-time" type="time" name="appt-time"
           min="12:00" max="18:00" required
           pattern="[0-9]{2}:[0-9]{2}">
    <span class="validity"></span>
  </div>
  <div>
      <input type="submit" value="Submit form">
  </div>
</form>

如果您尝试提交,则您看到的不支持的浏览器现在会显示错误消息(并将输入内容突出显示为无效),如果您输入的内容与pattern不匹配nn:nn,其中n的数字是0到9。

当然,这不会阻止人们输入无效时间或遵循该格式的错误格式的时间。

然后就是用户不知道确切的时间是什么格式的问题。

目前,以跨浏览器方式处理表单中时间的最佳方法是让用户在单独的控件中输入小时和分钟(如果需要,还可以输入秒)(<select>元素很流行;请参见下文,例如),或使用JavaScript库(例如jQuery timepicker插件)。

例子

在此示例中,我们创建了两组用于选择时间的界面元素:使用创建的本机选择器<input type="time">,以及<select>用于在不支持本机输入的旧版浏览器中选择小时/分钟的两组元素。

HTML看起来像这样:

<form>
  <div class="nativeTimePicker">
    <label for="appt-time">Choose an appointment time (opening hours 12:00 to 18:00): </label>
      <input id="appt-time" type="time" name="appt-time"
             min="12:00" max="18:00" required>
      <span class="validity"></span>
    </div>
  <p class="fallbackLabel">Choose an appointment time (opening hours 12:00 to 18:00):</p>
  <div class="fallbackTimePicker">
    <div>
      <span>
        <label for="hour">Hour:</label>
        <select id="hour" name="hour">
        </select>
      </span>
      <span>
        <label for="minute">Minute:</label>
        <select id="minute" name="minute">
        </select>
      </span>
    </div>
  </div>
</form>

它们的<select>元素的小时和分钟值是动态生成的。

代码的另一部分可能是功能检测代码-要检测浏览器是否支持<input type="time">,我们创建一个新<input>元素,将其设置type为time,然后立即检查其类型设置为-不支持的浏览器将返回text,因为time类型回退到type text。

如果<input type="time">不支持,我们将隐藏本机选择器并显示后备选择器UI(<select>)。

// define variables
var nativePicker = document.querySelector('.nativeTimePicker');
var fallbackPicker = document.querySelector('.fallbackTimePicker');
var fallbackLabel = document.querySelector('.fallbackLabel');

var hourSelect = document.querySelector('#hour');
var minuteSelect = document.querySelector('#minute');

// hide fallback initially
fallbackPicker.style.display = 'none';
fallbackLabel.style.display = 'none';

// test whether a new date input falls back to a text input or not
var test = document.createElement('input');
test.type = 'time';
// if it does, run the code inside the if() {} block
if(test.type === 'text') {
  // hide the native picker and show the fallback
  nativePicker.style.display = 'none';
  fallbackPicker.style.display = 'block';
  fallbackLabel.style.display = 'block';

  // populate the hours and minutes dynamically
  populateHours();
  populateMinutes();
}

function populateHours() {
  // populate the hours <select> with the 6 open hours of the day
  for(var i = 12; i <= 18; i++) {
    var option = document.createElement('option');
    option.textContent = i;
    hourSelect.appendChild(option);
  }
}

function populateMinutes() {
  // populate the minutes <select> with the 60 hours of each minute
  for(var i = 0; i <= 59; i++) {
    var option = document.createElement('option');
    option.textContent = (i < 10) ? ("0" + i) : i;
    minuteSelect.appendChild(option);
  }
}

// make it so that if the hour is 18, the minutes value is set to 00
// — you can't select times past 18:00
 function setMinutesToZero() {
   if(hourSelect.value === '18') {
     minuteSelect.value = '00';
   }
 }

 hourSelect.onchange = setMinutesToZero;
 minuteSelect.onchange = setMinutesToZero;

AXIHE / 精选资源

浏览全部教程

面试题

学习网站

前端培训
自己甄别

前端书籍

关于朱安邦

我叫 朱安邦,阿西河的站长,在杭州。

以前是一名平面设计师,后来开始接接触前端开发,主要研究前端技术中的JS方向。

业余时间我喜欢分享和交流自己的技术,欢迎大家关注我的 Bilibili

关注我: Github / 知乎

于2021年离开前端领域,目前重心放在研究区块链上面了

我叫朱安邦,阿西河的站长

目前在杭州从事区块链周边的开发工作,机械专业,以前从事平面设计工作。

2014年底脱产在老家自学6个月的前端技术,自学期间几乎从未出过家门,最终找到了满意的前端工作。更多>

于2021年离开前端领域,目前从事区块链方面工作了