购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

第4章
表格和表单

表格在生活中随处可见,例如,学校在进行班级统计时,就常常使用表格来展示各年级的学生人数。以尚硅谷北京校区为例,其各学科在校人数统计如表4-1所示。

表4-1 尚硅谷北京校区各学科在校人数统计

表单在生活中出现的次数更多,例如,在登录尚硅谷谷粒学苑网站的时候会出现一个表单,如图4-1所示。此时,需要在文本框中填写对应信息,最后点击“提交”按钮,即可将所填写的信息提交到服务器上。

图4-1 谷粒学苑登录界面

本章首先会带领读者在4.1节学习如何使用HTML在网页中实现表格,其次在4.2节学习如何使用HTML实现表单,最后会结合表格和表单的知识点,带领读者实现一个我们常见的“个人资料修改”页面。

4.1 表格

本节主要介绍表格的相关知识点。

4.1.1 普通表格

在生活中,我们需要经常使用表格来展示数据,使用户可以快速从表格中获取想要的信息。常见的表格如图4-2所示。

图4-2 常见的表格

图4-2展示的表格可以按照结构划分为4个部分,如图4-3所示。

图4-3 划分后的表格

图4-3中的4个部分的内容对应关系如表4-2所示,即一个表格可以分为表格标题、表格表头、表格主体、表格脚注。

表4-2 表格内容对应关系

那么,要怎么在网页中实现一个表格呢?

HTML提供了<table>标签,用来声明一个表格。<table>标签中可以包含表格标题、表格表头、表格主体、表格脚注,它们对应的标签如下所示。

①表格标题:<caption>标签用来展示一个表格的标题,其通常作为<table>标签的第一个子元素(可选)存在。

②表格表头:<thead>标签用来定义一组带有表格表头的行(可选)。

③表格主体:<tbody>标签用来定义一组带有表格主体内容的行(可选,但建议书写)。

④表格脚注:<tfoot>标签用来定义一组带有表格脚注内容的行(可选)。

通过上述信息可以得出,一个完整的HTML表格结构代码应如下所示。

在通常情况下,在表格表头、表格主体、表格脚注部分的内部都有多行数据,在HTML中我们使用<tr>标签来定义表格中的行。

不仅如此,HTML还提供了<th>标签,用来定义表头中每一行的单元格,<td>标签来定义表格主体、表格脚注中每一行的单元格,这在4.1.2节的讲解中会具体实现。

最后,将表格中各标签的父子关系通过导图进行展示,如图4-4所示。

图4-4 表格中各标签的父子关系

4.1.2 案例:海鲜购买清单

4.1.1节对表格结构进行了简单介绍,即表格结构由表格标题、表格表头、表格主体、表格脚注4个部分组成。本节将通过实现4.1.1节中的“海鲜购买清单”案例,来帮助读者理解和掌握表格的使用。

为了便于演示,在案例中会使用<table>标签的border属性。读者看到这里不必迷惑,在配套案例的讲解中,会对border属性进行详细说明,这里只需要明确对border属性进行设置就可以显示表格的边框。

因为图4-3已经对图4-2中展示的表格进行了划分,所以这里不再侧重划分部分的讲解,主要对每个部分进行细化分析,具体内容如下。

(1)图4-3中①所示的部分为表格标题,使用<caption>标签进行设置。

(2)图4-3中②所示的部分为表格表头,使用<thead>标签进行设置。表头整体只占一行,使用一组<tr>标签进行包裹。在一行中有4个单元格,分别为品名、价格(元/斤)、重量(斤)、单项总价(元),因此这里使用4组<th>标签进行设置比较合适。

(3)图4-3中③所示的部分为表格主体,使用<tbody>标签进行设置。因为<tbody>标签包含4行,所以需要使用4组<tr>标签。因为每一行都有4个单元格,所以每一行都需要有4组<td>标签。

(4)图4-3中④所示的部分为表格脚注,使用<tfoot>标签进行设置。因为<tfoot>标签包含1行,所以需要使用1组<tr>标签。在这一行中有4个单元格,需要使用4组<td>标签进行设置。

此时可以书写出的HTML代码如下所示。

