aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/web/html/element/input/week/index.html
blob: 8b93e611a457450744d6b5943f9e41f06e8d3c87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
---
title: <input type="week">
slug: Web/HTML/Element/Input/week
tags:
  - HTML
  - 元素
  - 参考
  - 周
  - 输出类型
translation_of: Web/HTML/Element/input/week
---
<div>{{HTMLRef("Input_types")}}</div>

<p><span class="seoSummary">{{HTMLElement("input")}} 类型为 <strong><code>week</code></strong> 的元素会创建输入字段,以便轻松输入年份以及该年(即第 1 周到<a href="https://en.wikipedia.org/wiki/ISO_8601#Week_dates">52 or 53</a>周)的<a href="https://en.wikipedia.org/wiki/ISO_8601#Week_dates">ISO 8601 week number</a> </span></p>

<div>{{EmbedInteractiveExample("pages/tabbed/input-week.html", "tabbed-shorter")}}</div>

<div class="hidden">该交互式示例的源存储在 GitHub 存储库中。 如果您想为交互式示例项目做出贡献,请克隆 <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> 并向我们发送请求请求。</div>

<p>控件的用户界面因浏览器而异; 跨浏览器的支持目前受到限制,目前只有 Chrome / Opera 和 Microsoft Edge 支持。 在不支持的浏览器中,该控件会正常降级,使其功能与 <code><a href="/en-US/docs/Web/HTML/Element/input/text">&lt;input type="text"&gt;</a></code>相同。</p>

<p>  在 Chrome / Opera 中,在<code>week</code>控件提供了用于填写周和年值的插槽,弹出式日历界面(可以更直观地选择它们)以及 “ X” 按钮以清除控件的值。</p>

<p><img alt="" src="https://mdn.mozillademos.org/files/15409/week-control-chrome.png" style="display: block; height: 235px; margin: 0px auto; width: 320px;"></p>

<p>Edge 的<code>week</code>控制更加精细,使用滚动的滚轮打开周和年的选择器。</p>

<p><img alt="" src="https://mdn.mozillademos.org/files/15411/week-control-edge.png" style="display: block; height: 391px; margin: 0px auto; width: 227px;"></p>

<table class="properties">
 <tbody>
  <tr>
   <td><strong><a href="#值"></a></strong></td>
   <td>A {{domxref("DOMString")}} representing a week and year, or empty</td>
  </tr>
  <tr>
   <td><strong>事件</strong></td>
   <td>{{domxref("HTMLElement/change_event", "change")}} and {{domxref("HTMLElement/input_event", "input")}}</td>
  </tr>
  <tr>
   <td><strong>支持的常用属性</strong></td>
   <td>{{htmlattrxref("autocomplete", "input")}}, {{htmlattrxref("list", "input")}}, {{htmlattrxref("readonly", "input")}}, and {{htmlattrxref("step", "input")}}</td>
  </tr>
  <tr>
   <td><strong>IDL 属性</strong></td>
   <td><code>value</code>, <code>valueAsDate</code>, <code>valueAsNumber</code>, 和 <code>list</code>.</td>
  </tr>
  <tr>
   <td><strong>方法</strong></td>
   <td>{{domxref("HTMLInputElement.select", "select()")}}, {{domxref("HTMLInputElement.stepDown", "stepDown()")}}, and {{domxref("HTMLInputElement.stepUp", "stepUp()")}}</td>
  </tr>
 </tbody>
</table>

<h2 id="值"></h2>

<p>一个 {{domxref("DOMString")}} 代表输入到输入中的星期/年的值。{{SectionOnPage("/en-US/docs/Web/HTML/Date_and_time_formats", "Format of a valid week string")}} 中描述了此输入类型使用的日期和时间值的格式。</p>

<p>您可以通过在 {{htmlattrxref("value", "input")}} 属性中包含一个值来为输入设置默认值,如下所示:</p>

<pre class="brush: html">&lt;label for="week"&gt;What week would you like to start?&lt;/label&gt;
&lt;input id="week" type="week" name="week" value="2017-W01"&gt;</pre>

<p>{{EmbedLiveSample('Value', 600, 60)}}</p>

<p>要注意的一件事是,显示的格式可能与<code>value</code>不同,后者始终采用 <code>yyyy-Www</code>格式。 例如,当将上述值提交给服务器时,浏览器可能会将其显示为 <code>Week 01, 2017</code>, 但是提交的值始终看起来像<code>week=2017-W01</code>.</p>

<p>您还可以使用输入元素的 {{domxref("HTMLInputElement.value", "value")}} 属性获取并设置 JavaScript 中的值,例如:</p>

