整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

小白学编程遇到的列表、表格以及form表单里的各种坑

小白学编程遇到的列表、表格以及form表单里的各种坑

们在浏览网页的时候,可以看到页面上有导航栏,逛商城的时候会看到商品的详情页里有商品的简介,以及在注册或者申请一个网站会员的时候会让我们填写各种各样的信息,这些分别由列表、表格、表单来完成的,今天我学习了这些知识,下面我把我学到的知识梳理一下,以及在学习中遇到的坑总结一下,希望能给其他初学者一些帮助,同时,如有不足之处,也请各位大神指出来,我也好学习学习,提升自我。

网站导航栏

HTML列表在网站页面中使用的是相当广泛。如上图的网站导航栏,就是使用了列表实现的,再比如说,一个栏目的文章列表等等,都是使用了列表功能,根据我今天学到的内容,我总结了一下,总共三大知识点:

一、HTML列表分为三种:

1.无序列表:

  1. 无序列表是由标签<ul>和<li>组成的;
  2. <ul>标签是声明无序列表的,<li>标签作为列表中每一项的起始项。

可以在<ul>标签中使用type属性来控制每一项前面的圆点的样式:

  • 1.disc 默认值,每一项前面的圆点为黑色实心圆。
  • 2.square 每一项前面的圆点为实体方心。
  • 3.circle 每一项前面的圆点为空心圆。
<h3>商品列表</h3>
<ul start="2">
    <li>iPhone 12</li>
    <li>MacBook Air</li>
    <li>AirPods Pro</li>
</ul>
  • 效果如图:

2.有序列表:

  1. 与无序列表有区别的是有序列表,他的每一项都是由它是有先后顺序进行排列的,并且会用数字依次进行标记;
  2. 有序列表由标签<ol>和<li>组成。
<h3>商品列表</h3>
<ol>
    <li>iPhone 12</li>
    <li>MacBook Air</li>
    <li>AirPods Pro</li>
</ol>
  • 效果如图:

有序列表

可以在<ol>标签中使用start属性来控制第一项数字起始值:

<h3>商品列表</h3>
<ol start="2">
    <li>iPhone 12</li>
    <li>MacBook Air</li>
    <li>AirPods Pro</li>
</ol>

效果如图:

start=2

可以使用type规定在列表中使用的标记类型,type值有五种:

  • 1 默认值,以数字样式标记;
  • A 以大写字母作为每一项前面的标记;
  • a 以小写字母作为每一项前面的标记;
  • I 以大写的罗马数字作为标记;
  • i 以小写的罗马数字作为标记。

不过我个人感觉,这个type属性的作用貌似不多大,基本上都是以默认值,就是数字来作为每一项的标记了吧。

3.自定义列表:

<dl>
    <dt>名称:</dt>
    <dd>小白学编程</dd>
    <dt>地址:</dt>
    <dd>河南省郑州市二七区</dd>
    <dt>联系</dt>
    <dd>电话:<a href="tel:189****1122">189****1122</a></dd>
    <dd>邮箱:<a href="mailto:admin@admin.com">admin@admin.com</a></dd>
</dl>
  • 效果如图:

自定义列表

备注:根据本小白查的文档,a标签的href属性,不仅可以填写链接,还可以用:

【tel:电话号码】的格式点击进行拨号,只不过是在电脑上需要有能拨号的软件;

拨号

【mailto:邮箱地址】的格式可以快速拉起发送邮件的软件。

发送邮件

不过我不知道这个的兼容性怎么样,如果有知道的大佬,可以在评论区指导一下,跪谢!

二、HTML表格:

  • <table>标签定义一个HTML表格;
  • 一个HTML表格由table以及一个或多个tr、th或者td组成
  • tr元素定义表格行,th元素定义表头,td元素定义表格单元格。

一个表格的基本结构:

