前端
任何与用户直接打交道的界面都称为
前端,不直接跟用户打交道的界面称为后端。
前端最核心的技术:HTML、CSS、Javascript。其中,HTML是网页的结构,CSS是网页的外观,Javascript是页面的行为。
浏览器窗口输入网址发生的几件事
软件开发架构
# BS架构
Browser <---> Server
# CS架构
Client <---> Server
******************************
******************************
"""
BS架构本质上也是CS架构
浏览器充当很多服务端的客户端
"""
- 服务端
# -*- coding: utf-8 -*-
from socket import *
HOST = \'127.0.0.1\'
PORT = 8080
BUFSIZE = 1024
ADDR = (HOST, PORT)
server = socket()
server.bind(ADDR)
server.listen(5)
while True:
conn, addr = server.accept()
while True:
data = conn.recv(BUFSIZE)
if not data:
break
print(data)
conn.send(b\'Hello!\')
conn.close()
- 浏览器访问
访问地址:127.0.0.1:8080
# 服务端返回内容
b\'GET / HTTP/1.1\r\nHost: 127.0.0.1:8080\r\nConnection: keep-alive\r\nsec-ch-ua: " Not A;Brand";v="99", "Chromium";v="90", "Google Chrome";v="90"\r\nsec-ch-ua-mobile: ?0\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\nSec-Fetch-Site: none\r\nSec-Fetch-Mode: navigate\r\nSec-Fetch-User: ?1\r\nSec-Fetch-Dest: document\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n\'
"""
能够很清晰的看到返回的信息内包含了UA请求头等信息
"""
HTTP协议
超文本传输协议,用来规定服务端和浏览器之间进行数据交互的格式。是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准,HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。
HTTP是基于客户端/服务端(C/S)的架构模型,通过一个可靠的链接来交换信息,是一个无状态的请求/响应协议,使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。
-
基于请求和响应
-
基于TCP/IP作用于应用层之上的协议
-
无状态(采用
Cookie、Session、Token记录用户状态)- 无/短链接(长链接:websocket)
客户端请求数据格式
请求消息由
请求首行、请求头、空行(\r\n)、请求体组成。
服务端响应数据格式
HTTP响应由
状态行、消息报头、空行(\r\n)和响应正文组成。
"""
- 请求数据格式
- 请求首行
- 标识HTTP协议版本,当前请求方式
- get请求
- 朝服务端获取数据
- post请求
- 朝服务端发送数据
- 请求头
- 一大堆key,value键值对
- \r\n
- 请求体
- 并不是所有的请求方法/方式有
- get没有,post有(post提交的是敏感数据)
- 响应数据格式
- 状态行
- 消息报头
- \r\n
- 响应正文
"""
HTTP响应状态码分类
HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。
| 分类 | 分类描述 |
|---|---|
| 1** | 信息,服务器收到请求,需要请求者继续执行操作 |
| 2** | 成功,操作被成功接收并处理 |
| 3** | 重定向,需要进一步的操作以完成请求 |
| 4** | 客户端错误,请求包含语法错误或无法完成请求 |
| 5** | 服务器错误,服务器在处理请求的过程中发生了错误 |
"""
- 200
- 请求成功
- 301
- 资源(网页等)被永久转移到其他URL,重定向
- 404
- 请求资源不存在
- 403
- 服务器理解请求客户端的请求,但是拒绝执行此请求
- 500
- 内部服务器错误
"""
URL:统一资源定位符
URI:统一资源标识符
HTML
HTML,全称是超文本标记语言(HyperText Markup Language),它是一种用于创建网页的标记语言。标记语言是一种将文本(Text)以及文本相关的其他信息结合起来,展现出关于文档结构和数据处理细节的计算机文字编码。
HTML是一个网页的主体部分,也是一个网页的基础。因为一个网页可以没有样式,可以没有交互,但是必须要有网页需要呈现的内容。
- 所有网站的内部都是HTML代码。
文件后缀名一般为:.html .htm
- 注释方式
我曾说过,注释是代码的灵魂。
<!--单行注释-->
<!--
多行注释1
多行注释2
多行注释3
-->
由于HTML代码非常的多,故习惯性的使用注释来划定功能区域。
HTML注释的注意事项:
- HTML注释不支持嵌套。
- HTML注释不能写在HTML标签中。
- HTML文档结构
<!DOCTYPE HTML>
<html>
<head>...</head>
<body>...</body>
</html>
首先,<!DOCTYPE HTML>是文档声明,必须写在HTML文档的第一行,位于<html>标签之前,表明该文档是HTML5文档。
-
<html></html>称为根标签,所有的网页标签都在<html></html>中。 -
<head></head>标签用于定义文档的头部,它是所有头部元素的容器。常见的头部元素有<title>、<script>、<style>、<link>和<meta>等标签,头部标签在下一节中会有详细介绍。 - 在
<body>和</body>标签之间的内容是网页的主要内容,如<h1>、<p>、<a>、<img>等网页内容标签,在<body>标签中的内容(图中淡绿色部分内容)最终会在浏览器中显示出来。
Head内常用标签
| 标签 | 意义 |
|---|---|
| 定义网页标题 | |
| 定义内部样式表(用来写CSS代码) |
- meta标签
元素可提供有关页面的原信息(mata-information),针对搜索引擎和更新频度的描述和关键词。
提供的信息是用户不可见的。 meta标签的组成:meta标签共有两个属性,它们分别是http-equiv属性和name属性,不同的属性又有不同的参数值,这些不同的参数值就实现了不同的网页功能。
- http-equiv属性
它用来向浏览器传达一些有用的信息,帮助浏览器正确地显示网页内容,与之对应的属性值为content,content中的内容其实就是各个参数的变量值。
<!--重定向 2秒后跳转到对应的网址,注意分号-->
<meta http-equiv="refresh" content="2;URL=http://www.baidu.com">
<!--指定文档的内容类型和编码类型 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<!--告诉IE浏览器以最高级模式渲染当前网页-->
<meta http-equiv="x-ua-compatible" content="IE=edge">
- name属性
主要用于页面的关键字和描述,是写给搜索引擎看的,关键字可以有多个用 ‘,’号隔开,与之对应的属性值为content,content中的内容主要是便于搜索引擎机器人查找信息和分类信息用的,即网页推荐或者SEO查询,description是对该网页的描述性信息。
<meta name="keywords" content="meta总结,html meta,meta属性,meta跳转">
<meta name="description" content="雪山菜鸟">
- 其他标签
<!--标题-->
<title>雪山菜鸟</title></title>
<!--icon图标(网站的图标)-->
<link rel="icon" href="img.ico">
<!--定义内部样式表-->
<style></style>
<!--引入外部样式表文件-->
<link rel="stylesheet" href="mystyle.css">
<!--定义JavaScript代码或引入JavaScript文件-->
<script src="myscript.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>雪山菜鸟不菜</title>
<!--style将body中的h1标签的文字颜色改为黄色-->
<style>
h1 {
color: yellow;
}
</style>
<!-- script内部用来书写JS代码,同时也可以引入外部的JS文件-->
<script>
alert("这是一个弹框")
</script>
<!-- 用于引入CSS文件-->
<link rel="stylesheet" href="外部CSS文件的路径">
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>
Body内常用标签
- 基本标签(块级标签和内联标签)
<h1> - <h6> 标签可定义标题。<h1> 定义最大的标题。<h6> 定义最小的标题。 由于 h 元素拥有确切的语义,因此请您慎重地选择恰当的标签层级来构建文档的结构。
<b>加粗</b>
<i>斜体</i>
<u>下划线</u>
<s>删除</s>
<p>段落标签</p>
<h1>标题1</h1>
<h2>标题2</h2>
<h3>标题3</h3>
<h4>标题4</h4>
<h5>标题5</h5>
<h6>标题6</h6>
<!--换行-->
<br>
<!--水平线--><hr>
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>雪山菜鸟</title>
</head>
<body>
<h1>海燕</h1>
<p>在苍茫的大海上,</p>
<p>狂风卷集着乌云。</p>
<p>在乌云和大海之间,</p>
<p>海燕像黑色的闪电,</p>
<p>在高傲地飞翔。</p>
</body>
</html>
- 特殊标签
| 内容 | 对应代码 |
|---|---|
| 空格 |   |
| > | > |
| < | < |
| & | & |
| ¥ | ¥ |
| 版权 | © |
| 注册 | ® |
- 标签分类
HTML中标签元素三种不同类型:块级标签,行内标签,行内块状元素。
通常块级标签可以包含内联元素或某些块级标签,但内联元素不能包含块标签,它只能包含其它内联元素,<p>标签不能包含块级标签,<p>标签也不能包含<p>标签。
常用的块级标签:
<!--
1、每个块级元素都从新的一行开始,并且其后的元素也另起一行。独占一行
2、元素的高度、宽度、行高以及顶和底边距都可设置。
3、元素宽度在不设置的情况下,是它本身父容器的100%(和父元素的宽度一致),除非设定一个宽度。
-->
<div> <p> <h1>~<h6> <ol> <ul> <table><form> <li>
常用的行内标签:
<!--
1、和其他元素都在一行上;
2、元素的高度、宽度及顶部和底部边距不可设置;
3、元素的宽度就是它包含的文字或图片的宽度,不可改变。
-->
<a> <span> <br> <i> <em> <strong> <label>
常用的行内块状标签:
<!--
1、和其他元素都在一行上;
2、元素的高度、宽度、行高以及顶和底边距都可设置
-->
<img> <input>
- 常用标签
页面的布局一般先用div和span标签进行占位,之后再进行调整。
div ---> 块级标签
<!--
只要是块级标签,
都可以嵌套任意的块级标签和行内标签
p标签不能嵌套块级标签,
可以嵌套行内标签,
p标签也不能包含p标签。
-->
span ---> 行内标签
a标签
链接标签,<a>标记代表一个链接点,是英文anchor(锚点)的简写,href放的是URL,用户点击就会跳转,它的作用是把当前位置的文本或图片连接到其他的页面、文本或图像。
<body>
<h1>
<!-- a链接 超链接
target:_blank 在新的网站打开链接的资源地址
_self 在当前网站打开链接的资源地址
title: 鼠标悬停时显示的标题
-->
<a href="http://www.baidu.com" target="_blank" title="鼠标悬停显示的标题">这真是个内容</a>
<a href="a.zip">下载包</a>
<a href="mailto:abaab@tedu.cn">联系我们</a>
<!-- 返回页面顶部的内容 -->
<a href="#">跳转到顶部</a>
<!-- 返回某个id -->
<a href="#p1">跳转到p1</a>
<!-- javascript:是表示在触发<a>默认动作时,执行一段JavaScript代码,而 javascript:; 表示什么都不执行,这样点击<a>时就没有任何反应。 -->
<a href="javascript:alert(1)">内容</a>
<a href="javascript:;">内容</a>
</h1>
</body>
target=“_blank”在新的网站打开链接的资源地址
target=“_self”在当前网站打开链接的资源地址
title: 表示鼠标悬停时显示的标题
链接其他表现形式
- 目标文档为下载资源 例如:href属性值,指定的文件名称,就是下载操作(rar、zip等)
- 电子邮件链接 前提:计算机中必须安装邮件客户端,并且配置好了邮件相关信息。 例如:
<a href="mailto:abaab@tedu.cn">联系我们</a> - 返回页面顶部的空链接或具体id值的标签 例如:
<a href="#">内容</a>或<a href="#id值">内容</a> - javascript:是表示在触发
<a>默认动作时,执行一段JavaScript代码。 例如:<a href="javascript:alert()">内容</a> - javascript:;表示什么都不执行,这样点击
<a>时就没有任何反应 例如:<a href="javascrip:;">内容</a
img标签
一个网页除了有文字,还会有图片。我们使用<img/>标签在网页中插入图片。
语法:<img src="图片地址/路径" alt="图片加载失败时显示的内容" title = "鼠标悬浮图片显示的标题" />
注意:
- src设置的图片地址可以是本地的地址也可以是一个网络地址。
- 图片的格式可以是png、jpg和gif。
- alt属性的值会在图片加载失败时显示在网页上。
- 还可以为图片设置宽度(width)和高度(height),不设置就显示图片默认的宽度和高度。
<div>
<span>与行内元素展示的标签<span>
<span>与行内元素展示的标签<span>
<img src="./machine-right.png" alt="图片加载显示的内容" style="width:200px;height:200px">
<img src="./finance-right.png" alt="图片加载显示的内容" style="width: 200px;height: 200px">
</div>
浏览器查看效果:行内块元素
- 与行内元素在一行内显示。
- 可以设置宽度和高度。
- span标签可以单独摘出某块内容,结合css设置相应的样式。
- 标签具有的两个重要属性
标签既有默认的属性,也支持进行自定义的属性,因此,标签也能进行存储一些数据。
id值
类似于标签的身份证号,再同一个html页面上的id值不能重复。
<a href="" id="d1">顶部</a>
<div style="height: 1000px;background-color: green"></div>
<a href="" id="d2">中部</a>
<div style="height: 1000px;background-color: yellow"></div>
<a href="#d1">底部</a>
<a href="#d2">回到中部</a>
class值
该值类似于面向对象里面的继承,一个标签可以继承多个class值。
- 列表标签
- 无序列表
再页面布局的时候,只要是排版一致的几行,用的都是ul标签。
<ul type="disc">
<li>第一项</li>
<li>第二项</li>
</ul>
- disc(实心圆点,默认值)
- circle(空心圆圈)
- square(实心方块)
- none(无样式)
- 有序列表
<!--
ol>li*2
ol>li{$}*3
-->
<ol type="1" start="2">
<li>第一项</li>
<li>第二项</li>
</ol>
- 1 数字列表,默认值
- A 大写字母
- a 小写字母
- Ⅰ大写罗马
- ⅰ小写罗马
- 标题列表
<dl>
<dt>标题1</dt>
<dd>内容1</dd>
<dt>标题2</dt>
<dd>内容1</dd>
<dd>内容2</dd>
</dl>
表格标签
只要是展示数据,都可以采用表格标签。
表格由<table> 标签来定义,每个表格均有若干行(由 <tr> 标签定义),每行被分割为若干单元格(由<td>标签定义)。
字母 td 指表格数据(table data),即数据单元格的内容。数据单元格可以包含文本、图片、列表、段落、表单、水平线、表格等等。
属性
- border: 表格边框
- cellpadding: 内边距
- cellspacing: 外边距
- width: 像素 百分比(最好通过css来设置长宽)
- rowspan: 单元格竖跨多少行
- colspan: 单元格横跨多少列(即合并单元格)
<table>
<thead>
<!-- 一个tr就表示一行-->
<tr>
<!-- th展示的是加粗的文本-->
<th>
内容
</th>
</tr>
</thead>
<tbody>
<tr>
<!-- td展示的是正常的文本-->
<td>
内容
</td>
</tr>
</tbody>
</table>
rowspan 合并行(竖着合并)
colspan 合并列(横着合并)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="table">
<table border="1" cellspacing="0">
<!--表格头-->
<thead>
<!--表格行-->
<tr>
<!--表格列,【注意】这里使用的是th-->
<th></th>
<th>星期一</th>
<th>星期二</th>
<th>星期三</th>
<th>星期四</th>
<th>星期五</th>
</tr>
</thead>
<!--表格主体-->
<tbody>
<!--表格行-->
<tr>
<td rowspan="3">上午</td>
<!--表格列,【注意】这里使用的是td-->
<td>语文</td>
<td>数学</td>
<td>英文</td>
<td>生物</td>
<td>化学</td>
</tr>
<tr>
<!--表格列,【注意】这里使用的是td-->
<td>语文</td>
<td>数学</td>
<td>英文</td>
<td>生物</td>
<td>化学</td>
</tr>
<tr>
<!--表格列,【注意】这里使用的是td-->
<td>语文</td>
<td>数学</td>
<td>英文</td>
<td>生物</td>
<td>化学</td>
</tr>
<tr>
<td rowspan ="2">下午</td>
<!--表格列,【注意】这里使用的是td-->
<td>语文</td>
<td>数学</td>
<td>英文</td>
<td>生物</td>
<td>化学</td>
</tr>
<tr>
<!--表格列,【注意】这里使用的是td-->
<td>语文</td>
<td>数学</td>
<td>英文</td>
<td>生物</td>
<td>化学</td>
</tr>
</tbody>
<!--表格底部-->
<tfoot>
<tr>
<td colspan="6">课程表</td>
</tr>
</tfoot>
</table>
</div>
</body>
</html>
label标签
定义:<label> 标签为 input 元素定义标注(标记)。
说明:
- label 元素不会向用户呈现任何特殊效果。
-
<label>标签的 for 属性值应当与相关元素的 id 属性值相同。
<form action="">
<label for="username">用户名</label>
<input type="text" id="username" name="username">
</form>
textarea多行文本
<textarea name="memo" id="memo" cols="30" rows="10">
默认内容
</textarea>
属性说明:
- name:名称
- rows:行数
- cols:列数
- disabled:禁用
select标签
<form action="" method="post">
<select name="city" id="city">
<option value="1">北京</option>
<option selected="selected" value="2">上海</option>
<option value="3">广州</option>
<option value="4">深圳</option>
</select>
</form>
属性说明:
- multiple:布尔属性,设置后为多选,否则默认单选
- disabled:禁用
- selected:默认选中该项
- value:定义提交时的选项值
form表单(★★★★★)
表单用于向服务器传输数据,从而实现用户与Web服务器的交互,获取前端数据,发送给后端。表单能够包含input系列标签,比如文本字段、复选框、单选框、提交按钮等等。
表单还可以包含textarea、select、fieldset和 label标签。
| 属性 | 描述 |
|---|---|
| accept-charset | 规定在被提交表单中使用的字符集(默认:页面字符集)。 |
| action | 规定向何处提交表单的后端路径(URL)(提交页面)。 |
| autocomplete | 规定浏览器应该自动完成表单(默认:开启)。 |
| enctype | 规定被提交数据的编码(默认:url-encoded)。 |
| method | 规定在提交表单时所用的 HTTP 方法(默认:GET)。 |
| name | 规定识别表单的名称(对于 DOM 使用:document.forms.name)。 |
| novalidate | 规定浏览器不验证表单。 |
| target | 规定 action 属性中地址的目标(默认:_self)。 |
input
<input> 元素会根据不同的 type 属性,变化为多种形态,默认要结合label标签使用。
| type属性值 | 表现形式 | 对应代码 |
|---|---|---|
| text | 单行输入文本 | |
| password | 密码输入框 | |
| date | 日期输入框 | |
| checkbox | 复选框 | |
| radio | 单选框 | |
| submit | 提交按钮 | |
| reset | 重置按钮 | |
| button | 普通按钮 | |
| hidden | 隐藏输入框 | |
| file | 文本选择框 |
- 相关属性
"""
name:表单提交时的“键”,注意和id的区别
value:表单提交时对应项的值
type="button", "reset", "submit"时,为按钮上显示的文本年内容
type="text","password","hidden"时,为输入框的初始值
type="checkbox", "radio", "file",为输入相关联的值
checked:radio和checkbox默认被选中的项
readonly:text和password设置只读
disabled:所有input均适用
"""
注:
所有获取用户输入的标签,都应该有name属性,用户的数据类似于字典的value。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>注册页面</h1>
<form action="">
<!-- host:port/index/-->
<p>
<label for="username">
username:<input type="text" name="" id="username">
</label>
</p>
<p>
<label for="password">
password:
</label>
<!-- 可以直接通过id进行关联-->
<input type="password" name="" id="password">
</p>
<p>
birthday:
<label for="birthdat">
<input type="date" id="birthday">
</label>
</p>
<p>
gender:
<label for="gender">
<!-- checked="checked" 默认选中
当标签的属性名和属性值一样的时候可以简写为checked-->
<input type="radio" name="gender" checked="checked">male
<input type="radio" name="gender">female
<input type="radio" name="gender">other
</label>
</p>
<p>
province:
<select name="province" id="province">
<option value="1">北京</option>
<!-- selected默认选中-->
<option value="2" selected>上海</option>
<option value="3">广州</option>
</select>
</p>
<p>
hobby:
<select name="hobby" id="hobby" multiple>
<option value="1">吃饭</option>
<option value="2">睡觉</option>
<option value="3">运动</option>
<option value="4">学习</option>
</select>
</p>
<p>
<!-- 进行文件的上传-->
head_portrait:
<label for="file">
<input type="file" id="file">
</label>
</p>
<p>
自我介绍:
<!-- 大段文本的获取-->
<textarea name="introduce" id="introduce" cols="30" rows="10" maxlength="100"></textarea>
</p>
<p>
<input type="submit" value="注册">
<!-- <button>点我点我点我</button>-->
</p>
</form>
</body>
</html>
验证form表单的数据提交
form表单默认提交的数据是GET请求,数据是直接放在URL后面,可以通过
method指定提交方式。
注:
所有获取用户输入的标签都应该有name属性,针对用户选择的标签,需要添加value值,form提交文件的method必须为post,还需要添加enctype="multipart/form-data"参数。
- flask服务端代码
# -*- coding: utf-8 -*-
from flask import Flask, request
app = Flask(__name__)
# 当前URL既可以支持GET请求,也可以支持POST请求 默认支持GET请求
@app.route(\'/index\', methods=[\'GET\', \'POST\'])
def index():
print(request.form) # 获取form表单提交过来的非文件数据
print(request.files) # 获取文件数据
file_obj = request.files.get(\'file.png\') # 键名由前端name属性决定
print(file_obj.name)
file_obj.save(file_obj.name) # 保存从前端获取到的文件
return \'OK\'
app.run()
- index页面代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>注册页面</h1>
<form action="http://127.0.0.1:5000/index" method="post" enctype="multipart/form-data">
<p>
<label for="username">
username:<input type="text" name="username" id="username">
</label>
</p>
<p>
<label for="password">
password:
</label>
<input type="password" name="password" id="password">
</p>
<p>
birthday:
<label for="birthdat">
<input type="date" id="birthday">
</label>
</p>
<p>
gender:
<label for="gender">
<input type="radio" name="gender" checked="checked" value="male">male
<input type="radio" name="gender" value="female">female
<input type="radio" name="gender" value="other">other
</label>
</p>
<p>
province:
<select name="province" id="province">
<option value="北京">北京</option>
<option value="上海" selected>上海</option>
<option value="广州">广州</option>
</select>
</p>
<p>
hobby:
<select name="hobby" id="hobby" multiple>
<option value="吃饭">吃饭</option>
<option value="睡觉">睡觉</option>
<option value="运动">运动</option>
<option value="学习">学习</option>
</select>
</p>
<p>
head_portrait:
<label for="file">
<input type="file" id="file" name="file">
</label>
</p>
<p>
自我介绍:
<textarea name="introduce" id="introduce" cols="30" rows="10" maxlength="100"></textarea>
</p>
<p>
<input type="submit" value="注册">
</p>
</form>
</body>
</html>
CSS
CSS是指层叠样式表(Cascading Style Sheets),样式定义如何显示HTML元素,样式通常又会存在于样式表中。也就是说把HTML元素的样式都统一收集起来写在一个地方或一个CSS文件里。
- CSS引入方式
把样式规则的内容都保存在CSS文件中,此时该CSS文件被称为外部样式表,在HTML文件中通过link标签引用该CSS文件即可。这样浏览器在解析到该link标签的时候就会加载该CSS文件,并按照该文件中的样式规则渲染HTML文件。
/*style 标签内部直接引入*/
<style>
h1 {
background-color: green;
}
</style>
/*link 标签引入外部CSS样式 (最正规的方式,起到解耦合的作用)*/
<link rel="stylesheet" href="myfile.css">
/*行内式*/
<h1 style="background-color: green">你好!我是Hello World!</h1>
- 注释方式
/*这是单行注释*/
/*
这是多行注释
这是多行注释
*/
通常在写CSS的时候,也是通过注释来划定样式区域。
- CSS语法结构
CSS语法分为两部分,即选择器和声明,声明由属性和值组成,多个声明之间用逗号进行分隔。
选择器 {
属性1:值1,
属性2:值2,
属性3:值3
}
CSS基本选择器
- id选择器(常用)
通过id值选择对应的标签
/*找到id为d1的标签,将其颜色改为绿色*/
#d1 {
color: green;
}
- 类选择器(常用)
通过样式类选择标签
/*找到class值包含c1的标签,将其颜色改为绿色*/
.c1 {
color: green;
}
- 元素/标签选择器
通过标签名来选择元素
/*将span标签全部改为绿色*/
span {
color: green;
}
- 通用选择器
使用*选择所有元素
/*将html页面上所有的标签全部找到,并改为绿色*/
* {
color: green;
}
CSS组合选择器
- 后代选择器
/*从div的所有后代中找span标签,将其全部设置字体颜色为红色*/
/*后代选择器*/
div span{
color: red;
}
- 儿子选择器
/*将div内部的子元素span标签全部设置为红色,即通过>进行连接*/
/*儿子选择器*/
div>span {
color: red;
}
- 毗邻选择器
/*将同级别紧挨着的下面的第一个span标签设置为红色*/
/*毗邻选择器*/
div+span {
color: red;
}
- 弟弟选择器
/*将与div标签同级别下面所有的span标签设置为红色*/
/*弟弟选择器*/
div~span {
color: red;
}
CSS属性选择器
除了HTML元素的id属性和class属性外,还可以根据HTML元素的特定属性选择元素。
<body>
<input type="text" username>
<input type="text" username="jack">
<input type="text" username="json">
<p username="jack">ppp</p>
</body>
- 含有某个属性
/*将所有含有属性名为username的标签背景色改为红色*/
[username] {
background-color: red;
}
- 含有某个属性并且有某个值
/*将所有属性名为username且属性值为jack的标签背景色改为黄色*/
[username="jack"] {
background-color: yellow;
}
- 含有某个属性并且有某个值的某个标签
/*找到所有属性名为username且属性值为json的input标签,将其背景色改为黄色*/
input[username="json"] {
background-color: yellow;
}
CSS分组选择器
当多个元素的样式相同的时候,可以通过在多个选择器之间使用逗号分隔的分组选择器来统一设置元素样式,其中,逗号表示并列关系。
/*为div标签和p标签统一设置字体为红色的样式*/
div,p {
color: red;
}
/*也可以写成以下形式*/
div,
p {
color: red;
}
/*将id为d1的标签,class为c1的标签,span标签的字体颜色设置为红色*/
#d1,.c1,span {
color: red;
}
CSS伪类选择器
- 未访问超链接时
a:link {
color: blue;
}
- 鼠标悬浮时,悬浮态(★★★★★)
a:hover {
background-color: #eee;
}
- 访问过的超链接
a:visited {
color: gray;
}
- 鼠标点击不松开,激活态
a:active {
color: green;
}
- input输入框获取焦点时
input:focus {
outline: none;
background-color: #eee;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
/*没有访问时的超链接a标签的字体颜色*/
a:link {
color: red;
}
/*鼠标悬停时的超链接a标签的字体颜色*/
a:hover {
color: blue;
}
/*鼠标点击不松开,激活态,a标签的字体颜色*/
a:active {
color: black;
}
/*访问之后的,超链接a标签的字体颜色*/
a:visited {
color: darkgray;
}
</style>
</head>
<body>
<a href="http://www.baidu.com">百度一下,你就知道</a>
</body>
</html>
CSS伪元素选择器
- first-letter
用于为文本的首字母(或第一个文字)设置特殊样式(颜色、字体大小等)。
例如:
p:first-letter {
font-size: 48px;
}
- before
用于在元素的内容前面插入新内容。
例如:
p:before {
content: "*";
color: red;
}
在所有p标签的内容前面加上一个红色的*。
- after
用于在元素的内容后面插入新内容。
例如:
p:after {
content: "?";
color: red;
}
在所有p标签的内容后面加上一个蓝色的?。
注:
before和after通常是用来清除浮动带来的影响,即解决父标签塌陷的问题。
选择器的优先级
/*
id选择器
类选择器
标签选择器
行内式
*/
/*
优先级:行内/内联 > id > 类 > 标签
精确度越高,优先级越大
*/
/*id选择器*/
#d1 {
color: aqua;
}
/*类选择器*/
.c1 {
color: blue;
}
/*元素/标签选择器*/
p {
color: red;
}
/*行内式/内联样式*/
<p id="d1" class="c1" style="color: darkgray">大漠孤烟直,长河落日圆。</p>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="mycss.css">
<style>
/*
选择器相同,书写位置不一样
遵循的是就近原则,即谁离标签最近,就听谁的
*/
/*id选择器*/
#d1 {
color: aqua;
}
/*设置的字体颜色应该为id选择器设置的颜色*/
/*类选择器*/
.c1 {
color: blue;
}
/*元素/标签选择器*/
p {
color: red;
}
/*
选择器不同
*/
</style>
<!-- 读取代码的顺序是从上至下的-->
<link rel="stylesheet" href="mycss.css">
</head>
<body>
<p id="d1" class="c1">大漠孤烟直,长河落日圆。</p>
</body>
</html>
注意:
还有一种不讲道理的!import方式来强制让样式生效,但是不推荐使用。因为大量使用!import的代码是无法维护的。
CSS属性相关
- 设置长宽
<style>
p {
background-color: red;
height: 200px;
width: 400px;
}
span {
background-color: green;
/*行内标签无法设置长宽,就算设置了也不会生效*/
}
</style>
- 字体属性
<style>
p {
/*设置字体的样式*/
/*第一个字体不生效,就会使用后面的字体,即会有多个备用的字体格式*/
font-family: \'Consolas\', \'Monaco\', \'Bitstream Vera Sans Mono\', monospace;
/*设置字体宽细*/
font-weight: bolder; /*更粗*/
/*设置字体大小 一般为12 14 16 48 64*/
font-size: 20px;
/*设置文字颜色*/
color: green;
}
</style>
font-weight参数:
| 值 | 描述 |
|---|---|
| normal | 默认值,标准粗细 |
| bold | 粗体 |
| bolder | 更粗 |
| lighter | 更细 |
| 100~900 | 设置具体粗细,400等同于normal,而700等同于bold |
| inherit | 继承父元素字体的粗细值 |
color
设置内容的字体颜色。
支持三种颜色值:
- 十六进制值 如: #FF0000
- 一个RGB值 如: RGB(255,0,0)
- 颜色的名称 如: red
p {
color: red;
}
- 文字属性
text-align
文本对齐
text-align 属性规定元素中的文本的水平对齐方式。
| 值 | 描述 |
|---|---|
| left | 左边对齐 默认值 |
| right | 右对齐 |
| center | 居中对齐 |
| justify | 两端对齐 |
line-height
行高
text-decoration
文字装饰。
| 值 | 描述 |
|---|---|
| none | 默认。定义标准的文本。 |
| underline | 定义文本下的一条线。 |
| overline | 定义文本上的一条线。 |
| line-through | 定义穿过文本下的一条线。 |
| inherit | 继承父元素的text-decoration属性的值。 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
p {
font-size: 16px;
text-align: center; /*居中*/
line-height: 100px; /*行高*/
text-decoration: underline; /*定义文本下的一条线*/
text-indent: 32px; /*首行缩进2个字符*/
}
a {
text-decoration: none; /*主要用于将a标签默认的下划线去掉*/
}
</style>
</head>
<body>
<p>仰天长啸出门去,我辈岂是蓬蒿人。</p>
<a href="https://www.mzitu.com">点我</a>
</body>
</html>
- 背景图片
常用背景相关属性:
| 属性 | 描述 |
|---|---|
| background-color | 规定要使用的背景颜色。 |
| background-image | 规定要使用的背景图像。 |
| background-size | 规定背景图片的尺寸。 |
| background-repeat | 规定如何重复背景图像。 |
| background-attachment | 规定背景图像是否固定或者随着页面的其余部分滚动。 |
| background-position | 规定背景图像的位置。 |
| inherit | 规定应该从父元素继承background属性的设置。 |
background-repeat取值范围:
| 值 | 描述 |
|---|---|
| repeat | 默认。背景图像将在垂直方向和水平方向重复。 |
| repeat-x | 背景图像将在水平方向重复。 |
| repeat-y | 背景图像将在垂直方向重复。 |
| no-repeat | 背景图像将仅显示一次。 |
| inherit | 规定应该从父元素继承background-repeat属性的设置。 |
background-attachment取值范围:
| 值 | 描述 |
|---|---|
| scroll | 默认值。背景图像会随着页面其余部分的滚动而移动。 |
| fixed | 当页面的其余部分滚动时,背景图像不会移动。 |
| inherit | 规定应该从父元素继承background-attachment属性的设置。 |
background-position取值范围:
| 值 | 描述 |
|---|---|
| top left top center top right center left center center center right bottom left bottom center bottom right | 如果只设置了一个关键词,那么第二个值就是"center"。 默认值:0% 0%。 |
| x% y% | 第一个值是水平位置,第二个值是垂直位置。 左上角是 0% 0%。右下角是 100% 100%。 如果只设置了一个值,另一个值就是50%。 |
| xpos ypos | 第一个值是水平位置,第二个值是垂直位置。 左上角是 0 0。单位是像素 (0px 0px) 或任何其他的 CSS 单位。 如果只设置了一个值,另一个值就是50%。 可以混合使用%和position值。 |
示例:
body {
background-color: red;
backgraound-image: url(xx.png);
background-size: 300px 300px;
background-repeat: no-repeat;
background-position: center
}
简写:
body {
background: red url(xx.png) no-repeat fixed center/300px 300px;
}
案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
div {
height: 800px;
width: 800px;
background-color: gray;
background-image: url("1.png"); /*默认全部铺满*/
background-repeat: no-repeat; /*不平铺*/
/*background-repeat: repeat-x; !*x轴方向平铺*!*/
/*background-repeat: repeat-y; !*y轴方向平铺*!*/
/*
浏览器是一个三维的立体结构,即xyz,
z轴指向用户,越大距离用户越近。
*/
background-position: center center; /*第一个左 第二个右 居中*/
/*background: url("1.png") gray no-repeat center center; !*简写*!*/
}
</style>
</head>
<body>
<div>
</div>
</body>
</html>
背景图片小案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#d1 {
height: 500px;
background-color: red;
}
#d2 {
height: 500px;
background-color: green;
}
#d3 {
height: 500px;
background-image: url("1.png");
background-attachment: fixed; /*随着页面的其余部分滚动*/
}
#d4 {
height: 500px;
background-color: blue;
}
</style>
</head>
<body>
<div id="d1"></div>
<div id="d2"></div>
<div id="d3"></div>
<div id="d4"></div>
</body>
</html>
- display属性
行内元素和块级元素的区别:
行内元素:
- 与其他行内元素并排;
- 不能设置宽、高。默认的宽度,就是文字的宽度。
块级元素:
- 霸占一行,不能与其他任何元素并列;
- 能接受宽、高。如果不设置宽度,那么宽度将默认变为父亲的100%。
块级元素和行内元素的分类:
在以前的HTML知识中,我们已经将标签分过类,当时分为了:文本级、容器级。
从HTML的角度来讲,标签分为:
- 文本级标签:p、span、a、b、i、u、em。
- 容器级标签:div、h系列、li、dt、dd。
PS:为甚么说p是文本级标签呢?因为p里面只能放文字&图片&表单元素,p里面不能放h和ul,p里面也不能放p。
现在,从CSS的角度讲,CSS的分类和上面的很像,就p不一样:
- 行内元素:除了p之外,所有的文本级标签,都是行内元素。p是个文本级,但是是个块级元素。
- 块级元素:所有的容器级标签都是块级元素,还有p标签。
块级元素和行内元素的相互转换
我们可以通过display属性将块级元素和行内元素进行相互转换。display即“显示模式”。
块级元素可以转换为行内元素:
一旦,给一个块级元素(比如div)设置:
display:
inline;
那么,这个标签将立即变为行内元素,此时它和一个span无异。inline就是“行内”。也就是说:
- 此时这个div不能设置宽度、高度;
- 此时这个div可以和别人并排了
行内元素转换为块级元素:
同样的道理,一旦给一个行内元素(比如span)设置:
display: block;
那么,这个标签将立即变为块级元素,此时它和一个div无异。block”是“块”的意思。也就是说:
- 此时这个span能够设置宽度、高度
- 此时这个span必须霸占一行了,别人无法和他并排
- 如果不设置宽度,将撑满父亲
PS:标准流里面的限制非常多,导致很多页面效果无法实现。如果我们现在就要并排、并且就要设置宽高,那该怎么办呢?办法是:脱离标准流!
css中一共有三种手段,使一个元素脱离标准文档流:
- (1)浮动
- (2)绝对定位
- (3)固定定位
盒子模型
- 盒模型的概念
在CSS中,"box model"这一术语是用来设计和布局时使用,然后在网页中基本上都会显示一些方方正正的盒子。我们称为这种盒子叫盒模型。
盒模型有两种:标准模型和IE模型。我们在这里重点讲标准模型。
盒模型示意图
"""
width:内容的宽高
height:内容的高
padding:内边距
border:边框
margin:外边距
"""
- 盒模型的属性
width:内容的宽度
height: 内容的高度
padding:内边距,边框到内容的距离
border: 边框,就是指的盒子的宽度
margin:外边距,盒子边框到附近最近盒子的距离
- 盒模型的计算
如果一个盒子设置了padding,border,width,height,margin(咱们先不要设置margin,margin有坑,后面课程会讲解)
盒子的真实宽度=width+2padding+2border
盒子的真实宽度=height+2padding+2border
那么在这里要注意看了。标准盒模型,width不等于盒子真实的宽度。
另外如果要保持盒子真实的宽度,那么加padding就一定要减width,减padding就一定要加width。真实高度一样设置。
- padding
padding:就是内边距的意思,它是边框到内容之间的距离
另外padding的区域是有背景颜色的。并且背景颜色和内容的颜色一样。也就是说background-color这个属性将填充所有的border以内的区域
- padding的设置
padding有四个方向,分别描述4个方向的padding。
描述的方法有两种
1、写小属性,分别设置不同方向的padding
padding-top: 30px;
padding-right: 30px;
padding-bottom: 30px;
padding-left: 30px;
2、写综合属性,用空格隔开
/*
上 右 下 左
*/
padding: 20px 30px 40px 50px ;
/*
上 左右 下
*/
padding: 20px 30px 40px;
/*
上下 左右
*/
padding: 20px 30px;
/*
上下左右
*/
padding: 20px;
- 一些标签默认有padding
比如ul标签,有默认的padding-left值。
那么我们一般在做站的时候,是要清除页面标签中默认的padding和margin。以便于我们更好的去调整元素的位置。
我们现在初学可以使用通配符选择器
*{
padding:0;
margin:0;
}
但是,这种方法效率不高。
所以我们要使用并集选择器来选中页面中应有的标签(不同背,因为有人已经给咱们写好了这些清除默认的样式表,reset.css)
边框
border:边框的意思,描述盒子的边框
边框有三个要素: 粗细 线性样式 颜色
border: solid
如果颜色不写,默认是黑色。如果粗细不写,不显示边框。如果只写线性样式,默认的有上下左右 3px的宽度,实体样式,并且黑色的边框。
- 按照3要素来写border
border-width: 3px;
border-style: solid;
border-color: red;
/*
border-width: 5px 10px;
border-style: solid dotted double dashed;
border-color: red green yellow;
*/
- 按照方向划分
border-top-width: 10px;
border-top-color: red;
border-top-style: solid;
border-right-width: 10px;
border-right-color: red;
border-right-style: solid;
border-bottom-width: 10px;
border-bottom-color: red;
border-bottom-style: solid;
border-left-width: 10px;
border-left-color: red;
border-left-style:solid;
上面12条语句,相当于 bordr: 10px solid red;
另外还可以这样:
border-top: 10px solid red;
border-right: 10px solid red;
border-bottom: 10px solid red;
border-left: 10px solid red;
清除边框的默认样式,比如input输入框
border:none;
border:0;
- margin
margin:外边距的意思。表示边框到最近盒子的距离。(兄弟之间)
如果我们想要调节标签和标签之间的距离,那就调整margin即可。
/*表示四个方向的外边距离为20px*/
margin: 20px;
/*表示盒子向下移动了30px*/
margin-top: 30px;
/*表示盒子向右移动了50px*/
margin-left: 50px;
margin-bottom: 100px;
Javascript
JavaScript的组成
- ECMAScript 5.0
定义了js的语法标准: 包含变量 、表达式、运算符、函数、if语句 for循环 while循环、内置的函数
- DOM
操作网页上元素的API。比如让盒子显示隐藏、变色、动画 form表单验证
- BOM
操作浏览器部分功能的API。比如刷新页面、前进后退、让浏览器自动滚动
引入方式
- 内接式
<script type="text/javascript">
</script>
- 外接式
<!--相当于引入了某个模块-->
<script type="text/javascript" src = \'./index.js\'></script>
注释
#### 调试语句
- alert(\'\'); 弹出警告框
- console.log(\'\'); 控制台输出
#### 变量的声明
在js中使用var关键字 进行变量的声明,注意 分号作为一句代码的结束符
var a = 100;
#### 单行注释的快捷键ctrl+/.多行注释的快捷键是ctrl+shift+/\`\`\`
变量
"""
- 变量命名
- 数字、字母、下划线 $
- 变量名命名规范
- 驼峰式
- userName
dataOfUser
- 不能用关键字作为变量名
"""
保留字
bstract、boolean、byte、char、class、const、debugger、double、enum、export、extends、final、float、goto implements、import、int、interface、long、native、package、private、protected、public、short、static、super、synchronized、throws、transient、volatile
基本数据类型
JavaScript是一门拥有动态类型的语言。
-
数值类型
number
如果一个变量中,存放了数字,那么这个变量就是数值型的。
typeof查看当前变量的数据类型。
var a = 100; // 定义了一个变量a,并且赋值100
console.log(typeof a); // 输出a变量的类型 使用typeof函数 检测变量a的数据类型
// 特殊情况
var b = 5/0;
console.log(b); // Infinity 无限大
console.log(typeof b); // number 类型
// NaN是一个数字类型 但是不是一个数字
typeof NaN;
>>>"number"
// 类型转换
parseInt(); // 转为整型
parseFloat(); // 转为浮点型
parseInt("213");
>>>213
parseFloat("123.123")
>>>123.123
parseInt("123fanfjka"); // 开头为数字就能转换
>>>123
parseInt("afads21312"); // 开头为字符串报错 NaN
>>>NaN
在JavaScript中,只要是数,就是数值型(number)的。无论整数、浮点数(即小数)、无论大小、无论正负,都是number类型的。
-
字符串类型
String
var a = "abcde";
var b = "张三";
var c = "123123";
var d = "哈哈哈哈哈";
var e = ""; //空字符串
连字符和+号的区别
键盘上的+可能是连字符,也可能是数字的加号。如下:
console.log("我" + "爱" + "你"); //连字符,把三个独立的汉字,连接在一起了
console.log("我+爱+你"); //原样输出
console.log(1+2+3); //输出6
// 模板字符串(可以定义多行文本)
var ss = `
床前明月光,
疑是地上霜。
`;
typeof ss;
>>>"string"
// 模板字符串的作用 用于拼接字符串 接收变量
var name = \'张三\';
var age = 18;
var hobby = \'读书\';
// 书写${}会自动去前面找大括号内定义的变量的值
var sss = `my name is ${name}, my age is ${age}, my hobby is ${hobby}`;
// 如果前面未定义指定的变量 则报错
sss
>>>"my name is 张三, my age is 18, my hobby is 读书"
总结:如果加号两边都是数值,此时是加。否则,就是连字符(用来连接字符串)。
常用方法
| 方法 | 说明 | 对应Python中的方法 |
|---|---|---|
| .length | 返回长度 | len() |
| .trim() | 移除空白 | strip() |
| .trimLeft() | 移除左边的空白 | lstrip() |
| .trimRight() | 移除右边的空白 | rstrip() |
| .charAt(n) | 返回第n个字符 | |
| .concat(value, ...) | 拼接 | join() |
| .indexOf(substring, start) | 子序列位置 | |
| .substring(from, to) | 根据索引获取子序列 | []索引取值 |
| .slice(start, end) | 切片 | [::]索引切片 |
| .toLowerCase() | 小写 | lower() |
| .toUpperCase() | 大写 | upper() |
| .split(delimiter, limit) | 分割 | split() |
-
布尔类型
boolean
var isShow = false;
console.log(typeof b1);
// 布尔值为false
0 null undefined NaN
-
空对象
null
var c1 = null; // 空对象. object
console.log(typeof c1);
-
未定义
undefined
var d1; // 声明了变量,但是未赋值
// 表示变量未定义
console.log(typeof d1);
null表示变量的值是空(null可以手动清空一个变量的值,使得该变量变为object类型,值为null),undefined则表示只声明了变量,但还没有赋值。
对象
- 数组
数组对象的作用是:使用单独的变量名来存储一系列的值。
var a = [123, "ABCDEF"];
console.log(a[1]); // 输出“ABCDEF”
常用方法
| 方法 | 说明 |
|---|---|
| .length | 数组的大小 |
| .push(ele) | 尾部追加元素 |
| .pop() | 获取尾部的元素 |
| .unshift(ele) | 头部插入元素 |
| .shift() | 头部移除元素 |
| .slice(start, end) | 切片 |
| .reverse() | 反转 |
| .join(seq) | 将数组元素连接成字符串 |
| .concat(val, ...) | 连接数组 |
| .sort() | 排序 |
| .forEach() | 将数组的每个元素传递给回调函数 |
| .splice() | 删除元素,并向数组添加新元素。 |
| .map() | 返回一个数组元素调用函数处理后的值的新数组 |
Python中的map、zip、filter、reduce
# -*- coding: utf-8 -*-
# map 映射
l = [1, 2, 3, 4, 5]
res = map(lambda x: x ** 2, l)
print(list(res)) # [1, 4, 9, 16, 25]
# zip 拉链 一一对应 元组 输出长度以最短的为主
l1 = [1, 2, 3]
l2 = [\'张三\', \'李四\', \'王五\']
l3 = [18, 20, 21]
res2 = zip(l1, l2, l3)
print(list(res2)) # [(1, \'张三\', 18), (2, \'李四\', 20), (3, \'王五\', 21)]
# filter 过滤
l4 = [1, 2, 3, 4, 5, 6]
res3 = filter(lambda x:x > 3, l4)
"""
先for循环l4里面的元素赋值给x
通过lambda判断x是否>3
将>3的输出
"""
print(list(res3)) # [4, 5, 6]
# reduce
from functools import reduce
l5 = [1, 2, 3, 4, 5]
res4 = reduce(lambda x, y:x * y, l5) # 累乘
res5 = reduce(lambda x, y:x + y, l5) # 累加
res6 = reduce(lambda x, y:x + y, l5, 100) # 累加 起始值100
print(res4) # 120
print(res5) # 15
print(res6) # 115
concat()
数组的合并
var north = [\'北京\',\'山东\',\'天津\'];
var south = [\'东莞\',\'深圳\',\'上海\'];
var newCity = north.concat(south);
console.log(newCity) // ["北京", "山东", "天津", "东莞", "深圳", "上海"]
join()
将数组中元素使用指定的字符串连接起来,它会形成一个新的字符串
var score = [98,78,76,100,0];
var str = score.join(\'|\');
console.log(str); // "98|78|76|100|0"
slice(start,end)
返回数组的一段记录,顾头不顾尾
var arr = [\'张三\',\'李四\',\'王文\',\'赵六\'];
var newArr = arr.slice(1,3); // (起始位,删除的个数) 从1开始,往后删除2个
console.log(newArr); // ["李四", "王文"]
pop
移除数组的最后一个元素
var arr = [\'张三\',\'李四\',\'王文\',\'赵六\'];
arr.pop();
console.log(arr); // ["张三", "李四","王文"]
push()
向数组最后添加一个元素
var arr = [\'张三\',\'李四\',\'王文\',\'赵六\'];
arr.push(\'小马哥\');
console.log(arr); // ["张三", "李四","王文","赵六","小马哥"]
reverse()
翻转数组
var names = [\'张三\',\'李四\',\'王五\',\'赵六\'];
// 反转数组
names.reverse();
console.log(names);
sort
对数组排序
var names = [4,1,3,2];
names.sort();
console.log(names); // [1, 2, 3, 4]
isArray()
判断是否为数组
布尔类型值 = Array.isArray(被检测的值) ;
- 自定义对象
JavaScript的对象(Object)本质上是键值对的集合(Hash结构),但是只能用字符串作为键。
var temp = {"name":"张三", "age":18};
temp.name;
>>>"张三"
temp.age;
>>>18
遍历对象中的内容
for (let i in temp){
console.log(i, temp[i]);
}
>>> name 张三
>>> age 18
创建对象
new进行创建对象。
Object结构提供了“字符串--值”的对应,Map结构提供了“值--值”的对应,是一种更完善的Hash结构实现。
var person=new Object(); // 创建一个person对象
person.name="张三"; // person对象的name属性
person.age=18; // person对象的age属性
var m = new Map();
var o = {p: "Hello World"}
m.set(o, "content"}
m.get(o) // "content"
m.has(o) // true
m.delete(o) // true
m.has(o) // false
#### 运算符
* **算术运算符**
```javascript
var x=10;
var res1=x++; // 先用再加 输出10 x的值已经变为11
var res2=++x; // 先加再用 x的值变为11+1=12 输出12
res1;
10
res2;
12
// 这里由于的x++和++x在出现赋值运算式,x++会先赋值再进行自增1运算,而++x会先进行自增运算再赋值!
- 比较运算符
> >= < <= != == === !==
注:
1 == “1” // true 弱等于
1 === "1" // false 强等于
// 上面这张情况出现的原因在于JS是一门弱类型语言(会自动转换数据类型),所以当你用两个等号进行比较时,JS内部会自动先将
// 数值类型的1转换成字符串类型的1再进行比较,所以我们以后写JS涉及到比较时尽量用三等号来强制限制类型,防止判断错误
- 逻辑运算符
&& || !
- 赋值运算符
= += -= *= /=
流程控制
- if - else
var a = 10;
if (a > 5){
console.log("yes");
}else {
console.log("no");
}
- if - else if - else
var a = 10;
if (a > 5){
console.log("a > 5");
}else if (a < 5) {
console.log("a < 5");
}else {
console.log("a = 5");
}
- switch
var day = new Date().getDay();
switch (day) {
case 0:
console.log("Sunday");
break;
case 1:
console.log("Monday");
break;
default:
console.log("...")
}
- for循环
for (var i=0;i<10;i++) {
console.log(i);
}
- while循环
var i = 0;
while (i < 10) {
console.log(i);
i++;
}
三元运算
判断条件 ? 条件成立的返回值:条件不成立返回值
var a = 1;
var b = 2;
var c = a > b ? a : b
// 这里的三元运算顺序是先写 判断条件 a>b 再写条件成立返回的值为a,条件不成立返回的值为b;三元运算可以嵌套使用;
函数
- 基本格式
function(形参1, 形参2,...){
函数体代码
}
// 无参函数
function func1(){
console.log("Hello World!");
}
func1();
>>> Hello World!
// 有参函数 参数多传则只选择定义的几个参数 多传或少传不会报错
function func2(a, b){
console.log(a+b);
}
func2(1,9);
>>> 10
// 带返回值的函数
function sum(a, b){
return a + b;
}
sum(1, 2); // 调用函数
// 匿名函数方式
var sum = function(a, b){
return a + b;
}
sum(1, 2);
// 立即执行函数 书写立即执行的函数,首先先写两个括号()()这样防止书写混乱
(function(a, b){
return a + b;
})(1, 2);
Date对象
let d1 = new Date();
d1;
>>> Sat May 08 2021 16:47:38 GMT+0800 (中国标准时间)
d1.toLocaleString();
>>> "2021/5/8下午4:47:38"
//方法1:不指定参数
var d1 = new Date();
console.log(d1.toLocaleString());
//方法2:参数为日期字符串
var d2 = new Date("2004/3/20 11:12");
console.log(d2.toLocaleString());
var d3 = new Date("04/03/20 11:12");
console.log(d3.toLocaleString());
//方法3:参数为毫秒数
var d3 = new Date(5000);
console.log(d3.toLocaleString());
console.log(d3.toUTCString());
//方法4:参数为年月日小时分钟秒毫秒
var d4 = new Date(2004,2,20,11,12,0,300);
console.log(d4.toLocaleString()); //毫秒并不直接显示
Date对象的方法
var d = new Date();
//getDate() 获取日
//getDay () 获取星期
//getMonth () 获取月(0-11)
//getFullYear () 获取完整年份
//getYear () 获取年
//getHours () 获取小时
//getMinutes () 获取分钟
//getSeconds () 获取秒
//getMilliseconds () 获取毫秒
//getTime () 返回累计毫秒数(从1970/1/1午夜)
格式化输出日期案例
const WEEKMAP = {
0:"星期天",
1:"星期一",
2:"星期二",
3:"星期三",
4:"星期四",
5:"星期五",
6:"星期六"
}; // 定义一个数字与星期的对应关系对象
function showTime() {
var d1 = new Date();
var year = d1.getFullYear();
var month = d1.getMonth() + 1; //注意月份是从0~11
var day = d1.getDate();
var hour = d1.getHours();
var minute = d1.getMinutes() < 10?"0"+d1.getMinutes():d1.getMinutes(); //三元运算
var week = WEEKMAP[d1.getDay()]; //星期是从0~6
var strTime = `
${year}-${month}-${day} ${hour}:${minute} ${week}
`;
console.log(strTime)
};
showTime();
>>> 2021-5-8 16:52 星期六
详细的内置方法:https://www.w3school.com.cn/jsref/jsref_obj_date.asp
JSON对象
在python中序列化用dumps,反序列化用loads,主要是用于作前后端的交互。
在Javascript中也有序列化和反序列化,JSON.stringify(),JSON.parse()。
class JSONEncoder(object):
"""Extensible JSON <http://json.org> encoder for Python data structures.
Supports the following objects and types by default:
+-------------------+---------------+
| Python | JSON |
+===================+===============+
| dict | object |
+-------------------+---------------+
| list, tuple | array |
+-------------------+---------------+
| str | string |
+-------------------+---------------+
| int, float | number |
+-------------------+---------------+
| True | true |
+-------------------+---------------+
| False | false |
+-------------------+---------------+
| None | null |
+-------------------+---------------+
To extend this to recognize other objects, subclass and implement a
``.default()`` method with another method that returns a serializable
object for ``o`` if possible, otherwise it should call the superclass
implementation (to raise ``TypeError``).
"""
var str1 = \'{"name": "Alex", "age": 18}\';
var obj1 = {"name": "Alex", "age": 18};
// JSON字符串转换成对象 相当于python的loads
var obj = JSON.parse(str1);
// 对象转换成JSON字符串 相当于python的dumps
var str = JSON.stringify(obj1);
Math对象
"""
abs(x) 返回数的绝对值。
exp(x) 返回 e 的指数。
floor(x) 对数进行下舍入。
log(x) 返回数的自然对数(底为e)。
max(x,y) 返回 x 和 y 中的最高值。
min(x,y) 返回 x 和 y 中的最低值。
pow(x,y) 返回 x 的 y 次幂。
random() 返回 0 ~ 1 之间的随机数。
round(x) 把数四舍五入为最接近的整数。
sin(x) 返回数的正弦。
sqrt(x) 返回数的平方根。
tan(x) 返回角的正切。
"""
client、offset、scroll系列
他们的作用主要与计算盒模型、盒子的偏移量和滚动有关
clientTop 内容区域到边框顶部的距离 ,说白了,就是边框的高度
clientLeft 内容区域到边框左部的距离,说白了就是边框的乱度
clientWidth 内容区域+左右padding 可视宽度
clientHeight 内容区域+ 上下padding 可视高度
- client演示
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
.box{
width: 200px;
height: 200px;
position: absolute;
border: 10px solid red;
/*margin: 10px 0px 0px 0px;*/
padding: 80px;
}
</style>
</head>
<body>
<div class="box">
床前明月光,疑是地上霜。
举头望明月,低头思故乡。
</div>
</body>
<script type="text/javascript">
/*
* clientTop 内容区域到边框顶部的距离 ,说白了,就是边框的高度
* clientLeft 内容区域到边框左部的距离,说白了就是边框的乱度
* clientWidth 内容区域+左右padding 可视宽度
* clientHeight 内容区域+ 上下padding 可视高度
* */
var oBox = document.getElementsByClassName(\'box\')[0];
console.log(oBox.clientTop);
console.log(oBox.clientLeft);
console.log(oBox.clientWidth);
console.log(oBox.clientHeight);
</script>
</html>
- 屏幕的可视区域
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
</body>
<script type="text/javascript">
// 屏幕的可视区域
window.onload = function(){
// document.documentElement 获取的是html标签
console.log(document.documentElement.clientWidth);
console.log(document.documentElement.clientHeight);
// 窗口大小发生变化时,会调用此方法
window.onresize = function(){
console.log(document.documentElement.clientWidth);
console.log(document.documentElement.clientHeight);
}
}
</script>
</html>
- offset演示
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
</style>
</head>
<body style="height: 2000px">
<div>
<div class="wrap" style=" width: 300px;height: 300px;background-color: green">
<div id="box" style="width: 200px;height: 200px;border: 5px solid red;position: absolute;top:50px;left: 30px;">
</div>
</div>
</div>
</body>
<script type="text/javascript">
window.onload = function(){
var box = document.getElementById(\'box\')
/*
offsetWidth占位宽 内容+padding+border
offsetHeight占位高
offsetTop: 如果盒子没有设置定位 到body的顶部的距离,如果盒子设置定位,那么是以父辈为基准的top值
offsetLeft: 如果盒子没有设置定位 到body的左部的距离,如果盒子设置定位,那么是以父辈为基准的left值
* */
console.log(box.offsetTop)
console.log(box.offsetLeft)
console.log(box.offsetWidth)
console.log(box.offsetHeight)
}
</script>
</html>
- scroll演示
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{padding: 0;margin: 0;}
</style>
</head>
<body style="width: 2000px;height: 2000px;">
<div style="height: 200px;background-color: red;"></div>
<div style="height: 200px;background-color: green;"></div>
<div style="height: 200px;background-color: yellow;"></div>
<div style="height: 200px;background-color: blue;"></div>
<div style="height: 200px;background-color: gray;"></div>
<div id = \'scroll\' style="width: 200px;height: 200px;border: 1px solid red;overflow: auto;padding: 10px;margin: 5px 0px 0px 0px;">
<p>
床前明月光,疑是地上霜。
举头望明月,低头思故乡。
</p>
</div>
</body>
<script type="text/javascript">
window.onload = function(){
//实施监听滚动事件
window.onscroll = function(){
// console.log(1111)
// console.log(\'上\'+document.documentElement.scrollTop)
// console.log(\'左\'+document.documentElement.scrollLeft)
// console.log(\'宽\'+document.documentElement.scrollWidth)
// console.log(\'高\'+document.documentElement.scrollHeight)
}
var s = document.getElementById(\'scroll\');
s.onscroll = function(){
// scrollHeight : 内容的高度+padding 不包含边框
console.log(\'上\'+s.scrollTop)
console.log(\'左\'+s.scrollLeft)
console.log(\'宽\'+s.scrollWidth)
console.log(\'高\'+s.scrollHeight)
}
}
</script>
</html>
BOM与DOM操作
"""
- BOM
- 浏览器对象模型(Browser Object Model)
- js代码操作浏览器
- DOM
- 文档对象模型(Document Object Model)
- js代码操作标签
"""
BOM操作
"""
- window对象
- 指代的就是浏览器
"""
# 当前浏览器窗口的高度
window.innerHeight
# 当前浏览器窗口的宽度
window.innerWidth
# 打开高度为800px,宽度为800px的网址
window.open(url,target)
window.open("https://mzitu.com",\'\',\'height=800px, width=800px\')
"""
url:要打开的地址。
target:新窗口的位置。可以是:_blank 、_self、 _parent 父框架。
第二个参数写空即可,第三个参数写页面打开的位置
"""
# 关闭网页
window.close()
- window子对象
# 拿到当前浏览器名称
window.navigator.appName
""""
Netscape
""""
# 拿到当前浏览器版本
window.navigator.appVersion
""""
5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36
""""
# 标识当前是否是一个浏览器
window.navigator.userAgent
""""
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36
""""
# 浏览器支持的系统
window.navigator.platform
"""
Win32
"""
- history对象
# 回退到上一页
window.history.back()
# 前进到下一页
window.history.forward()
- location对象
# 拿到当前页面的相关信息
window.location
# 拿到当前页面的url
window.location.href
"""
https://cn.bing.com/
"""
# 页面跳转到指定的url
window.location.href = url
# 重新加载当前页面
window.location.reload()
-
弹框
-
警告框
alert(\'这是一个警告框!\')
- 确认框
confirm(\'这是一个确认框,请确认!\')
// 返回true(确认) false(取消)
- 提示框
prompt(\'继续前进?\',\'这是默认消息框内容\')
// 确认(返回用户在输入框的内容)
-
计时器相关
-
过几秒之后触发(一次性):setTimeout()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width-device-width, initial-scale=1">
</head>
<body>
<script>
function func1(){
alert(123)
}
setTimeout(func1, 3000) // 单位:ms 3秒后自动执行func1函数
</script>
</body>
</html>
取消定时任务
<script>
function func1(){
alert(123)
}
let t = setTimeout(func1, 3000) // 单位:ms 3秒后自动执行func1函数
clearTimeout(t) // 取消定时任务
</script>
- 每隔几秒触发(周期性):setInterval()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width-device-width, initial-scale=1">
</head>
<body>
<script>
function func2() {
alert(123)
}
setInterval(func2, 3000) // 单位:ms 循环自动执行func2函数
</script>
</body>
</html>
取消定时任务
<script>
function func2() {
alert(123)
}
function show(){
let t = setInterval(func2, 3000) // 单位:ms 循环自动执行func2函数
function inner() {
clearInterval(t)
}
setTimeout(inner, 9000)
}
show() // 弹框三次后不再弹框
</script>
DOM操作
需要用关键字:document开头
- DOM树
- 元素节点:HTML标签。
- 文本节点:标签中的文字(比如标签之间的空格、换行)
- 属性节点::标签的属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>div上面的div</div>
<div>div上面的div</div>
<div id="d1">div
<div>div>div</div>
<p class="c1">div>p
<span>
div>p>span
</span>
</p>
<p>
div>p
</p></div>
<div>div下面的div</div>
<div>div下面的div</div>
</body>
</html>
- 查找标签
直接查找
"""
- id查找
- document.getElementById("d1")
- 类查找
- document.getElementsByClassName("c1")
- 返回多个标签对象(数组)
- 标签查找
- document.getElementsByTagName("div")
- 返回数组对象
- document.getElementsByTagName("div")[0]
- 返回标签树
"""
注意:
"""
- 用变量名指代标签对象的时候,变量名的书写格式:xxxEle
- 如:divEle aEle pEle
"""
间接查找
let pEle = document.getElementsByClassName(\'c1\')[0]
pEle.parentElement // 获取父标签
let divEle = document.getElementById(\'d1\')
divEle.children // 获取子标签
divEle.firstElementChild // 获取大儿子标签
divEle.lastElementChild // 获取小儿子标签
- 节点操作
创建节点
新的标签(元素节点) = document.createElement("标签名");
<script type="text/javascript">
var a1 = document.createElement("li"); //创建一个li标签
var a2 = document.createElement("adbc"); //创建一个不存在的标签
console.log(a1);
console.log(a2);
console.log(typeof a1);
console.log(typeof a2);
</script>
插入节点
父节点.appendChild(新的子节点); // 父节点的最后插入新的子节点 标签内部添加元素 尾部追加
父节点.insertBefore(新的子节点,作为参考的子节点);
删除节点
父节点.removeChild(子节点); // 用父节点删除子节点
node1.parentNode.removeChild(node1); // 删除当前的节点
- 获取值操作
inputEle.value
// 获取用户数据标签内部的数据
let inputEle = document.getElementById("d1")
undefined
inputEle.innerText // 获取的是标签的默认文本
>>>""
inputEle.value // 实时获取输入的内容
>>>"hahah "
// 如何获取用户上传的文件数据
fileEle.files
>>>FileList {0: File, length: 1}
fileEle.files[0]
>>>File {name: "info.md", lastModified: 1619704874077, lastModifiedDate: Thu Apr 29 2021 22:01:14 GMT+0800 (中国标准时间), webkitRelativePath: "", size: 6219, …}
- class和css操作
let divEle = document.getElementById(\'d1\')
undefined
divEle.classList // 获取标签所有的类属性
DOMTokenList(3) ["c1", "bg_red", "bg_green", value: "c1 bg_red bg_green"]
divEle.classList.remove(\'bg_red\') // 移除某个类属性
undefined
divEle.classList.add(\'bg_red\') // 添加类属性
undefined
divEle.classList.contains(\'c1\') // 验证是否包含某个类属性
true
divEle.classList.contains(\'c2\')
false
divEle.classList.toggle(\'bg_red\') // 有则删除 无则添加
false
divEle.classList.toggle(\'bg_red\')
true
divEle.classList.toggle(\'bg_red\')
false
divEle.classList.toggle(\'bg_red\')
true
divEle.classList.toggle(\'bg_red\')
false
divEle.classList.toggle(\'bg_red\')
true
// DOM操作操作标签样式 统一先用style起手
let pEle = document.getElementsByTagName(\'p\')[0]
undefined
pEle.style.color = \'red\'
"red"
pEle.style.fontSize = \'28px\'
"28px"
pEle.style.backgroundColor = \'yellow\'
"yellow"
pEle.style.border = \'3px solid red\'
"3px solid red"
- 事件
"""
- 什么是事件
- 符合或达到某个事先设定的条件 自动触发的动作
"""
# 绑定事件的两种方式
<button onclick="func1()">点我</button>
<button id="d1">点我</button>
<script>
// 第一种绑定事件的方式
function func1() {
alert(111)
}
// 第二种
let btnEle = document.getElementById(\'d1\');
btnEle.onclick = function () {
alert(222)
}
</script>
"""
script标签既可以放在head内 也可以放在body内
但是通常情况下都是放在body内的最底部
# 等待浏览器窗口加载完毕之后再执行代码
window.onload = function () {
// 第一种绑定事件的方式
function func1() {
alert(111)
}
// 第二种
let btnEle = document.getElementById(\'d1\');
btnEle.onclick = function () {
alert(222)
}
}
"""
案例
- 开关灯
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.c1 {
height: 200px;
width: 200px;
border-radius: 50%;
}
.bg_green {
background-color: green;
}
.bg_red {
background-color: red;
}
</style>
</head>
<body>
<div id="d1" class="c1 bg_red bg_green"></div>
<button id="d2">变色</button>
<script>
let btnEle = document.getElementById(\'d2\')
let divEle = document.getElementById(\'d1\')
btnEle.onclick = function () { // 绑定点击事件
// 动态的修改div标签的类属性
divEle.classList.toggle(\'bg_red\')
}
</script>
</body>
</html>
- input框获取焦点及失去焦点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="text" value="这是一个默认的文本内容" id="d1">
<script>
let iEle = document.getElementById(\'d1\')
// 获取焦点事件
iEle.onfocus = function () {
// 将input框内部值去除
iEle.value = \'\'
// 点value就是获取 等号赋值就是设置
}
// 失去焦点事件
iEle.onblur = function () {
// 给input标签重写赋值
iEle.value = \'失去焦点事件的输出内容\'
}
</script>
</body>
</html>
- 实时显示当前时间
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="text" id="d1" style="display: block;height: 50px;width: 200px">
<button id="d2">开始</button>
<button id="d3">结束</button>
<script>
// 先定义一个全局存储定时器的变量
let t = null
let inputEle = document.getElementById(\'d1\')
let startBtnEle = document.getElementById(\'d2\')
let endBtnEle = document.getElementById(\'d3\')
// 1 访问页面之后 将访问的时间展示到input框中
// 2 动态展示当前时间
// 3 页面上加两个按钮 一个开始 一个结束
function showTime() {
let currentTime = new Date();
inputEle.value = currentTime.toLocaleString() // 获取当前时间
}
startBtnEle.onclick = function () {
// 限制定时器只能开一个
if(!t){
t = setInterval(showTime,1000) // 每点击一次就会开设一个定时器 而t只指代最后一个
}
}
endBtnEle.onclick = function () {
clearInterval(t)
// 还应该将t重置为空
t = null
}
</script>
</body>
</html>
- 省市联动
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<select name="" id="d1">
<option value="" selected disabled>--请选择--</option>
</select>
<select name="" id="d2"></select>
<script>
let proEle = document.getElementById(\'d1\')
let cityEle = document.getElementById(\'d2\')
// 先模拟省市数据
data = {
"河北": ["廊坊", "邯郸",\'唐山\'],
"北京": ["朝阳区", "海淀区",\'昌平区\'],
"山东": ["威海市", "烟台市",\'临沂市\'],
\'上海\':[\'浦东新区\',\'静安区\',\'黄浦区\'],
\'深圳\':[\'南山区\',\'宝安区\',\'福田区\']
};
// 选for循环获取省
for(let key in data){
// 将省信息做成一个个option标签 添加到第一个select框中
// 1 创建option标签
let opEle = document.createElement(\'option\')
// 2 设置文本
opEle.innerText = key
// 3 设置value
opEle.value = key // <option value="省">省</option>
// 4 将创建好的option标签添加到第一个select中
proEle.appendChild(opEle)
}
// 文本域变化事件 change事件
proEle.onchange = function () {
// 先获取到用户选择的省
let currentPro = proEle.value
// 获取对应的市信息
let currentCityList = data[currentPro]
// 清空市select中所有的option
cityEle.innerHTML = \'\'
// 自己加一个请选择
let ss = "<option disabled selected>请选择</option>"
// let oppEle = document.createElement(\'option\')
// oppEle.innerText = \'请选择\'
// oppEle.setAttribute(\'selected\',\'selected\')
cityEle.innerHTML = ss
// for循环所有的市 渲染到第二个select中
for (let i=0;i<currentCityList.length;i++){
let currentCity = currentCityList[i]
// 1 创建option标签
let opEle = document.createElement(\'option\')
// 2 设置文本
opEle.innerText = currentCity
// 3 设置value
opEle.value = currentCity // <option value="省">省</option>
// 4 将创建好的option标签添加到第一个select中
cityEle.appendChild(opEle)
}
}
</script>
</body>
</html>