在上述代码中,<table>标签的border属性用来设置整个表格边框的粗细。如果将其值设置为0,就意味着没有边框;如果将其值设置为1,就表示设置了1px的边框。其实在HTML5中,不建议使用border属性,因为这属于对样式的修饰。在后面的章节中会讲解如何使用CSS修饰边框,这里简单提及border属性,只是为了让读者看到对应的效果。

大多数程序员在使用HTML编写表格时,不太习惯使用<thead>标签、<tbody>标签和<tfoot>标签,会将它们省略,上面的例子写成如下所示的代码也是可以的。

对比2段代码可以看出,不管是否使用<thead>标签、<tbody>标签、<tfoot>标签,都可以实现相同的效果。但是需要注意的是,即使在使用表格时省略了<tbody>标签,浏览器在解析时也会自动将<tbody>标签加上。

4.1.3 <th>、<td>标签中的colspan和rowspan属性

<th>标签和<td>标签都支持colspan属性和rowspan属性。colspan的英文原意为跨列、合并列,顾名思义,它在HTML标签中用来规定单元格可以横跨的列数。rowspan的英文原意为跨行、合并行,在HTML标签中它用来规定单元格可以竖跨的行数。

下面将通过一个案例来演示colspan属性和rowspan属性的使用方式。

现在有一个2行3列的表格,如图4-5所示。

图4-5 一个2行3列的表格

根据前文所述,我们可以编写出如下所示的代码。

如果将colspan属性值设置为2,那么会出现什么效果呢?下面为图4-5中的1-1单元格添加colspan属性,并将其属性值设置为2,代码如下所示。

运行代码后,页面效果如图4-6所示。

图4-6 页面效果(1)

从页面效果来看,仿佛和我们预想的效果不一样。初始表格本来是2行3列,每个单元格横向占据1份。但是,1-1单元格在设置了colspan属性并将其属性值设置为2后,其占2份,1-2单元格仍占1份,1-3单元格仍占1份,这样来看,第一行共变为4份,而第二行依旧是3份。最终1-3单元格超出原表格范围,形成了图4-6所示的页面效果。

那么,如果给图4-5中的单元格加上rowspan属性并将其属性值设置为2,会不会出现类似的效果呢?下面通过代码进行验证。

运行代码后,页面效果如图4-7所示。

图4-7 页面效果(2)

从图4-7来看,表格本来是2行3列(每个单元格纵向占据1份),但是在为1-1单元格设置了属性值为2的rowspan属性后,1-1单元格会向下一行多占据1份,相当于纵向占2份,同时2-1单元格占1份、2-2单元格占1份、2-3单元格占1份,第二行共变为4份,而第一行还是共3份。最终2-3单元格超出了原表格范围,如图4-7所示。

4.1.4 案例:食堂菜谱

本节将结合前面讲解的相关知识,带领读者实现经典案例“食堂菜谱”。先来看想要实现的菜谱效果,如图4-8所示。

图4-8 菜谱

在正式编写代码之前,先对该菜谱表格进行划分。

从图4-8中可以看出,整个菜谱表格可以分为标题、早餐、午餐3个部分,下面将分区域进行分析。①所对应的区域为标题部分。这个部分是要在表格内部实现的标题,应该使用<th>标签来实现,而不是使用<caption>标签。需要注意的是,这个<th>标签需要横向跨3列。②所对应的区域为早餐部分。这个部分分为3列,其中,“早餐”作为标题,其单元格需要竖跨2行;其余单元格正常书写即可。③所对应的区域为午餐部分。这个部分同样分为3列,其中,“午餐”作为标题,其单元格需要竖跨2行;其余单元格正常书写即可。

该案例的HTML代码实现如下所示。

4.2 表单

到目前为止,所有的Web通信都是单向的,通信过程是客户端发送请求至服务器端,然后服务器端给出响应。使用表单的相关知识可以向服务器端提交内容,例如,在本章开头出现的谷粒学苑登录界面(见图4-1)。其实,常见的表单界面还有重设密码等,如图4-9所示。

而表单提交数据的整体流程,也是先从客户端发送请求至Web服务器端,具体过程如图4-10所示。

从图4-10中可以看出,将表单数据从客户端发送至Web服务器端分为5步。

(1)当用户访问带有表单的HTML页面时,他们会填写表单并提交。

(2)客户端会将表单中的数据打包并发送到Web服务器端。

(3)Web服务器端在接收到表单数据后,会将表单数据传给Web服务器端的脚本进行处理。