<pre class="brush: js">var weekControl = document.querySelector('input[type="week"]');
weekControl.value = '2017-W45';</pre>

<h2 id="其他属性">其他属性</h2>

<p>除了 {{HTMLElement("input")}} 元素共有的属性外,周输入还提供以下属性:</p>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">属性</th>
   <th scope="col">描述</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td><code><a href="#max">max</a></code></td>
   <td>接受为有效输入的最新年份和星期</td>
  </tr>
  <tr>
   <td><code><a href="#min">min</a></code></td>
   <td>最早的年和周接受为有效输入</td>
  </tr>
  <tr>
   <td><code><a href="#readonly">readonly</a></code></td>
   <td>一个布尔值(如果存在),指示用户无法编辑字段的内容</td>
  </tr>
  <tr>
   <td><code><a href="#step">step</a></code></td>
   <td>用于用户界面和约束验证的步进间隔(允许值之间的距离)</td>
  </tr>
 </tbody>
</table>

<h3 id="max">max</h3>

<p>接受以上 <a href="#值"></a> 部分中讨论的字符串格式的最新(按时间)年份和星期数。 如果输入到元素中的 {{htmlattrxref("value", "input")}} 超过此值,则元素将无法通过<a href="/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation">约束验证</a>。 如果<code>max</code>属性的值不是有效的周字符串,则该元素没有最大值。</p>

<p>此值必须大于或等于<code>min</code> 属性指定的年和周。</p>

<h3 id="min">min</h3>

<p>最早接受的年和周。 如果元素的 {{htmlattrxref("value", "input")}}小于此值,则该元素将无法通过 <a href="/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation">约束验证</a>。 如果为<code>min</code>指定的值不是有效的星期字符串,则输入没有最小值。</p>

<p>该值必须小于或等于 <code>max</code> 属性的值。</p>

<p>{{page("/en-US/docs/Web/HTML/Element/input/text", "readonly", 0, 1, 2)}}</p>

<h3 id="step">step</h3>

<p>{{page("/en-US/docs/Web/HTML/Element/input/number", "step-include")}}</p>

<p>对于<code>week</code> 输入, <code>step</code> 的值以周为单位,比例因子为 604,800,000(因为基础数值以毫秒为单位)。 <code>step</code>的默认值为 1,表示 1 周。 默认的步进基数是-259,200,000,这是 1970 年第一周的开始 (<code>"1970-W01"</code>).</p>

<p><em>目前,尚不清楚当与<code>week</code>输入一起使用时,<code>"any"</code> 的值对<code>step</code> 意味着什么。 确定该信息后,将对其进行更新。</em></p>

<h2 id="使用星期输入">使用星期输入</h2>

<p>乍看之下,周输入听起来很方便,因为它们提供了用于选择周的简单 UI,并且它们标准化了发送到服务器的数据格式,而与用户的浏览器或区域设置无关。 但是, <code>&lt;input type="week"&gt;</code> 存在问题,因为不能保证所有浏览器都支持浏览器。</p>

<p>我们将研究 <code>&lt;input type="week"&gt;</code>的基本和更复杂的用法,然后在以后提供有关缓解浏览器支持问题的建议(请参阅 <a href="#处理浏览器支持">处理浏览器支持</a>).</p>

<h3 id="周的基本用途">周的基本用途</h3>

<p><code>&lt;input type="week"&gt;</code> 的最简单用法涉及基本的 <code>&lt;input&gt;</code>{{htmlelement("label")}} 元素组合,如下所示:</p>

<pre class="brush: html">&lt;form&gt;
  &lt;label for="week"&gt;What week would you like to start?&lt;/label&gt;
  &lt;input id="week" type="week" name="week"&gt;
&lt;/form&gt;</pre>

<p>{{EmbedLiveSample('Basic_uses_of_week', 600, 40)}}</p>

<h3 id="控制输入大小">控制输入大小</h3>

<p><code>&lt;input type="week"&gt;</code> 不支持 {{htmlattrxref("size", "input")}}. 您必须依靠<a href="/en-US/docs/Web/CSS">CSS</a>来确定大小 。</p>

<h3 id="使用step属性">使用 step 属性</h3>

<p>您应该能够使用{{htmlattrxref("step", "input")}} 属性来更改每次递增或递减的跳转周数,但是这似乎对支持浏览器没有任何影响。</p>

<h2 id="验证方式">验证方式</h2>

<p>默认情况下,<code>&lt;input type="week"&gt;</code> 不会对输入的值应用任何验证。 UI 实现通常不允许您指定不是有效的周/年的任何内容,这很有用,但是仍然可以在字段为空的情况下提交,并且您可能希望限制可选择的周数范围。</p>

