转载

【译】原生表单组件

HTML表单 是由组件构成的,这些组件是各种浏览器都支持的内置控件。本文中我们将深入探讨它们、了解它们的作用、学习如何让各种浏览器更好地支持它们。

虽然这里我们只探讨内建表单组件,但由于HTML表单有诸多限制、以及不同浏览器间的实现有很多的不同,故web开发者有时也得构建自定义的表单组件。这部分内容将会在[怎样创建定制表单组件]()一文中详细讨论。

文本输入框

文本输入框是最基本的表单组件,它便于用户输入各种数据。然而一些文本框也可以专门用来实现一些特定需求。

值得注意的是,HTML文本框只是个纯文本输入控件。这就意味着你不能用它来进行 富文本编辑 (如加粗、斜体等)。所谓的富文本编辑器其实都是自定义的组件。

所有文本框都共享一些公共行为:

  • 它们可以被标记为 只读 (用户不可修改输入的值)或者 禁用 (输入的值不会随着表单的其他部分一起提交)。

  • 它们可拥有一个 占位符 ;这是一小段在文本输入框内的、用于简明描述文本框作用的文本。

  • 它们都受 size (输入框的物理尺寸)和 length (文本框能输入的最大字符数)的约束。

  • 它们可以有 拼写检查 ,如果浏览器支持的话。

兼容性表

属性(桌面端) Chrome Firefox (Gecko) IE Opera Safari
<input> .readonly 1.0 1.0 (1.7 or earlier) 6 1.0 1.0
<input> .disabled 1.0 1.0 (1.7 or earlier) 6 1.0 1.0
<input> .placeholder 10.0 Unknown (4.0) 10 11.10 4.0
<textarea> .placeholder 10.0 Unknown (4.0) 10 11.50 5.0
<input> .size 1.0 1.0 (1.7 or earlier) 2 1.0 1.0
<input> .maxlength 1.0 1.0 (1.7 or earlier) 2 1.0 1.0
<input> .spellcheck 10.0 Unknown (3.6) 10 11.0 4.0
属性(移动端) Android Firefox (Gecko) IE Opera Safari
<input> .readonly (Yes) 4.0 (4.0) (Yes) (Yes) (Yes)
<input> .disabled (Yes) 4.0 (4.0) (Yes) (Yes) (Yes)
<input> .placeholder 2.3 4.0 (4.0) ? 11.10 4
<textarea> .placeholder ? 4.0 (4.0) ? 11.50 4
<input> .size (Yes) 4.0 (4.0) (Yes) (Yes) (Yes)
<input> .maxlength (Yes) 4.0 (4.0) (Yes) (Yes) (Yes)
<input> .spellcheck ? 4.0 (4.0) ? 11.0 ?

单行文本框

单行文本框是用 type 属性值为 text<input> 元素创建的(若未提供 type 属性值, text 也是个默认属性)。此外,如果你指定给 type 属性的值不被浏览器支持,也会使用 text 作为回退值。

<input type="text">

【译】原生表单组件

单行文本框只有一个约束:若你输入的文本中有换行,浏览器会在发送数据前将这个换行给移除。

但是,我们也可以给单行文本框“按需”添加一些约束。这得用到 pattern 属性;该属性会告诉浏览器根据你选择的一个 正则表达式 来验证值的有效性。

<input type="text" pattern="^cherry|banana$">

HTML5添加了几个 type 属性的值来增强基本的单行文本框。虽然这些值仍会把 <input> 元素呈现为一个单行文本框,但实际上它们还给文本框添加了几个额外的约束和特性。

E-mail输入框

该类型的输入框设置了 type 值为 email

<input type="email" multiple>

它给输入框添加了这样的验证约束:用户需要输入一个有效的e-mail地址;其他任何输入都会导致输入框报错。而通过设置 multiple 属性,这种输入框也可以让用户输入多个e-mail地址。

密码输入框

该类型的输入框设置了 type 值为 password

<input type="password">

它并未给输入文本添加任何特殊的约束,只是把输入框的里值做了隐藏以防止被读取。

注:注意这只是个用户界面的特性;浏览器还是会发送纯文本,除非你用Javascript给文本进行编码。

搜索框

该类型的输入框设置了 type 值为 search

<input type="search" autosave>

【译】原生表单组件