(4)Web服务器端的脚本语言处理完成后,会告诉Web服务器端要返回什么数据给浏览器。

(5)浏览器接收Web服务器端返回的信息,并且进行解析。

本节会带领读者简单地书写一个表单,让读者能够对表单结构进行清晰划分。本节的后续内容还会对表单的各结构依次展开讲解。

图4-9 重设密码界面

图4-10 表单提交数据的整体流程

4.2.1 初始表单

在正式书写表单前,先对涉及的标签进行简单介绍。

● <form>标签用于创建一个表单。在<form>标签内,通常会放置一个或多个专用于表单的标签。这些表单标签可以提供输入信息的不同方法,如文本框、单选、多选、下拉菜单等。

● <input/>标签用于创建一个文本框。<input/>标签可以设置name属性,该属性用来给<input/>标签起名。开发者可以自定义设置该属性的属性值,如在下面案例的代码中,name属性的属性值为userName。

● <button>标签用于创建一个提交按钮。

如图4-11所示为一个经典表单。

图4-11 一个经典表单

该表单的代码实现如下所示。

在代码中,我们通过<form>标签创建了一个表单,其标签内部包含<input/>标签和<button>标签。其中,<input/>标签使用了name属性并为其赋值“userName”,也就是说,该表单标签<input/>的名字为userName。

在输入框中输入“123”后,点击“提交数据给服务器”按钮,此时观察浏览器的地址栏,如图4-12所示。

图4-12 浏览器地址栏

在图4-12中,方框内为查询字符串(URL参数)。所谓查询字符串,是指在URL的末尾加上用于向服务器发送信息的字符串(变量),将“?”放在URL的末尾,然后再加上“名字=值”。如果想要加上多个参数,就要使用“&”连接。通过这个形式,可以将想要发送给服务器的数据添加到URL中。

从图4-12中可以看出,查询字符串中的“userName”就是我们给上面的<input/>标签起的名字,在输入框中输入的值就是等号后面的值。这进一步证明了浏览器在传递值的时候,其格式为“名字=值”。

4.2.2 <form>标签的action和method属性

<form>标签拥有action属性和method属性,下面将会对这2个属性进行详细介绍。

在4.2.1节,我们简单地创建了一个表单,但是在点击提交时,提交的路径是当前的文件名。其实,我们可以通过<form>标签的action属性来指定提交路径。在通常情况下,action属性的属性值是一个服务器端脚本文件。例如,将<form>标签修改为:

此时再次点击提交,就会把对应的表单数据提交到当前目录下的test.php文件中。

<form>标签中的method属性可以指定表单的请求方式。读者可能对get或post这2个单词有些陌生,不过不用着急,这是刚开始接触Web的缘故。思考4.2.1节的案例可以发现,表单中提交的值都在URL中以查询字符串的形式进行了传递,这是因为此时<form>标签的method属性的默认值为get。method属性的属性值除了可以为get,还可以为post。因为现在刚开始接触Web,所以对于get和post只需要简单了解:当method属性的属性值为get时,数据将会以查询字符串的方式提交;当method属性的属性值为post时,数据将会被打包在请求中。在实际使用时,我们更建议在提交表单的时候尽量使用post方式。

下面通过一个实际案例来演示action属性和method属性的使用方式。

案例需求为定义一个表单,输入用户名并提交数据到test.php文件中,提交方式为post。

HTML代码实现如下所示。

在前面的内容中,我们已经对“action="./test.php"”“method="post"”这2个属性进行了详细讲解,这里不再赘述。运行这段代码后,页面效果如图4-13所示。

图4-13 页面效果

当在文本框中输入“小邓”后,点击提交按钮,浏览器地址栏如图4-14所示。

图4-14 浏览器地址栏

浏览器地址栏的提交路径为action属性的属性值test.php,因为method属性的属性值为post,所以在浏览器中没有出现查询字符串,数据是被打包放在请求中进行传输的。

4.2.3 布尔属性

在HTML标签中有一部分属性统称为布尔属性。这类属性的特点是,不管属性名后面的属性值是什么,只要属性名存在,就会在内部表现为true(真的)。例如,disabled属性是所有表单都支持的布尔属性,只要该属性出现在标签中,就表示其表单标签被禁用了。