<table class="table">
    <!-- caption:表格标题 -->
    <caption>
        商品信息表
    </caption>
    <!-- 表头 -->
    <thead>
        <!-- 添加表格数据的时候必须先添加一行 -->
        <tr>
            <td>ID</td>
            <td>商品名称</td>
            <td>单价</td>
            <td>单位</td>
            <td>数量</td>
            <td>金额</td>
        </tr>
    </thead>
    <!-- 一个表格可以有多个tbody,但是只能有一个thead -->
    <tbody>
        <tr>
            <td>1</td>
            <td>iPhone 12 mini</td>
            <td>5499</td>
            <td>部</td>
            <td>100</td>
            <td>549900</td>
        </tr>
    </tbody>
</table>
  • 总结:
    1.一个表格允许有多个<tbody>,但是有且只能有一个<thead>;
    2.添加表格数据的时候必须先添加一行;
    3.所有的数据必须填充到<td>或者<th>标签中;
    4.th是td元素的一个加强版,<th>比<td>多了个加粗和居中的效果。

Excel里的表格可以进行行与列的合并,单元格直接也能合并,那么HTML表格也是可以的,可以使用colspan进行列合并,rowspan进行行的合并。利用这两个属性,我们可以使用<table>标签写一个课程表。

三、HTML表单与常用控件

HTML表单是用于搜集用户输入的不同类型数据的,它包含了不同类型的<input>元素,如:文本框、单选框、复选框、提交按钮等等。因此可以看出,<input>元素是表单中最重要的元素。

表单的基本格式

<form action="" method="POST" class="register">
    <!-- 这里面可以放input元素 -->
</form>
  • action:处理表单的程序,通知表单往何处发送数据;
  • method:表单数据提交类型,有两个值:
    - GET:数据直接显示在url地址中;
    - POST:表单数据在请求头体中。

根据我学习的成果,我总结出了input元素的七种type类型并一一做了记录:

1.type="text" 单行文本框

<label for="username">账号:</label>
<input type="text" name="username" id="username" value="admin" required>

单行文本框

2.type="email" 邮箱型文本框

<label for="email">邮箱:</label>
<input type="email" name="email" id="email" value="html@html.cn" required>

邮箱型文本框还会对输入的内容进行校验,如果不符合邮件地址的格式会弹出如上图提示。

3.type="password" 密码型文本框/非明文

<label for="password">密码:</label>
<input type="password" name="password" id="password" value="" placeholder="密码不少于6位" required>

密码型文本框

输入内容

值得注意的是,密码型文本框在输入密码的时候都是以小黑点进行替换的,并不会显示我们输入的内容。

4.type="radio" 单选框

<label for="">性别:</label>
<div>
    <input type="radio" name="gender" value="male" id="male">
    <label for="male">男</label>
    <input type="radio" name="gender" value="male" id="male">
    <label for="female">女</label>
    <input type="radio" name="gender" value="male" id="male" checked>
    <label for="secret">保密</label>
</div>

单选框

单选框(radio)的name值必须都相同才能保证值的唯一性,默认选中使用checked属性。

5.type="checkbox" 复选框

<label for="#">兴趣:</label>
<div>
    <input type="checkbox" name="hobby[]" value="basketball" id="basketball">
    <label for="basketball">篮球</label>
    <input type="checkbox" name="hobby[]" value="game" id="game">
    <label for="game">游戏</label>
    <input type="checkbox" name="hobby[]" value="travel" id="travel">
    <label for="travel">旅游</label>
    <input type="checkbox" name="hobby[]" value="program" id="program">
    <label for="program">编程</label>
</div>

复选框

复选框的name值一定要用数组表示,否则,服务器在接收数据的时候不能获取所有选中的值。

6.type="file" 文件域

<label for="user-pic">头像:</label>
<input type="file" name="user_pic" id="user-pic" />

上传文件

7.type="hidden" 隐藏域

<input type="hidden" name="MAX_FILE_ZIE" value="80000" />

隐藏域在页面是看不到的,是服务器端进行处理的一项数据。

通过上述的七种<input>元素类型,我得出一个结论就是一个<input>元素至少包含有三个属性:

  1. type 控件的类型;
  2. name 相当于变量名称,用于后端服务器接收时使用;
  3. value 控件的值。