文本框和搜索框的主要区别在于外观和体验上(通常,搜索框会以圆角呈现)。但其实搜索框还增加了一个特性:输入的值可被自动保存,以实现在同一站点的不同页面中给出自动补全。

电话号码输入框

该类型的输入框设置了 type 值为 tel

<input type="tel">

由于世界上有多种电话号码制式,所以此类型的的文本框不会给用户输入的值强制使用任何约束,主要是一个语义上的区别而已。虽然在某些设备上(尤其是手机)点击该输入框,会出现一个不同的虚拟键盘。

URL输入框

该类型的输入框设置了 type 值为 url

<input type="url">

为确保只输入有效的URL,它为输入框添加了些特殊的验证约束;若输入的值不是个符合格式的URL,表单将会呈现错误状态。

注:URL符合格式并不意味着它指向确切存在的地址。

有特殊约束并处于错误状态的输入框会阻止表单提交;此外,为让错误提示更明显,也可以为它们加些样式,我们将在[表单数据验证]()一文中详细讨论这点。

兼容性表

属性(桌面端) Chrome Firefox (Gecko) IE Opera Safari
<input> .type="text" 1.0 1.0 (1.7 or earlier) 2 1.0 1.0
<input> .type="email" 10.0 Unknown (4.0) 10 10.62 ?
<input> .type="password" 1.0 1.0 (1.7 or earlier) 2 1.0 1.0
<input> .type="search" 5.0 Unknown (4.0) 10 11.01 5.0
<input> .type="tel" 5.0 Unknown (4.0) 10 11.01 5.0
<input> .type="url" 10.0 Unknown (4.0) 10 10.62 ?
属性(移动端) Android Firefox (Gecko) IE Opera Safari
<input> .type="text" (Yes) 4.0 (4.0) (Yes) (Yes) 1.0
<input> .type="email" Not supported 4.0 (4.0) Not supported (Yes) ?
<input> .type="password" ? 4.0 (4.0) ? ? ?
<input> .type="search" Not supported 4.0 (4.0) ? (Yes) 4.0
<input> .type="tel" 2.3 4.0 (4.0) ? (Yes) 3.1
<input> .type="url" Not supported 4.0 (4.0) ? (Yes) 3.1

多行文本框

多行文本框使用了 <textarea> 元素而非 <input> 元素。

<textarea cols="20" rows="10"></textarea>

多行文本框与普通的单行文本框间的主要不同在于,用户可以输入带有显式换行(即支持回车[CR]和换行[LF]字符)的文本。

值得注意的是,使用CSS属性 resize ,用户可以直接改变多行文本框大小,如果你想让他们这么做的话。

【译】原生表单组件

兼容性表

属性(桌面端) Chrome Firefox (Gecko) IE Opera Safari
<textarea> (Yes) 1.0 (1.7 or earlier) (Yes) (Yes) (Yes)
属性(移动端) Android Firefox (Gecko) IE Opera Safari
<textarea> (Yes) 4.0 (4.0) (Yes) (Yes) (Yes)

下拉组件

下拉组件能让用户很方便地从众多选项中作选择。HTML有两种下拉组件:选择框和自动补全组件。这两者的交互方式是一样的,一旦控件被激活,浏览器会展示一列表的值让用户从中选择,这个值列表会覆盖在页面内容之上。

选择框

选择框是通过 <select> 元素创建的,并使用一或多个 <option> 元素作为其子元素,每个 <option> 都指定了一个可能的值。

<select>   <option>Banana</option>   <option>Cherry</option>   <option>Lemon</option> </select>

若有需要,选择框的默认值可通过为相应的 <option> 元素设置 selected 属性进行指定。为了给值创建分组, <option> 元素亦可嵌套于 <optgroup> 元素中:

<select>   <optgroup label="fruits">     <option>Banana</option>     <option selected>Cherry</option>     <option>Lemon</option>   </optgroup>   <optgroup label="vegetables">     <option>Carrot</option>     <option>Eggplant</option>     <option>Potatoe</option>   </optgroup> </select>

【译】原生表单组件

兼容性表