请观察如图4-15所示的文本框。

图4-15 文本框

观察图4-15可以发现,文本框明显被禁用了,因此可以将<input/>标签书写为下方代码。

或者省略属性值,直接写为下方代码。

这里只简单地演示布尔属性的使用,在4.2.4节会详细介绍<input/>标签。

4.2.4 详解<input/>标签

<input/>标签的type属性用来定义form表单中输入数据的类型,它们可以使用户输入内容的方式变得不同。type属性共有4种属性值,分别是text、password、radio、checkbox。下面将对这4种属性值进行讲解和演示。

(1)当type属性的属性值为text时,代表定义一个文本输入框,代码如下所示。

运行代码后,页面显示为一个文本框,其效果如图4-16所示。

图4-16 文本框效果

值得一提的是,type属性的默认值是text,即当<input/>标签中没有书写type属性时,它依旧显示为文本框。例如:

这行代码的运行效果与图4-16相同,都显示为一个文本框。

在很多网站的表单中,经常会看到这样一个场景:当你进入页面后,输入框中会有文字提醒你需要输入的信息。例如,在输入用户名的文本框中会提示“请输入用户名”,如图4-17所示。

图4-17 输入个人信息界面

在<input/>标签内可以通过设置value属性来实现这个效果,value属性的属性值代表在文本输入框中默认显示的内容。通过下方代码就可以实现图4-17的效果。

在name为“userName”的<input/>标签中,文本框默认显示的内容为“请输入用户名”。在name为“tel”的<input/>标签中,文本框默认显示的内容为“请输入电话”。

在4.2.3节中,我们对布尔属性进行了介绍。其实,在表单标签中,除了disabled属性,readonly属性也是一个布尔属性。

如果发现在一个表单标签中书写了readonly属性,就表示该表单标签是只读的,例如:

运行代码后会发现,页面上的文本框中无法输入文字。

将readonly属性和disbaled属性放在一起观察,发现二者的共同特征是,都不能获得光标并无法在输入框中输入值。二者的不同点在于,disabled属性表示禁用,不会向服务器发送值;而readonly属性表示只读,虽然不能修改文本框中的值,但是能够向服务器发送值。

请观察下面这段代码。

这段代码分别在2个<input/>标签中使用了disabled属性和readonly属性,2个文本框都带有默认内容“test1”“test2”,页面效果如图4-18所示。

图4-18 页面效果(1)

在点击“提交”按钮后,观察地址栏可以发现,带有readonly属性的文本框依然可以传递值,但是带有disabled属性的文本框不能传递值,浏览器地址栏如图4-19所示。

图4-19 浏览器地址栏(1)

(2)当type属性的属性值为password时,代表定义一个密码框,代码如下所示。

这段代码定义了2个文本框,文本框类型分别是文本和密码。运行代码后,页面效果如图4-20所示。

图4-20 页面效果(2)

此时输入信息,在用户名对应的文本框中显示的是用户名文本;而在密码对应的文本框中,不管输入什么,都以占位符“·”来显示,页面效果如图4-21所示。

图4-21 页面效果(3)

需要注意的是,虽然密码框在表单中显示为占位符“·”,看起来像是被加密了,但是在提交表单后就会发现,密码实际上没有被加密,浏览器地址栏如图4-22所示。

图4-22 浏览器地址栏(2)

(3)当type属性的属性值为radio时,代表定义一个单选框。

单选框用于要求用户单独选择某一项的情况,如性别。因为用户不能在其中输入值,所以需要使用value属性来指定值,在这种情况下,页面效果如图4-23所示。

图4-23 页面效果(4)

需要注意的是,被归类为一组的单选框需要具有相同的name属性值。图4-23的实现代码如下所示。

在代码中,两个单选框为一组,它们的name属性值都为sex。

在单选框中可以书写checked属性。checked属性是一个布尔属性,用于默认选中某个单选框,代码如下所示。

可以发现,在单选框“女”的<input/>标签中书写了checked属性,代表该单选框被默认选中。运行代码后,页面效果如图4-24所示。

图4-24 页面效果(5)

(4)当type属性的属性值为checkbox时,代表定义一个复选框。

复选框用于让用户选择多个选项,如选择自己的爱好。因为用户不能在其中输入值,所以需要使用value属性来指定值。与单选框相同,复选框也可以使用checked属性,用于默认选中某个单选框,页面效果如图4-25所示。