除了上述的<input>元素的7种标签类型,还有下拉列表、文本域这些常用的控件。

下拉列表/下拉框

<label for="">学历:</label>
<select name="edu" id="eud">
    <option value="1">初中</option>
    <option value="2">高中</option>
    <option value="3" selected>本科</option>
    <option value="4">研究生</option>
    <option value="5" label="老司机">博士</option>
</select

下拉列表/下拉框

  • 注意:
    如果option里有label值,label属性的优先级于option里的内容。因此,上述列表第5项应该显示“老司机”。
  • HTML5中新属性:
    multiple multiple可以选择多个选项
    size 数值,如:3,下拉框里可见的选项数量
<label for="">学历:</label>
<select name="edu" id="eud">
    <option value="1">初中</option>
    <option value="2">高中</option>
    <option value="3" selected>本科</option>
    <option value="4">研究生</option>
    <option value="5" label="老司机">博士</option>
</select>

multiple、size用法

文本域(多行文本框)

<label for="comment">备注:</label>
<textarea name="comment" id="comment" cols="30" rows="10"></textarea>

文件域与隐藏域

上传文件需要注意两点

  1. 请求类型必须为POST类型;
  2. form表单必须有enctype属性,并且数据编码设置为:enctype=”multipart/form-data”;
<form action="" method="POST" class="register" enctype="multipart/form-data">
    <label for="user-pic">头像:</label>
    <!-- 隐藏域在页面是看不到的,是服务器端进行处理的一项数据。 -->
    <input type="hidden" name="MAX_FILE_ZIE" value="80000" />
    <input type="file" name="user_pic" id="user-pic" />
    <div class="user-pic" style="grid-column: 2;"></div>
    <button>提交</button>
</form>

enctype有3个值:

  1. application/x-www-form-urlencoded 默认值,在发送前对所有字符进行编码;
  2. multipart/form-data 使用上传文件空间时必须用该值;
  3. text/plain 将空格转换为“+”,但不对特殊字符编码。

四、表单的form属性

<form action="check.php" method="get" id="register">
  <div class="box">
  	<label for="email">邮箱:</label>
		<input type="email" form="register" name="email" id="email" placeholder="demo@email.com" />
  	<label for="password">密码:</label>
		<input type="password" form="register" name="password" id="password" placeholder="至少8位" />
  	<button form="register">提交</button>
	</div>
</form>
<label for="username">帐号:</label>
<input type="text" name="username" id="username" placeholder="不能为空" />

注册表单

  • 如果某个控件写在form表单的外部,则该控件需要使用form属性:form=”表单的id值”,才可以在表单提交时传该控件的值,否则无法进行传值。

例如:以下情况就是没有在空间中写form属性的情况,我们可以看到,在浏览器里没有获取到密码password的值,只获取到了username和email的值:

没有获取到password的值

我个人的理解是:如果不把表单控件写到form内部,这样会方便js获取表单元素的值,但是这样写会容易影响布局,造成布局混乱,建议还是按照标准的写法,把所有的控件都写到form表单内部。

至于什么时候使用GET方法,什么时候使用POST方法呢?通过今天的学习,我做了如下总结:

  1. GET方法传输的数据相对于POST要小的很多,并且是明文传输的,是直接将参数放在应用程序的URL中传输的,一眼就能看见,因此对于小一些的表单,对安全性要求不高的,可以使用GET方法。
  2. POST方法可以发送大文件,并且在请求的URL中看不到发送的数据,安全性高,因此建议使用POST方法。当然这个安全性也是相对来说的,对于一些网络黑客高手,还是有办法获取这些传输内容,至于怎么获取的,我也不清楚,毕竟咱还是小白。
  3. 还有一点就是在上传文件的时候必须使用POST方法,因为文件一般都比较大,GET方法最大大概只能发送32K的数据,POST方法可以达到1G。

作业:用表格写一个课程表

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/table.css">
    <title>表格:行与列的合并</title>