属性(桌面端) Chrome Firefox (Gecko) IE Opera Safari
<select> 1.0 1.0 (1.7 or earlier) (Yes) (Yes) (Yes)
<option> 1.0 1.0 (1.7 or earlier) (Yes) (Yes) (Yes)
<optgroup> 1.0 1.0 (1.7 or earlier) (Yes) (Yes) (Yes)
属性(移动端) Android Firefox (Gecko) IE Opera Safari
<select> 1.0 4.0 (4.0) (Yes) (Yes) (Yes)
<option> 1.0 4.0 (4.0) (Yes) (Yes) (Yes)
<optgroup> 1.0 4.0 (4.0) (Yes) (Yes) (Yes)

多选下拉框

默认的,选择框只允许用户选择一个值。要让用户能选择多个值,可通过给 <select> 元素添加 multiple 属性实现。但此时,选择框就不再呈现为一个下拉组件了,反而呈现为一个普通的列表框。

<select multiple>   <option>Banana</option>   <option>Cherry</option>   <option>Lemon</option> </select>

【译】原生表单组件

注:所有支持 <select> 元素的浏览器也都支持它的 multiple 属性。

自动补全组件

通过使用 <datalist> 元素,你可以给表单组件提供说明、自动补全的值,并通过子元素 <option> 来指定要呈现的值。设置好后,这份数据列表就能绑定到其他使用了 list 属性的组件上了。

一旦数据列表附加到一个表单组件上,它的选项就能被用于自动补全用户输入的文本;典型的情况是,选项被呈现为一个带有可能匹配的值的下拉框。

<label for="myFruit">What's your favorite fruit?</label> <input type="text" id="myFruit" list="mySuggestion" /> <datalist id="mySuggestion">   <option>Apple</option>   <option>Banana</option>   <option>Blackberry</option>   <option>Blueberry</option>   <option>Lemon</option>   <option>Lychee</option>   <option>Peach</option>   <option>Pear</option> </datalist>

【译】原生表单组件

注:根据 HTML规范 , list 属性和 <datalist> 元素可被用于任何需要用户输入的组件上。然而,其并未清楚指明如何在非文本控件上使用,同时不同浏览器的实现也是各有不同。所以,要在非文本控件使用该特性得多加小心。

兼容性表

属性(桌面端) Chrome Firefox (Gecko) IE Opera Safari
<datalist> 20.0 Unknown (4.0) 10 9.6 Not supported
<input> .list 20.0 Unknown (4.0) 10 9.6 Not supported
属性(移动端) Android Firefox (Gecko) IE Opera Safari
<datalist> Not supported 4.0 (4.0) Not supported (Yes) Not supported
<input> .list Not supported 4.0 (4.0) Not supported (Yes) Not supported

可勾选组件

可勾选组件指的是可以通过点击改变其状态的组件。有两种可勾选组件:复选框和单选框,它们都可以通过 checked 属性来指示该组件是否默认被勾选。

值得注意的是,这些组件的行为和其他表单组件不太一样。对大多数表单组件而言,表单提交后所有具有 name 属性的组件都会被提交,即使它们没有获值。但对于可勾选组件,它们的值却只有在它们被勾选之后才会提交,如果没有勾选,则不会提交东西,包括其 name 属性。

复选框

复选框由设置了 type 值为 checkbox<input> 元素创建:

<input type="checkbox" checked>

上面的HTML创建的复选框是默认勾选的。

【译】原生表单组件

兼容性表

属性(桌面端) Chrome Firefox (Gecko) IE Opera Safari
<input> .type="checkbox" 1.0 1.0 (1.7 or earlier) 2 1.0 1.0
属性(移动端) Android Firefox (Gecko) IE Opera Safari
<input> .type="checkbox" 1.0 1.0 (1.0) (Yes) (Yes) (Yes)

单选框

单选框由设置了 type 值为 radio<input> 元素创建:

<input type="radio" checked>

几个单选框可以被绑定在一起,只要它们使用相同的 name 属性值,它们就被视为同一组选框。而在同一组中,只有一个选框能被勾选;这意味着其中一个勾选之后,其他所有选框会自动不勾选。

到了表单提交时,也只有被勾选的值会被提交;如果没有勾选,整组单选框会被认为处于未知状态且不会随表单提交。

【译】原生表单组件

兼容性表

属性(桌面端) Chrome Firefox (Gecko) IE Opera Safari
<input> .type="radio" 1.0 1.0 (1.7 or earlier) 2 1.0 1.0
属性(移动端) Android Firefox (Gecko) IE Opera Safari
<input> .type="radio" 1.0 1.0 (1.0) (Yes) (Yes) (Yes)