图4-25 页面效果(6)

从图4-25中可以看出,“运动”的复选框被默认选中了,因为“运动”所对应的复选框标签被书写了checked属性,具体代码实现如下所示。

4.2.5 下拉列表

HTML提供了<select>标签,用来实现下拉列表。<select>标签中可以包含一个或多个<option>标签,用来表示下拉列表中的选项。以一个生活中常见的下拉列表为例来讲解,其形式如图4-26所示。

图4-26 下拉列表

具体代码实现如下所示。

上述代码使用<select>标签定义了一个下拉列表,并且在其内部定义了“中国”“日本”“韩国”3个选项。

这段代码虽然实现了下拉列表,但对于开发来说还不够全面,因为在选择选项并点击“提交”按钮后,在浏览器地址栏中可以发现,提交的值是<option>标签中的文本,如图4-27所示。

图4-27 浏览器地址栏(1)

在实际的网站中,可能读者选择的是“日本”,但在提交时传递给服务器的是“Japan”。那么,如果想要提交的值就是自定义的值,要怎么操作呢?

与单选框相同,<option>标签同样可以通过书写value属性来指定值,具体代码实现如下所示。

对比上段代码,很明显这段代码在每个<option>标签上都添加了对应的value属性值,这样提交到服务器的数据就不再是选项的值了。此时在页面上选择“中国”再点击“提交”按钮,浏览器地址栏如图4-28所示。

图4-28 浏览器地址栏(2)

下拉列表可以通过在<option>标签中书写selected属性来设置默认选项,值得一提的是,该属性也是一个布尔属性,代码如下所示。

上述代码在“韩国”的<option>标签中书写了selected属性,表示该下拉列表的默认选项是“韩国”。运行代码后,页面效果如图4-29所示。

图4-29 页面效果

4.2.6 文本域

HTML提供了<textarea>标签,用来表示文本域。文本域可以用来输入多行文本,输入的内容允许换行,如图4-30所示。

图4-30 文本域

<textarea>标签的使用如下所示,代码使用一对<textarea>标签定义了一个文本域。

<textarea>标签也可以用来定义默认文本,但是与其他标签不同,<textarea>标签不支持设置value属性。编写在<textarea>标签的开始标签和结束标签之间的内容,会被视为默认内容。如图4-31所示为文本域内存在的默认文本(“这里是默认内容”),其就被书写在<textarea>标签对内。

图4-31 文本域内存在的默认文本

代码实现如下所示。

在<textarea>标签中可以书写cols属性和rows属性,它们分别对应文本域的宽度和高度,具体说明如下。

● cols属性:用来设置文本域中默认显示的列数,可以影响文本域的宽度。

● rows属性:用来设置文本域中默认显示的行数,可以影响文本域的高度。

例如,设置一个默认显示30行50列的文本框,如图4-32所示。

图4-32 默认显示30行50列的文本框

具体代码实现如下所示。

上述代码在<textarea>标签中将cols属性的属性值设置为50,将rows属性的属性值设置为30,从而实现了如图4-32所示的效果。

4.2.7 按钮

前面的内容多次使用<button>标签来定义一个按钮,但是关于<button>标签的使用,仅书写标签是远远不够的。本节将对<button>标签的其他知识展开讲解。

可以通过在<button>标签中书写type属性来指定按钮的类型。type属性具有3个属性值,分别是submit、button和reset,具体讲解如下。

(1)submit:当属性值为submit时,点击按钮可以将表单数据提交给服务器。如果没有指定type属性值,就将该值作为默认值,代码如下所示。

(2)button:当属性值为button时,在点击按钮时没有默认行为。该属性值通常配合JavaScript使用,代码如下所示。

(3)reset:当属性值为reset时,点击按钮会将表单数据重置,代码如下所示。

4.2.8 为表单标签定义标注

HTML提供了<label>标签,用来定义表单标签的说明。它虽然在样式上看不到任何效果,但是使用该标签可以提高用户的体验度,使用户通过点击<label>标签中的文本,就可以定位表单标签。

<label>标签需要书写for属性,for属性可以把<label>标签绑定到另一个元素上,其属性值应当与相关表单标签的id属性值相同,代码如下所示。