</head>
<body>
    <table class="lesson">
        <caption>
            xxxx小学课程表
        </caption>
        <thead>
            <tr>
                <th colspan="2"></th>
                <th>星期一</th>
                <th>星期二</th>
                <th>星期三</th>
                <th>星期四</th>
                <th>星期五</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td rowspan="4">上午</td>
                <td>1</td>
                <td>语文</td>
                <td>数学</td>
                <td>音乐</td>
                <td>社会</td>
                <td>科学</td>
            </tr>
            <tr>
                <td>2</td>
                <td>数学</td>
                <td>语文</td>
                <td>音乐</td>
                <td>语文</td>
                <td>数学</td>
            </tr>
            <tr>
                <td>3</td>
                <td>美术</td>
                <td>音乐</td>
                <td>音乐</td>
                <td>数学</td>
                <td>音乐</td>
            </tr>
            <tr>
                <td>4</td>
                <td>社会</td>
                <td>体育</td>
                <td>音乐</td>
                <td>体育</td>
                <td>语文</td>
            </tr>

            <tr class="rest">
                <td colspan="7">中午休息</td>
            </tr>

            <tr>
                <td rowspan="4">下午</td>
                <td>5</td>
                <td>语文</td>
                <td>数学</td>
                <td>音乐</td>
                <td>社会</td>
                <td>科学</td>
            </tr>
            <tr>
                <td>6</td>
                <td>数学</td>
                <td>语文</td>
                <td>音乐</td>
                <td>语文</td>
                <td>数学</td>
            </tr>
            <tr>
                <td>7</td>
                <td>课外活动:</td>
                <td colspan="4">各班自行组织,自愿参加</td>
                <td>数学</td>
                <td>音乐</td> -->
            </tr>
        </tbody>
    </table>
</body>
</html>

效果:

用HTML表格写一个课程表

个人总结:为了学习这些表单知识,真真的是看了一天,头都懵了,还有不少内容没有记住,还是需要多写多练,其中我认为比较坑的几个地方是:

  1. 表格的行与列的合并,colspan、rowspan,如果能熟练的用好这两个属性,相信写出上面课程表实例也不难;
  2. 表单的属性太多了,一时半会真的是记不住;
  3. 上传文件需要注意的两点:请求类型必须为POST;form表单加上enctype=”multipart/form-data”;
  4. 表单控件的form属性,这个可能是因为我还是个小白,才接触这些东西,不知道这些知识点,不知道今后的工作中用到这个属性的情况多不多。

在看视频教程的过程中,我看到好多大佬在用VS Code的时候都是使用了快捷键,后来网上搜了一下,原来官方给的就有一个PDF文档,从VS里就可以进去,在工具的顶部导航栏帮助里,如下图:

快捷键

为了方便大家快速找到,我把官方地址贴出来吧,VS Code快捷键PDF文档:https://code.visualstudio.com/shortcuts/keyboard-shortcuts-windows.pdf

VS Code快捷键

续一周没怎么更新了,今天我们继续HTML的学习,表格标签。表格是实际开发中常用的一种标签类型,会说到表格标签的主要作用和基本语法。

主要作用: 表格主要用于显示、展示数据,因为它可以让数据展示的非常规整,可读性非常好,特别是后台展示数据的时候,能够熟练运用表格非常重要。一个清爽简约的表格可以把复杂的数据表现的很简单。表格不是用来布局页面的,而是用来展示数据的。

表格的基本语法: <table><tr><td></td></tr></table>

<table></table>用来定义表格标签

<tr></tr>用于定义表格中的行,嵌套在<table>标签中使用

<td></td>用于定义表格中的单元格,嵌套在<tr>标签中使用,字母td指表格数据(table data),即数据单元格的内容。

我们来展示一个例子,比如 数据库中有三个字段,分别为 姓名 性别和年龄,如果想用前端将这三个字段的数据展示出来,应该怎么操作呢?


先看效果:

然后我们看下代码:

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>20210829---</title>

</head>

<body>