按钮

HTML表单中,有三种按钮:

提交按钮

用于发送表单数据给服务器。

重置按钮

用于重置所有表单组件为默认值。

匿名按钮

这种按钮不自带特效,但也可以通过Javascript代码进行自定义。

按钮可以由 <button> 元素或 <input> 元素创建。 type 属性的值会指定将呈现何种按钮。

提交按钮

<button type="submit">     This a <br><strong>submit button</strong> </button> <input type="submit" value="This is a submit button">

重置按钮

<button type="reset">     This a <br><strong>reset button</strong> </button> <input type="reset" value="This is a reset button">

匿名按钮

<button type="button">     This a <br><strong>anonymous button</strong> </button> <input type="button" value="This is a anonymous button">

通常使用 <button><input> 创建的按钮行为都是一样的。然而也存在几点不同:

  • 就如先前的例子所示, <button> 元素允许你使用HTML内容作为其标记内容,但 <input> 元素只接受纯文本内容。

  • 使用 <button> 元素是,可以采用和按钮中内容不一样的值。(但在IE8以下的浏览器中这是不可行的)

【译】原生表单组件

兼容性表

属性(桌面端) Chrome Firefox (Gecko) IE Opera Safari
<input> .type="number" 1.0 1.0 (1.7 or earlier) 2 1.0 1.0
<input> .type="reset" 1.0 1.0 (1.7 or earlier) 2 1.0 1.0
<input> .type="button" 1.0 1.0 (1.7 or earlier) 3 1.0 1.0
<button> 1.0 1.0 (1.7 or earlier) (Yes)(Buggy before IE8) (Yes) (Yes)
属性(移动端) Android Firefox (Gecko) IE Opera Safari
<input> .type="number" 1.0 1.0 (1.0) (Yes) (Yes) (Yes)
<input> .type="reset" 1.0 1.0 (1.0) (Yes) (Yes) (Yes)
<input> .type="button" 1.0 1.0 (1.0) (Yes) (Yes) (Yes)
<button> 1.0 1.0 (1.0) (Yes) (Yes) (Yes)

高级表单组件

这一系列的组件能让用户输入一些复杂或高度结构化的数据,包括精确或近似数字、日期和时间、颜色。

数字

数字组件是通过 type 设置为 number<input> 元素创建的。该控件看起来像文本框,但却只允许输入浮点数,而且通常还会带有几个按钮来增加或减少组件的值。

我们可以通过设置 minmax 属性来约束该组件的值。也可以通过 step 属性来指定该组件的增加和减少按钮的改变量。

<input type="number" min="1" max="10" step="2">

上述代码创建了一个取值被限制在1到10之间的数字组件,其增加和减少按钮的改变量为2。

兼容性表

属性(桌面端) Chrome Firefox (Gecko) IE Opera Safari
<input> .type="number" 11.0 Not supported 10
(recognized but no UI) (Yes) 5.2
属性(移动端) Android Firefox (Gecko) IE Opera Safari
<input> .type="number" 2.3 Not supported Not supported (Yes) 4.0

滑块

另一种选取数字的方法是使用滑块。由于操作滑块看起来不及文本框输入数字精确,所以滑块常用于选取对值的要求不是很精确的数字。

滑块组件是通过 type 设置为 range<input> 元素创建的。适当配置滑块是很重要的,强烈推荐你设置其 min , max , step 属性。

<input type="range" min="1" max="5" step="1">

示例中创建了一个取值被限制在1到5之间的滑块组件,其增加和减少按钮的改变量分别为+1和-1。

兼容性表

属性(桌面端) Chrome Firefox (Gecko) IE Opera Safari
<input> .type="range" 5.0 23.0 10 10.62 4.0
属性(移动端) Android Firefox (Gecko) IE Opera Safari
<input> .type="range" Not supported 23.0 Not supported 10.62 5.0

日期和时间选择器

收集日期和时间的值在之前往往是web开发者的噩梦。现在HTML5通过引入一个特殊的控件用于处理这类特定的数据,带来了一些新改进。

日期和时间控件是通过 type 设置为特定值的 <input> 元素创建的。因为你可能希望能收集日期、时间或者两者兼有,所以它提供了几个不同的 type 属性值:

date