这段代码使用<label>标签的for属性将<label>标签和<input/>标签绑定在一起。运行代码后,页面效果如图4-33所示。

图4-33 页面效果

从页面上看,<label>标签的效果没有体现出来,但当点击“用户名”这3个字时,可以发现光标自动定位在文本框内。这里对效果不再做演示,读者可自行练习。

同时,可以将<input/>标签书写在<label>标签对内,此时可省略for属性。上面的代码也可以写为下面这种形式。

上面的代码没有使用<label>标签的for属性,以及<input/>标签的id属性。这是因为在<label>标签的for属性与<input/>标签的id属性绑定后,我们才能知道<label>标签对应的是哪个<input/>标签的标注。而这里的<label>标签已经包含了<input/>标签,即可以认为<label>标签已经和其中的子元素<input/>标签进行了绑定。

4.3 案例:个人资料修改表单

本节将结合使用前面讲解的知识点来实现一个经典案例。先来看想要实现的页面效果,即小尚的个人资料修改页面,如图4-34所示。

观察图4-34可知,该案例使用了表格和表单的相关知识。表格的<table>标签用来固定布局,表单的相关内容用来标记需要修改的选项内容。

下面我们将从结构和表单2个部分进行分析。

1.结构分析

首先对图4-34进行结构划分,如图4-35所示。

可以将该案例的整体结构看作一个10行2列的表格。在图4-35中,①和③所示的2个部分只有一个单元格,但是占据了2列的空间;②所示区域就是普通的8行2列的表格,在结构上没有什么特殊的地方,这里不做具体讲解。

图4-34 小尚的个人资料修改页面

图4-35 结构划分

由此,该案例的结构代码可以书写如下。

2.表单分析

将表单部分进行划分,如图4-36所示。

图4-36 表单划分

图4-36共被分为10个区域,下面将分区域进行讲解。

(1)①是标题部分,可以使用<h1>标签来实现。

(2)②是一个文本输入框,文本输入框内有默认值“lgzhyan”。因为登录账号默认是不允许修改的,所以还需要在<input>标签上加上readonly属性。

(3)③、④是密码框,这里不多做讲解。

(4)⑤是一个文本输入框,对应需要输入的是邮箱地址。

(5)⑥是单选框,有2个选项:“男”“女”。根据图4-36可知,要默认选中“男”,因此在“男”对应的标签上需要书写checked属性。

(6)⑦是复选框,有5个选项:“登山”“郊游”“养鱼”“钓鱼”“交友”。其中“登山”不允许被选中,因此要使用disabled属性将其禁用。“交友”为默认选中项,需要在对应的标签上书写checked属性。

(7)⑧是下拉列表,其默认选项为“中国”,需要在其对应的<option>标签上书写checked属性。

(8)⑨是个人简介,因为需要输入内容较多,所以使用文本域<textarea>标签来实现比较合适,其中有默认值“这个人很懒,什么都没有留下!”。

(9)⑩是“确认修改”按钮,这里不多做讲解。

在分析后,再通过代码来实现。整体代码实现如下所示。

4.4 本章小结

本章主要分3个部分对表格和表单进行了介绍。4.1节对表单的相关知识进行了讲解。其中,通过对一个案例的划分,让读者了解了表格结构的相关标签;同时介绍了表格中<td>标签、<th>标签的2个属性,并且通过生活中常见的案例“食堂菜谱”对表格的相关知识进行了应用。阅读完4.1节后,相信读者已经可以通过HTML在网页上实现绝大部分表格。

4.2节介绍了表单的相关内容。与表格的介绍方式不同,4.2节由浅入深地对表单的相关知识进行了介绍。首先对表单传递数据的原理进行了讲解,其次对初始表单进行了简单应用,最后对每个标签的使用方式和可以在该标签上使用的属性进行了介绍,并且不断配以简单案例进行练习。

4.3节结合本章所学,带领读者实操了一个经典案例:个人资料修改表单。同样是从表格划分和表单划分2个方面进行讲解,帮助读者在日后的开发中养成结构划分的习惯,从而快速地开发所有表单和表格页面。 7ww83YUvYbwVx+/422tMOAXjR1Gi9pKYWZl5G6loVUCvv0cWdy2+T6GiGilX+gKz

点击中间区域
呼出菜单
上一章
目录
下一章
×