<table>

<tr> <td>姓名</td> <td>性别</td> <td>年龄</td> </tr>

</table>

</body>

</html>

这次开始使用vs code来编辑代码了,感觉比sublime line高级一些,但是相对的也麻烦点。可以看到,在前端页面展示了 姓名、性别和年龄。然后我们添加一行数据,看效果:

民族英雄黄飞鸿如果还活着,应该也是一位非常高寿的宗师了。多加几个数据

让我们看看代码有什么不同

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>20210829---</title>

</head>

<body>

<table>

<tr> <td>姓名</td> <td>性别</td> <td>年龄</td> </tr>

<tr> <td>黄飞鸿</td> <td></td> <td>188</td> </tr>

<!--再多创建几个数据-->>

<tr><td>鬼脚七</td> <td></td> <td>186</td> </tr>

<tr><td>梁宽</td> <td></td> <td>33</td> </tr>

</table>

</body>

</html>

可以看到,就是将之前的数据进行了复制而已。


接着我们说下表头单元格标签,一般表头单元格位于表头的第一行或第一列,表头单元格里面的文本内容,加粗居中表示。

<th>标签表示HTML表格的表头部分,table head的缩写

我们先来看下效果:

再看下对应的代码:

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>20210829---</title>

</head>

<body>

<table>

<!--HTML表格的表头标签,内容加粗居中展示-->>

<tr> <th>姓名</th> <th>性别</th> <th>年龄</th> </tr>

<tr> <td>黄飞鸿</td> <td></td> <td>188</td> </tr>

<!--再多创建几个数据-->>

<tr><td>鬼脚七</td> <td></td> <td>186</td> </tr>

<tr><td>梁宽</td> <td></td> <td>33</td> </tr>

</table>

</body>

</html>

就是将表格表头那一行的<td>都换成了<th>,可以看到表头每个字段都已经居中并且加粗了。


最后我们说下表格的属性,其实表格标签属性这部分用的不多,一般都是用css样式来设置。例如表格的边框、大小等。我们需要关注的表格属性目的,有2点:

  1. 记住英文显示名称,之后使用css样式会用到
  2. 直观感受表格的外观状态

align 属性值: left right center 对应表格相对周围元素的对齐方式

border 属性值 1或"" (空) 规定表格单元是否有边框,默认为空,表示没有边框

cellpadding 像素值 规定单元边沿与其内容之间的空白,默认1像素

cellspacing 像素值 规定单元格之间的空白,默认1像素

width 像素值或百分比 规定表格的宽度


我们来看下效果:

来看下代码:

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>20210829---</title>

</head>

<body>

<table align="center" border=1 cellpadding=1 cellspacing=1 width=500>

<!--HTML表格的表头标签,内容加粗居中展示-->>

<tr> <th>姓名</th> <th>性别</th> <th>年龄</th> </tr>

<tr> <td>黄飞鸿</td> <td></td> <td>188</td> </tr>

<!--再多创建几个数据-->>

<tr><td>鬼脚七</td> <td></td> <td>186</td> </tr>

<tr><td>梁宽</td> <td></td> <td>33</td> </tr>

</table>

</body>

</html>

记住,属性都是在table处添加和修改的,因为我们是对整个table的设置值。

好的,今天就先到这里了,大家周末愉快

一篇文章我给大家说明了如何从零开始搭建一个node的服务端框架,我们用到了Egg框架。Egg框架我不再过多介绍,如果有小伙伴想了解,可以回去看我以前写的文章,会有相关的介绍。这次我将在上次搭建的框架上进行延伸,讲一下如果用Egg框架连接数据库,并且实现对数据的增删查改。接下来我们直接进入主题。

安装数据库插件

我本次选用的数据库是MySQL。所以我们安装Egg官方的数据库插件即可,首先我们安装插件 egg-mysql我们在项目根目录打开命令提示符,输入命令行:npm i --save egg-mysql 。回车等待插件下载安装完成。

npm i --save egg-mysql

配置插件