创建展示和选取日期、但不含具体时间的组件。

<input type="date">

datetime

创建展示和选取日期、并带有UTC时区时间的组件。

<input type="datetime">

datetime-local

创建展示和选取日期、并带有任何指定时区时间的组件。

<input type="datetime-local">

month

创建展示和选取月份、并带有年份的组件。

<input type="month">

time

创建展示和选取一个时间值的组件。

<input type="time">

week

创建展示和选取周数、并带其年份的组件。

<input type="week">

所有的日期与时间控件都可以使用 maxmin 属性进行约束:

<label for="myDate">When are you available this summer?</label> <input type="date" min="2013-06-01" max="2013-08-31" id="myDate">

兼容性表

属性(桌面端) Chrome Firefox (Gecko) IE Opera Safari
<input> .type="date" Not supported Not supported Not supported 10.62 (Yes)
<input> .type="datetime" Not supported Not supported Not supported 10.62 (Yes)
<input> .type="datetime-local" Not supported Not supported Not supported 10.62 (Yes)
<input> .type="month" Not supported Not supported Not supported 10.62 (Yes)
<input> .type="time" Not supported Not supported Not supported 10.62 (Yes)
<input> .type="week" Not supported Not supported Not supported 10.62 (Yes)
属性(移动端) Android Firefox (Gecko) IE Opera Safari
<input> .type="date" Not supported Not supported Not supported 10.62 5.0
<input> .type="datetime" Not supported Not supported Not supported 10.62 (Yes)
<input> .type="datetime-local" Not supported Not supported Not supported 10.62 (Yes)
<input> .type="month" Not supported Not supported Not supported 10.62 (Yes)
<input> .type="time" Not supported Not supported Not supported 10.62 (Yes)
<input> .type="week" Not supported Not supported Not supported 10.62 (Yes)

警告:日期和时间组件都是很新的组件,甚至那些声称支持它们的浏览器也常有重大的用户界面问题,这让这些组件很难被使用。所以在发布你的内容之前,请先彻底地在不同的浏览器上测试一遍!

颜色选择器

通常颜色都有点难于处理,因为有许多种方式来表示它们:RGB值(十进制或十六进制)、HSL值、关键字等等。而颜色选择器能方便用户以文本或图形的形式选择颜色。

颜色组件是通过 type 设置为 color<input> 元素创建的。

<input type="color">

兼容性表

属性(桌面端) Chrome Firefox (Gecko) IE Opera Safari
<input> .type="color" 21.0 Not supported Not supported 11.01 Not supported
属性(移动端) Android Firefox (Gecko) IE Opera Safari
<input> .type="color" Not supported Not supported Not supported ? Not supported

其他组件

还有一些组件难以被归类,因为它们拥有一些非常特殊的行为;但其实它们也是很有用的。

文件选择器

HTML表单可以向服务器发送文件,关于这点,在[发送表单数据]()一文中有详细的讨论。文件选择器组件是让用户选择一或多个文件进行发送的一种方式。

文件选择器组件是通过 type 设置为 file<input> 元素创建的。被接收的文件类型可通过使用 accept 属性进行指定;此外,若你想让用户选择不止一个文件,可以添加 multiple 属性。

在下面的例子中,我们创建了一个接收图像图形文件的文件选择器,它也允许用户选择多个文件。

<input type="file" accept="image/*" multiple>

兼容性表

属性(桌面端) Chrome Firefox (Gecko) IE Opera Safari
<input> .type="file" 1.0 1.0 (1.7 or earlier) 3.02 1.0 1.0
属性(移动端) Android Firefox (Gecko) IE Opera Safari
<input> .type="file" ? ? ? ? ?

隐藏内容

有时因为技术原因,我们得让一些随表单发送的数据对用户不可见。要这样做,你可以在你的表单中添加一个隐藏元素,只需使用 type 设置为 hidden<input> 元素。

若你创建了这种元素,还必须设置其 namevalue 属性:

<input type="hidden" name="timestamp" value="1286705410">

兼容性表

属性(桌面端) Chrome Firefox (Gecko) IE Opera Safari
<input> .type="hidden" 1.0 1.0 (1.7 or earlier) 2 1.0 1.0
属性(移动端) Android Firefox (Gecko) IE Opera Safari
<input> .type="hidden" (Yes) (Yes) (Yes) (Yes) (Yes)

