HTML input type month 类型
功能介绍
类型为 month 的 <input>
可以让你容易地创建一个方便输入年份或月份的一个 <input>
。
这个控件在各个浏览器支持都不同,目前是支持部分浏览器。在桌面上支持情况为 Chrome/Opera 和 Edge 。在移动端支持大部分现代浏览器。在其他浏览器中,这个控件会被优雅的降级到<input type="text">
.
对于那些使用不支持的浏览器的用户,Chrome / Opera月份控制如下图所示。单击右侧的向下箭头会显示日期选择器,以便您选择日期;你必须手动输入时间。
Value
DOMString 表示输入输入的月份和年份的值, in the form YYYY-MM (four or more digit year, then a hyphen ("-"), followed by the two-digit month). The format of the month string used by this input type is described in Format of a valid local month string in Date and time formats used in HTML.
你可以设置一个默认的属性值插入到 value 里, 像这样:
<label for="bday-month">What month were you both in?</label>
<input id="bday-month" type="month" name="bday-month" value="2017-06">
需要注意的是显示的如期格式不同于实际的value — 日期显示的格式将根据用户的操作系统的时区设置, 而时间的格式通常会格式化为 yyyy-MM。
在向服务器提交上述值的时候他们看起来像这样:bday-month=1978-06.
你也可以使用JavaScript 的 HTMLInputElement.value 来设置日期的值 。例如:
var monthControl = document.querySelector('input[type="month"]');
monthControl.value = '1978-06';
其他属性
除<input>
元素共有的属性外,月份输入还提供以下属性:
属性 | 描述 |
---|---|
max | 接受为有效输入的最新年份和月份 |
min | 接受为最早输入的最早年份和月份 |
readonly | 一个布尔值,如果存在,则指示不能编辑输入的值 |
step | 在递增和递减输入字段的值时要使用的步进间隔 |
max
接受上面“ 值”部分中讨论的字符串格式的最新年份和月份。如果在value元素中输入的内容超出此范围,则该元素将无法通过约束验证。如果该max属性的值不是“ yyyy-MM”格式的有效字符串,则该元素没有最大值。
此值必须指定晚-月配对,晚于或等于min属性指定的配对。
min
接受的最新年份和月份,yyyy-MM格式与上述相同。如果value元素的小于此值,则该元素将无法通过约束验证。如果为其指定的值min不是有效的年和月字符串,则输入没有最小值。
此值必须是早/月配对,且早于或等于max属性指定的配对。
readonly
一个布尔属性,如果存在,则表示该字段不能由用户编辑。它value可以,但是,仍然可以从JavaScript代码直接设置的值更改HTMLInputElement.value属性。
注意:因为只读字段不能有值,required所以对readonly也指定了属性的输入没有任何影响。
step
该step属性是一个数字,用于指定值必须遵循的粒度或特殊值any(如下所述)。仅等于步进基础的值(min如果指定,value否则指定;如果未提供任何默认值,则为适当的默认值)有效。
字符串值any表示不暗示任何步进,并且允许任何值(除非存在其他约束,例如min和max)。
注意:当用户输入的数据不遵循步进配置时,用户代理可能会舍入到最接近的有效值,当有两个相等的接近选项时,首选在正方向上的数字。
对于month输入,值step以月为单位,缩放因子为1(因为基础数值也以月为单位)。默认值为step1个月。
使用月份输入
与日期相关的输入乍一看很方便,它们提供了一个简单的用户界面来选择日期,并且它们将发送到服务器的数据格式规范化,而不考虑用户的本地环境。
但是, 由于浏览器支持有限,所以这个 <input type="month">
还是存在兼容性问题。
我们在往下看更多关于<input type="month">
基础和更多的高级的用法, 下面将讲有关缓解浏览器支持问题的建议 (请参阅Handling browser support).
月的基本用途
最简单的<input type="month">
涉及到基础的 <input>
和 <label>
的元素组合, 像下面这样:
<form>
<label for="bday-month">What month were you both in?</label>
<input id="bday-month" type="month" name="bday-month">
</form>
设置最长和最短日期
你可以使用min 和 max 属性 来限制用户选择日期. 在下列的例子中我们设置最小月份1900-01 最大月份到 2017-08:
<form>
<label for="bday-month">What month were you both in?</label>
<input id="bday-month" type="month" name="bday-month"
min="1900-01" max="2017-08">
</form>
结果是这样:
- 月份只有在2017年八月份到1900年一月可以选择 — 在这个控件里这个范围以外的月份不能滚动选择。
- 根据您使用的浏览器,您可能会发现在时间选择器(例如Edge)中无法选择超出指定值的时间,或者无效(请参见Validation)但仍然可以使用(例如Chrome)。
注意:您应该能够使用该step属性来改变每次日期增加时所跳的天数(例如,也许您只想选择星期六)。但是,在撰写本文时,这似乎在任何实现中均未有效。
控制输入大小
<input type="month">
不支持表单大小设置属性,例如size。您必须依靠CSS来确定大小。
验证方式
默认情况下,<input type="month">
不对输入的值应用任何验证。UI实现通常不允许您输入非日期的任何内容(这很有用),但是您仍然无法填写日期并提交或输入无效的日期(例如4月32日)。
您可以使用min和max限制可用日期(请参阅anch(“设置最大和最小日期”),此外,还可以使用required属性来强制填写日期。因此,如果您尝试提交超出设置范围的日期或空白日期字段,则支持的浏览器将显示错误。
让我们看一个例子-在这里我们设置了最小和最大日期,并且还设置了必填字段:
<form>
<div>
<label for="month">What Month would you like to visit us? (Summer months only.)</label>
<input id="month" type="month" name="month"
min="2017-06" max="2017-09" required>
<span class="validity"></span>
</div>
<div>
<input type="submit" value="Submit form">
</div>
</form>
如果您尝试提交日期不完整(或日期超出设定范围)的表单,浏览器将显示错误。
在这里,我们利用: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;
}
重要说明:HTML表单验证不能代替脚本来确保输入的数据采用正确的格式。对于某人来说,对HTML进行调整以使其绕过验证或完全删除验证太容易了。有人也可以完全绕过HTML并将数据直接提交到服务器。如果服务器端代码无法验证接收到的数据,则在提交格式不正确的数据(或太大,类型错误的数据等)时,灾难可能会发生。
处理浏览器支持
如上所述,在撰写本文时使用日期输入的主要问题是浏览器支持-仅Chrome / Opera和Edge在台式机上支持它,而大多数现代浏览器在移动设备上。例如,monthChrome for Android上的选择器如下所示:
不支持的浏览器会优雅地降级为文本输入,但这在用户界面的一致性(所提供的控件将有所不同)和数据处理方面都产生了问题。
第二个问题是最严重的-正如我们前面提到的,在month输入的情况下,实际值总是被标准化为format yyyy-mm。另一方面,使用文本输入时,默认情况下,浏览器无法识别日期应采用的格式,并且人们可以通过多种方式来写日期,例如:
- mmyyyy
- mm/yyyy
- mm-yyyy
- yyyy-mm
- 等等
解决此问题的一种方法是pattern在month输入中放置一个属性。即使month输入不使用它,文本输入的回退也将使用。例如,尝试在不支持的浏览器中查看以下演示:
<form>
<div>
<label for="month">What Month would you like to visit us? (Summer months only, yyyy-mm)</label>
<input id="month" type="month" name="month"
min="2017-06" max="2017-09" required
pattern="[0-9]{4}-[0-9]{2}">
<span class="validity"></span>
</div>
<div>
<input type="submit" value="Submit form">
</div>
</form>
如果您尝试提交,则您将看到浏览器现在显示错误消息(并将输入内容突出显示为无效),如果您输入的内容与pattern不匹配nnnn-nn,n则为0到9之间的数字。当然,不能阻止人们输入无效日期或遵循该格式的格式错误的日期。
什么样的用户将理解他们输入日期所需的模式?
我们仍然有问题。
目前,以跨浏览器方式处理表单中日期的最佳方法是让用户在单独的控件中输入月份和年份(<select>
流行的元素,请参见下文以了解实现),或使用JavaScript库(例如jQuery日期选择器和jQuery timepicker插件。
例子
在此示例中,我们创建了两组用于选择日期的UI元素-使用创建的本机选择器<input type="month">
,以及<select>
用于在不支持本机输入的旧版浏览器中选择月/年的两组元素。
HTML看起来像这样:
<form>
<div class="nativeDatePicker">
<label for="month-visit">What Month would you like to visit us?</label>
<input type="month" id="month-visit" name="month-visit">
<span class="validity"></span>
</div>
<p class="fallbackLabel">What Month would you like to visit us?</p>
<div class="fallbackDatePicker">
<div>
<span>
<label for="month">Month:</label>
<select id="month" name="month">
<option selected>January</option>
<option>February</option>
<option>March</option>
<option>April</option>
<option>May</option>
<option>June</option>
<option>July</option>
<option>August</option>
<option>September</option>
<option>October</option>
<option>November</option>
<option>December</option>
</select>
</span>
<span>
<label for="year">Year:</label>
<select id="year" name="year">
</select>
</span>
</div>
</div>
</form>
月份是硬编码的(因为它们始终相同),而年份值则根据当前年份动态生成(有关这些功能如何工作的详细说明,请参见下面的代码注释。)
代码的另一部分可能是功能检测代码-要检测浏览器是否支持<input type="month">
,我们创建一个新<input>
元素,将其设置type为month,然后立即检查其类型设置为-不支持的浏览器将返回text,因为date类型回退到type text。
如果<input type="month">
不支持,我们将隐藏本机选择器并显示后备选择器UI(<select>
)。
// define variables
var nativePicker = document.querySelector('.nativeDatePicker');
var fallbackPicker = document.querySelector('.fallbackDatePicker');
var fallbackLabel = document.querySelector('.fallbackLabel');
var yearSelect = document.querySelector('#year');
var monthSelect = document.querySelector('#month');
// 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 = 'month';
// 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 years dynamically
// (the months are always the same, therefore hardcoded)
populateYears();
}
function populateYears() {
// get the current year as a number
var date = new Date();
var year = date.getFullYear();
// Make this year, and the 100 years before it available in the year <select>
for(var i = 0; i <= 100; i++) {
var option = document.createElement('option');
option.textContent = year-i;
yearSelect.appendChild(option);
}
}
参考网站:https://developer.mozilla.org/zh/docs/web/html/element/input/%E6%9C%88%E4%BB%BD