命令行下载安装插件完成后,我们下一步的工作就是在项目中开启并配置egg-mysql插件。具体操作如下:

首先我们要在项目中开启数据库。找到项目中的/config/plugin.js文件我们需要在里面添加几行代码,如下所示。

//开启数据库插件
  mysql : {
    enable: true,
    package: 'egg-mysql',
  }

然后我们还要在 config/config.default.js 中配置各个环境的数据库连接信息。具体配置如下。

//添加数据库连接信息
  config.mysql={
    // 单数据库信息配置
    client: {
      // host
      host: 'localhost',
      // 端口号
      port: '3306',
      // 用户名
      user: 'root',
      // 密码
      password: '123456',
      // 数据库名
      database: 'testdb',
    },
    // 是否加载到 app 上,默认开启
    app: true,
    // 是否加载到 agent 上,默认关闭
    agent: false,
  };

到此步骤我们的数据库插件已经安装完成并且配置好了。那我们怎么实现数据的增删查改呢?大家请继续往下看。

数据操作-新增用户

首先我们看一下怎么新增数据。我们在mysql的testdb实例中新建一个user空表。如下图所示。

我们的egg框架也遵循MVC的架构所以我们一般会在service层里面写我们逻辑处理的代码,而controller层则是获取前端数据,回传数据的控制层。所以我们操作数据库的代码是写在service文件夹里面的。

我们在app/service文件夹里面新建一个user.js文件。在里面写个新增用户的方法,该方法就是把数据存到数据库中。具体代码如下。

const Service=require('egg').Service;

class UserService extends Service {

  //新增用户data是有controller层传递过来的数据记录。
  async addUser(data) {

    const {ctx, app}=this;
    let result={};
    try {
      data.id=0;//定义id=0,因为数据库已经设置id为主键,并且自增。所以只需要赋值0即可。
      // 在 user 表中,插入前端提交上来的数据记录
      const info=await app.mysql.insert('user', data); 
  
      //插入成功后。
      if(info.affectedRows===1){
        //给前端返回一个Json的对象
        result={
          state: 0, //自定义的状态码
          msg: "添加成功", //返回的消息
          data: info.insertId, //新增的记录的id
        }
      }

    } catch (err) {
      //插入数据失败的返回结果
      result={
        state: 1, 
        msg: err,
        data: null,
      }
    }
    
    return result
  }
};
module.exports=UserService;

然后我们在app/controller文件夹里新建一个user.js文件。在这里我们需要获取前端提交上来的数据,并且将数据处理的结果返回给前端。具体代码如下。

'use strict';

const Controller=require('egg').Controller;
/**
 * @Controller 用户管理
 */
class UserController extends Controller {

  /**
  * @summary 新增用户
  * @router post /user/add
  * @request body userAddRequest 
  * @response 200 
  */
  async addUser() {
    const { ctx }=this;

    //通过ctx.request.body的方式,可以获取到前端post方式提交上来的数据
    const data=ctx.request.body;

    //调用service层的addUser方法。并且返回相应的结果
    const userInfo=await ctx.service.user.addUser(data);
    
    //向前端接口响应数据。
    ctx.body=userInfo;
  }

}

module.exports=UserController;

最后我们定义一个路由,让前端请求访问此路由。框架会监听路由是否被访问,如果被访问了则会调用我们定义在controller层的新增用户的方法。我们在app/router.js文件中添加如下代码,即可完成路由的定义。

//新增用户路由
  router.post('/user/add', controller.user.addUser);

完成这步骤后,我们一个新增用户的功能就已经完成了。接下里我们就测试一下它的实际效果。我们运行命令:npm run dev。启动项目,然后打开网页http://127.0.0.1:7001,可以直接在swagger-ui.html页面中进行测试。结果如下图所示。

经过测试,数据已经添加完成。所以数据库连接也是正常的。

本次分享暂时先告一段落。请各位小伙伴抬起你们发财的小手,点个赞呗。下次我将会进行和大家分享对数据查改删的方法。关注我!!!更多精彩分享不迷路。