图像按钮

图像按钮控件表面看起来就像是 <img> 元素,除非被用户点击,它才会具有提交按钮的行为(参见上文)。

图像按钮是通过 type 设置为 image<input> 元素创建的。该元素支持与 <img> 元素相同的属性集,且还加上了表单按钮支持的那些属性。

<input type="image" alt="Click me!" src="my-img.png" width="80" height="30" />

若图像按钮被用于提交表单,它不会提交它的值,而是提交在图片上点击的X和Y坐标(坐标是相对图像而言的,取左上角为(0, 0)坐标)。坐标以两个键/值对的形式发送,X值的键名是 name 属性的值加上字符串".x",Y值的键名是 name 属性的值加上字符串".y"。这样就提供了一种便于创建“热点地图”的方式。

举个例子:

<form action="http://foo.com" method="get">   <!-- 译注:原文是value="pos",明显是错的,下面已改正 -->   <input type="image" name="pos" alt="" src="map.png" /> </form>

当你点击这个表单的图像时,你会发送出如下URL:

http://foo.com?pos.x=123&pos.y=456

pos.xpos.y 参数的值取决于你点击了图片上哪个地方。这些数据的发送和检索将在[发送表单数据]()一文中讨论。

兼容性表

属性(桌面端) Chrome Firefox (Gecko) IE Opera Safari
<input> .type="image" 1.0 1.0 2 1.0 1.0
属性(移动端) Android Firefox (Gecko) IE Opera Safari
<input> .type="image" (Yes) (Yes) (Yes) (Yes) (Yes)

度量和进度条

度量和进度条是数字值的可视化表示。

进度条代表一个随时间变化、直至达到由 max 属性指定的最大值的值。进度条使用 <progress> 元素进行创建, <progress> 元素的内容用于让不支持该元素的浏览器作降级处理、也让无障碍设备能读出来。

<progress max="100" value="75">75/100</progress>

度量条表示一个处于由 minmax 值划分的范围的固定值。该值被渲染为一个长条,长条使用 <meter> 元素进行创建, <meter> 元素的内容用于让不支持该元素的浏览器作降级处理、也让无障碍设备能读出来。

<meter min="0" max="100" value="75" low="33" high="66" optimum="50">75</meter>

而要知道该长条长什么样子,我们还得比较它的 value 值与另外几个值:

  • lowhigh 值将一个长条的范围划分了三个部分:

    • 范围较低的那部分位于 minlow 之间(含这两个值)。

    • 范围的中间部分位于 lowhigh 之间(不含这两个值)。

    • 范围较高的那部分位于 highmax 之间(含这两个值)。

  • optimum 值定义了 <meter> 元素的最佳值。结合 lowhigh 值,就能确定一个长条范围的哪个部分是最佳的:

    • optimum 值位于范围较低的那部分,则较低的那部分是最佳的部分,中间部分是平均的部分,较高的那部分则是最差的部分。

    • optimum 值位于范围的中间部分,则较低的那部分是平均的部分,中间部分是最佳的部分,较高的那部分也还是平均的部分。

    • optimum 值位于范围较高的那部分,则较低的那部分是最差的部分,中间部分是平均的部分,较高的那部分是最佳的部分。

所有实现了 <meter> 元素的浏览器都会使用上述的值来改变度量长条的颜色:

  • 若现在的值位于范围最佳的部分,则长条显示为绿色。

  • 若现在的值位于范围平均的部分,则长条显示为黄色。

  • 若现在的值位于范围最差的部分,则长条显示为红色。

兼容性表

属性(桌面端) Chrome Firefox (Gecko) IE Opera Safari
<progress> 6.0 6.0(6.0) 10 10.6 5.2
<meter> 6.0 16.0(16.0) Not supported 11.0 5.2
属性(移动端) Android Firefox (Gecko) IE Opera Safari
<progress> Not supported 6.0(6.0) Not supported 11.0 ?
<meter> Not supported 16.0(16.0) Not supported 11.0 ?

参见

若要深入了解表单组件的不同,这里还提供了一些你应该看看的有用资源:

  • The Current State of HTML5 Forms by Wufoo

  • HTML5 Tests - inputs on Quirksmode (也可 用于移动端浏览器 )

原文  https://segmentfault.com/a/1190000005367760
正文到此结束
Loading...