<h3 id="设置最大和最小星期">设置最大和最小星期</h3>

<p>您可以使用 {{htmlattrxref("min", "input")}}{{htmlattrxref("max", "input")}} 属性来限制用户可以选择的有效周数。 在以下示例中,我们设置了 <code>Week 01, 2017</code> 的最小值和 <code>Week 52, 2017</code>的最大值:</p>

<pre class="brush: html">&lt;form&gt;
  &lt;label for="week"&gt;What week would you like to start?&lt;/label&gt;
  &lt;input id="week" type="week" name="week"
         min="2017-W01" max="2017-W52"&gt;
  &lt;span class="validity"&gt;&lt;/span&gt;
&lt;/form&gt;</pre>

<p>{{EmbedLiveSample('Setting_maximum_and_minimum_weeks', 600, 40)}}</p>

<p>这是上面示例中使用的 CSS。 在这里,我们利用{{cssxref(":valid")}} and {{cssxref(":invalid")}} CSS 属性根据当前值是否有效来设置输入的样式。 我们必须将图标放在输入旁边的 {{htmlelement("span")}} 上,而不是输入本身上,因为在 Chrome 中,生成的内容位于表单控件内,无法设置样式或显示 有效。</p>

<pre class="brush: css">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;
}</pre>

<p>结果是,在 2017 年 W01 到 W52 之间只有几周才被视为有效,并且可以在支持的浏览器中选择。</p>

<h3 id="使周值成为必需">使周值成为必需</h3>

<p>另外,您可以使用 {{htmlattrxref("required", "input")}} }属性来强制填写星期。 因此,如果您尝试提交空白的星期字段,则支持的浏览器将显示错误。</p>

<p>让我们看一个例子; 在这里,我们设置了最小和最大周数,并设置了必填字段:</p>

<pre class="brush: html">&lt;form&gt;
  &lt;div&gt;
    &lt;label for="week"&gt;What week would you like to start?&lt;/label&gt;
    &lt;input id="week" type="week" name="week"
         min="2017-W01" max="2017-W52" required&gt;
    &lt;span class="validity"&gt;&lt;/span&gt;
  &lt;/div&gt;
  &lt;div&gt;
      &lt;input type="submit" value="Submit form"&gt;
  &lt;/div&gt;
&lt;/form&gt;</pre>

<p>如果您尝试提交不带任何值的表单,浏览器将显示错误。 现在尝试使用示例:</p>

<p>{{EmbedLiveSample('Making_week_values_required', 600, 120)}}</p>

<p>这是不使用支持的浏览器的屏幕截图:</p>

<p><img alt="" src="https://mdn.mozillademos.org/files/15415/week-validation-chrome.png" style="display: block; height: 85px; margin: 0px auto; width: 473px;"></p>

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

<h2 id="处理浏览器支持">处理浏览器支持</h2>

<p>如上所述,现在使用星期输入的主要问题是浏览器支持:Safari 和 Firefox 在桌面上不支持它,而旧版本的 IE 不支持它。</p>

<p><br>
 诸如 Android 和 iOS 之类的移动平台确实很好地利用了这种输入类型,提供了专门的 UI 控件,使在触摸屏环境中选择值变得非常容易。 例如,Android 版 Chrome 上的周选择器如下所示:<img alt="" src="https://mdn.mozillademos.org/files/15413/week-chrome-android.png" style="display: block; margin: 0 auto;"></p>

<p>不支持的浏览器会优雅地降级为文本输入,但这在用户界面的一致性(所提供的控件将有所不同)和数据处理方面都产生了问题。</p>

<p>第二个问题是更严重的。 如前所述,在输入一个<code>week</code> 的情况下,实际值始终会归一化为 <code>yyyy-Www</code>格式。当浏览器退回通用文本输入时,没有什么可以指导用户正确格式化输入的格式(这肯定是不直观的)。 人们可以通过多种方式来写星期值。 例如:</p>

<ul>
 <li><code>2017 年第 1 周</code></li>
 <li><code>2017 年 1 月 2 日至 8 日</code></li>
 <li><code>2017-W01</code></li>
 <li>等等。</li>
</ul>

