<input type="week">
<input>
元素,当其 type
属性设置为 week
时,会创建一个允许用户方便地输入年份和该年份的 ISO 8601 周数(即第 1 周至第 52 或 53 周)的输入字段。
试一试
<label for="camp-week">Choose a week in May or June:</label>
<input
type="week"
name="week"
id="camp-week"
min="2018-W18"
max="2018-W26"
required />
label {
display: block;
font:
1rem "Fira Sans",
sans-serif;
}
input,
label {
margin: 0.4rem 0;
}
控件的用户界面因浏览器而异;目前跨浏览器支持略有限,仅 Chrome/Opera 和 Microsoft Edge 支持。在不支持的浏览器中,该控件会优雅地降级,其功能与 <input type="text">
相同。
值
一个字符串,表示输入框中输入的周/年值。此输入类型使用的日期和时间值的格式在 周字符串 中进行了描述。
您可以通过在 value
属性中包含一个值来设置输入的默认值,如下所示:
<label for="week">What week would you like to start?</label>
<input id="week" type="week" name="week" value="2017-W01" />
需要注意的是,显示格式可能与实际 value
不同,实际值始终是 yyyy-Www
格式。例如,当上述值提交到服务器时,浏览器可能会将其显示为 Week 01, 2017
,但提交的值将始终是 week=2017-W01
。
您还可以通过输入元素的 value
属性在 JavaScript 中获取和设置该值,例如:
const weekControl = document.querySelector('input[type="week"]');
weekControl.value = "2017-W45";
附加属性
除了 <input>
元素的通用属性外,周输入框还提供以下属性。
max
可接受的最新(时间上)年份和周数,格式为上面 值 部分讨论的字符串格式。如果元素中输入的 value
超过此值,则元素将 验证约束 失败。如果 max
属性的值不是有效的周字符串,则该元素没有最大值。
此值必须大于或等于 min
属性指定的年份和周数。
min
可接受的最早年份和周数。如果元素 value
小于此值,则元素将 验证约束 失败。如果为 min
指定了不是有效周字符串的值,则输入没有最小值。
此值必须小于或等于 max
属性的值。
readonly
一个布尔属性,如果存在,则表示该字段不能由用户编辑。但是,其 value
仍然可以通过 JavaScript 代码直接设置 HTMLInputElement
value
属性来更改。
注意: 由于只读字段不能有值,因此 required
对同时指定了 readonly
属性的输入没有影响。
step
step
属性是一个数字,指定值必须遵循的粒度,或者为特殊值 any
(如下所述)。只有与步长基数相差整数步长的值才有效。步长基数是 min
(如果已指定),否则为 value
,或者为 −259,200,000(1970-W01
周的开始),如果两者均未提供。
对于 week
输入框,step
的值以周为单位,并被视为一个数值,等于 step
值乘以 604,800,000 毫秒(底层数值单位为毫秒)。默认值为 1,表示 1 周。
字符串值 any
表示不隐含步长,允许任何值(排除其他约束,例如 min
和 max
)。实际上,对于 week
输入框,它的效果与 1
相同,因为选择器 UI 只允许选择整周。
注意:当用户输入的数据不符合步进配置时,用户代理可能会四舍五入到最近的有效值,当有两个同样接近的选项时,优先选择正方向的数字。
使用周输入框
周输入框乍一看似乎很方便,因为它们提供了方便的周选择 UI,并且无论用户浏览器或地区如何,都能将数据格式标准化以发送到服务器。然而,<input type="week">
存在一些问题,因为并非所有浏览器都能保证支持。
我们将介绍 <input type="week">
的基本用法和更复杂的用法,然后(参见 处理浏览器支持)提供有关缓解浏览器支持问题的建议。
周输入的基本用法
<input type="week">
最基本的使用涉及一个基本的 <input>
和 <label>
元素组合,如下所示:
<form>
<label for="week">What week would you like to start?</label>
<input id="week" type="week" name="week" />
</form>
控制输入大小
使用 step 属性
您应该能够使用 step
属性来改变每次递增或递减时跳过的周数,但似乎它对支持的浏览器没有任何影响。
验证
默认情况下,<input type="week">
不会对输入的值应用任何验证。UI 实现通常不允许您指定任何不是有效周/年的内容,这很有帮助,但仍然可以提交一个空字段,您可能希望限制可选周的范围。
设置最大和最小周数
您可以使用 min
和 max
属性来限制用户可以选择的有效周数。在以下示例中,我们将最小值为 Week 01, 2017
,最大值为 Week 52, 2017
:
<form>
<label for="week">What week would you like to start?</label>
<input id="week" type="week" name="week" min="2017-W01" max="2017-W52" />
<span class="validity"></span>
</form>
这是上面示例中使用的 CSS。在这里,我们利用 :valid
和 :invalid
CSS 属性来根据当前值是否有效来设置输入框的样式。我们不得不将图标放在输入框旁边的 <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;
}
结果是,只有 2017 年的 W01 到 W52 之间的周才被视为有效并在支持的浏览器中可选。
使周值成为必填项
此外,您还可以使用 required
属性使填写周数成为强制性。因此,支持的浏览器会在您尝试提交一个空的周字段时显示错误。
让我们看一个例子;这里我们设置了最小和最大周数,并将该字段设置为必填:
<form>
<div>
<label for="week">What week would you like to start?</label>
<input
id="week"
type="week"
name="week"
min="2017-W01"
max="2017-W52"
required />
<span class="validity"></span>
</div>
<div>
<input type="submit" value="Submit form" />
</div>
</form>
如果您尝试在没有值的情况下提交表单,浏览器会显示一个错误。现在就尝试玩一下这个例子吧。
对于不使用支持浏览器的用户,这里是一个截图。
警告: HTML 表单验证不能替代确保输入数据格式正确的脚本。有人很容易调整 HTML 以绕过验证,或完全删除它。也有可能有人完全绕过您的 HTML,直接将数据提交到您的服务器。如果您的服务器端代码未能验证收到的数据,当提交格式不正确的数据(或数据过大、类型错误等)时,可能会发生灾难。
处理浏览器支持
如上所述,目前使用周输入框的主要问题是浏览器支持:Safari 和 Firefox 在桌面端不支持,旧版本的 IE 也不支持。
Android 和 iOS 等移动平台可以完美利用这些输入类型,提供专门的 UI 控件,在触摸屏环境中非常容易选择值。例如,Android 版 Chrome 上的 week
选择器如下所示:
不支持的浏览器会优雅地降级为文本输入框,但这会在用户界面一致性(呈现的控件不同)和数据处理方面带来问题。
第二个问题更为严重。如前所述,对于 week
输入框,实际值始终被标准化为 yyyy-Www
格式。当浏览器回退到通用文本输入框时,没有任何东西可以引导用户正确格式化输入(而且它肯定不直观)。人们有多种方式可以书写周值;例如:
第 1 周 2017
2017 年 1 月 2 日至 8 日
2017-W01
- etc.
目前,在表单中以跨浏览器兼容的方式处理周/年的最佳方法是让用户在单独的控件中输入周数和年份(<select>
元素很受欢迎;请参见下面的示例),或者使用 JavaScript 库,例如 jQuery date picker。
示例
在此示例中,我们为周选择创建了两组 UI 元素:一组是使用 <input type="week">
创建的本机选择器,另一组是用于在不支持 week
输入类型的旧浏览器中选择周/年的两个 <select>
元素。
HTML 如下所示:
<form>
<div class="nativeWeekPicker">
<label for="week">What week would you like to start?</label>
<input
id="week"
type="week"
name="week"
min="2017-W01"
max="2018-W52"
required />
<span class="validity"></span>
</div>
<p class="fallbackLabel">What week would you like to start?</p>
<div class="fallbackWeekPicker">
<div>
<span>
<label for="week">Week:</label>
<select id="fallbackWeek" name="week"></select>
</span>
<span>
<label for="year">Year:</label>
<select id="year" name="year">
<option value="2017" selected>2017</option>
<option value="2018">2018</option>
</select>
</span>
</div>
</div>
</form>
周值由下面的 JavaScript 代码动态生成。
代码中可能还有其他感兴趣的部分是功能检测代码。为了检测浏览器是否支持 <input type="week">
,我们创建一个新的 <input>
元素,尝试将其 type
设置为 week
,然后立即检查其 type
设置为何值。不支持的浏览器将返回 text
,因为 week
类型会回退到 text
类型。如果 <input type="week">
不受支持,我们将隐藏本机选择器,而是显示回退选择器 UI(<select>
)。
// Get UI elements
const nativePicker = document.querySelector(".nativeWeekPicker");
const fallbackPicker = document.querySelector(".fallbackWeekPicker");
const fallbackLabel = document.querySelector(".fallbackLabel");
const yearSelect = document.querySelector("#year");
const weekSelect = document.querySelector("#fallbackWeek");
// 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
const test = document.createElement("input");
try {
test.type = "week";
} catch (e) {
console.log(e.description);
}
// 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 weeks dynamically
populateWeeks();
}
function populateWeeks() {
// Populate the week select with 52 weeks
for (let i = 1; i <= 52; i++) {
const option = document.createElement("option");
option.textContent = i < 10 ? `0${i}` : i;
weekSelect.appendChild(option);
}
}
注意: 请记住,有些年份有 53 周(请参阅 每年周数)!在开发生产应用程序时,您需要将此考虑在内。
技术摘要
值 | 一个表示周和年份的字符串,或为空 |
事件 |
change 和 input |
支持的常见属性 |
autocomplete , list , readonly , step |
IDL 属性 |
list , value , valueAsDate , valueAsNumber |
DOM 接口 | HTMLInputElement |
方法 |
select() 、stepDown() 和 stepUp() |
隐式 ARIA 角色 | 没有对应的角色 |
规范
规范 |
---|
HTML # week-state-(type=week) |
浏览器兼容性
加载中…