<p>目前,以跨浏览器方式处理星期/年的最佳方法是让用户在单独的控件中输入星期数和年份 ({{htmlelement("select")}} 元素很流行; 参见下面的示例),或使用 JavaScript 库(例如 <a href="https://jqueryui.com/datepicker/">jQuery 日期选择器</a></p>

<h2 id="例子">例子</h2>

<p>在此示例中,我们创建了两组用于选择星期的 UI 元素:使用 <code>&lt;input type="week"&gt;</code>,创建的本机选择器,以及两个用于选择星期/年的 {{htmlelement("select")}} 元素的集合 不支持<code>week</code>输入类型的旧版浏览器。  </p>

<p>{{EmbedLiveSample('Examples', 600, 140)}}</p>

<p>HTML 看起来像这样:</p>

<pre class="brush: html">&lt;form&gt;
  &lt;div class="nativeWeekPicker"&gt;
    &lt;label for="week"&gt;What week would you like to start?&lt;/label&gt;
    &lt;input id="week" type="week" name="week"
           min="2017-W01" max="2018-W52" required&gt;
    &lt;span class="validity"&gt;&lt;/span&gt;
  &lt;/div&gt;
  &lt;p class="fallbackLabel"&gt;What week would you like to start?&lt;/p&gt;
  &lt;div class="fallbackWeekPicker"&gt;
    &lt;div&gt;
      &lt;span&gt;
        &lt;label for="week"&gt;Week:&lt;/label&gt;
        &lt;select id="fallbackWeek" name="week"&gt;
        &lt;/select&gt;
      &lt;/span&gt;
      &lt;span&gt;
        &lt;label for="year"&gt;Year:&lt;/label&gt;
        &lt;select id="year" name="year"&gt;
          &lt;option value="2017" selected&gt;2017&lt;/option&gt;
          &lt;option value="2018"&gt;2018&lt;/option&gt;
        &lt;/select&gt;
      &lt;/span&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/form&gt;</pre>

<p>周值由下面的 JavaScript 代码动态生成。</p>

<div class="hidden">
<pre class="brush: css">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;
}</pre>
</div>

<p>该代码中可能感兴趣的另一部分是特征检测代码。 要检测浏览器是否支持<code>&lt;input type="week"&gt;</code>, 我们创建一个新的 {{htmlelement("input")}} 元素,尝试将其 <code>type</code> 设置为 <code>week</code>, 然后立即检查其 <code>type</code> 设置为。  不支持的浏览器将返回<code>text</code>,因为<code>week</code>类型回退为<code>text</code>类型。 如果不支持 ,  <code>&lt;input type="week"&gt;</code> 我们将隐藏本机选择器并显示后备选择器 UI ({{htmlelement("select")}}s) .</p>

<pre class="brush: js">// define variables
var nativePicker = document.querySelector('.nativeWeekPicker');
var fallbackPicker = document.querySelector('.fallbackWeekPicker');
var fallbackLabel = document.querySelector('.fallbackLabel');

var yearSelect = document.querySelector('#year');
var 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
var 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(var i = 1; i &lt;= 52; i++) {
    var option = document.createElement('option');
    option.textContent = (i &lt; 10) ? ("0" + i) : i;
    weekSelect.appendChild(option);
  }
}</pre>

<div class="note">
<p><strong>注意:</strong> 请记住,有些年份有 53 周(请参阅 <a href="https://en.wikipedia.org/wiki/ISO_week_date#Weeks_per_year">每年的周数</a>)! 在开发生产应用程序时,您需要考虑到这一点。</p>
</div>

<h2 id="技术指标">技术指标</h2>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">规格</th>
   <th scope="col">状态</th>
   <th scope="col">评论</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>{{SpecName('HTML WHATWG', 'forms.html#week-state-(type=week)', '&lt;input type="week"&gt;')}}</td>
   <td>{{Spec2('HTML WHATWG')}}</td>
   <td></td>
  </tr>
 </tbody>
</table>

<h2 id="浏览器兼容性">浏览器兼容性</h2>

<p>{{Compat("html.elements.input.input-week")}}</p>

<h2 id="另请详见">另请详见</h2>

<ul>
 <li>通用 {{HTMLElement("input")}} 元素和用于操作该元素的接口 {{domxref("HTMLInputElement")}}</li>
 <li><a href="/en-US/docs/Web/HTML/Date_and_time_formats">HTML 中使用的日期和时间格式</a></li>
 <li><code><a href="/en-US/docs/Web/HTML/Element/input/datetime-local">&lt;input type="datetime-local"&gt;</a></code>, <code><a href="/en-US/docs/Web/HTML/Element/input/date">&lt;input type="date"&gt;</a></code>, <code><a href="/en-US/docs/Web/HTML/Element/input/time">&lt;input type="time"&gt;</a></code>, 和 <code><a href="/en-US/docs/Web/HTML/Element/input/month">&lt;input type="month"&gt;</a></code></li>
</ul>