HTML5学习笔记

01.标签之标题

标签是通过

来实现的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1></h1>
    <h2></h2>
    <h3></h3>
    <h4></h4>
    <h5></h5>
    <h6></h6>
</body>
</html>

快速生成h1—h6快捷键:h$*6


02.标签之段落,换行,水平线

<p>标签:段落标签,用于文本展示

<p>我是<br/>段落标签</p>

<br/>标签:换行标签,单标签

<p>我是<br/>段落标签</p>

<hr>标签:水平线,单标签

<hr color="red" width="300px" size="10px" align="left">

属性:

  1. color:设置水平线的颜色
  2. width:设置水平线的宽度
  3. size:高度
  4. align:设置对齐方式,默认居中,可取 left | right

实时效果:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <p>我是<br />段落标签</p>
    <hr color="red" width="300px" size="10px" align="left">
    <p>我是<br />段落标签</p>
</body>

</html>

image-20220928230924506


03.标签之图片

<img>单标签,用于图片处理

<img src="图片路径">

属性:

  1. src:路径
  2. alt:规定图像的代替文本
  3. width:宽度
  4. height:高度
  5. title:鼠标悬停图片时提示

实时效果:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <img src="img/xjj.jpeg" alt="小姐姐" width="10%" title="美丽小姐姐">
</body>

</html>

image-20220928231907106


04.图片路径详解

绝对路径:图片在计算机的位置,如:“D:\文档\前端工作台\Test\img\xjj.jpeg”

相对路径:

  1. 子级关系:/
  2. 父级关系:…/
  3. 同级关系:./(可省略)

网络路径:http://2z8.cn/FNDRW


05.标签之超文本链接

<a>实现超文本链接:

<a href="url">链接文本<a/>

属性:

  1. 未访问的链接显示为蓝色带下划线
  2. 访问过的链接显示为紫色带下划线
  3. 点击链接时,链接显示为红色带下划线

06.标签之文本
标签 描述
<em> 定义着重文字
<b> 定义粗体文字
<i> 斜体
<strong> 加重语气
<del> 删除字
<span> 无特定含义

特别提醒

常用文本标签和段落是不同的,段落代表一段文本,而文本标签一般表示文本词汇

<p>p白菜</p>
<i>i白菜</i>
<strong>strong白菜</strong>
<span>span白菜</span>
<del>del白菜</del>

image-20220928235020627


07.标签之列表
1. 有序列表:
<ol type="1">
    <li>白菜</li>
    <li>萝卜</li>
</ol>
<ol type="a">
    <li>白菜</li>
    <li>萝卜</li>
</ol>
<ol type="A">
    <li>白菜</li>
    <li>萝卜</li>
</ol>
<ol type="i">
    <li>白菜</li>
    <li>萝卜</li>
</ol>
<ol type="I">
    <li>白菜</li>
    <li>萝卜</li>
</ol>
image-20220929000025890

<ol>的属性type具有的选项:

  1. 1 数字标识
  2. a 小写字母标识
  3. A 大写字母标识
  4. i 小写罗马数字标识
  5. I  大写罗马数字标识

列表的嵌套使用

<ol type="1">
        <li>蔬菜
            <ol type="a">
                <li>白菜</li>
                <li>萝卜</li>
            </ol>
        </li>
        <li>水果</li>
    </ol>

image-20220929001408018

2. 无序列表:

快速生成ul+li的布局:ul>li*n (n为产生的li的数量)

		<li type="circle">白菜</li>
        <li type="square">萝卜</li>
        <li type="none">萝卜</li>
        <li type="disc">萝卜</li><!--默认实心圆 -->

image-20220929102910875

type属性:

  • disc默认实心圆
  • circle空心圆
  • square小方块
  • none不显示

同有序列表一样,无序列表也可进行嵌套

常见应用场景

  • 导航效果(导航栏)

###### 3.自定义列表:

自定义列表不仅仅是一列项目,而是项目及其注释的组合。

自定义列表以

标签开始。每个自定义列表项以
开始。每个自定义列表项的定义以
开始

<dl>
<dt>Coffee</dt>
<dd>- black hot drink</dd>
<dt>Milk</dt>
<dd>- white cold drink</dd>
</dl>
//浏览器显示
Coffee
- black hot drink
Milk
- white cold drink
08.标签之表格

表:<table>

行:<tr>

列:<td>

快捷键:tabel>tr*2>td*2{单元格内容}

<table border="2px">
        <tr>
            <td>白菜</td>
            <td>白菜</td>
        </tr>
        <tr>
            <td>白菜</td>
            <td>白菜</td>
        </tr>
        <tr>
            <td>白菜</td>
            <td>白菜</td>
        </tr>
    </table>
表格单元格合并
  • 水平合并:colspan
  • 垂直合并:rowspan
<table border="2px" width="200px">
        <tr>
            <td colspan="2">白菜1 白菜2</td>
            <!-- <td>白菜2</td> -->
        </tr>
        <tr>
            <td>白菜3</td>
            <td rowspan="2">白菜4 白菜6</td>
        </tr>
        <tr>
            <td>白菜5</td>
            <!-- <td>白菜6</td> -->
        </tr>
    </table>

image-20220929105212466

合并区域为方形时,以左上的单元格为基础

<table border="1">
        <tr>
            <td colspan="2" rowspan="2">白菜1</td>
            <!-- <td>白菜2</td> -->
            <td>白菜3</td>
        </tr>
        <tr>
            <!-- <td>白菜4</td> -->
            <!-- <td>白菜5</td> -->
            <td>白菜6</td>
        </tr>
        <tr>
            <td>白菜</td>
            <td>白菜</td>
            <td>白菜</td>
        </tr>
    </table>

image-20220929110128068


09.表单元素

表单:<form></form>

文本框:<input type="text">

密码框:<input type="password">

提交按钮:<input type="submit" value="显示文本">

<form>
        <input type="text">
        <input type="password"></input>
        <input type="submit">
    </form>

10.块元素和行级元素(内联元素)

常见的块级元素

div,form,h1~h6,hr,p,table,ul等

行内块级元素(特点:不换行,能够识别宽高)

button,img,input等

常见内联元素(行内元素)

a,b,em,i,span,strong等

块级元素 内联元素
块级元素在页面中独占一行(自上向下垂直排列) 行内元素不会独占页面中的一行,只占自身大小
可以设置width,height属性 行内设置width,height属性无效
一般块级元素可以包含行内元素和其他块级元素 一般内联元素包含内联元素,不包含块级元素

11.html5新增标签

<div>标签:页面中使用最多的标签

    <div id="header"></div>
    <div id="nav"></div>
    <div id="article">
        <div id="section"></div>
    </div>
    <div id="silder"></div>
    <div id="footer"></div>
    <!-- 使用H5新标签 -->
    <header></header>				<!-- 头部-->
    <nav></nav>						<!-- 导航-->
    <article>						<!-- 内容块-->
        <section></section>			<!-- 定义文档中的节(章节,页眉,页脚)-->
    </article>
    <aside></aside>					<!-- 侧边栏-->
    <footer></footer>				<!-- 脚部-->

CSS学习笔记

01.介绍

语法

CSS规则由两个主要的部分构成:选择器,以及一条或多条声明

image-20220929153600621

每条声明由一个属性和一个值组成

属性(property)是设置的样式属性(style attribute)。每个属性都有一个值。

<style>
    h1{
        color:red;
        font-size:12px;
    }
</style>
02.CSS的引入方式

内联样式

<p style="background:red;font-size:12px;"></p>

特点:

缺乏整体性和规划性,不利于维护,维护成本高

内部样式

当单个文档需要特殊的样式时,就应该使用内部样式表。你可以使用<stye> 标签在文档头部定义内部样式表

<head>
    <style>
        h1{
            background:red;
        }
    </style>
</head>

特点:

单个页面内的CSS代码具有统一-性和规划性, 便于维护,但是在多个页面之间容易混乱

外部样式(推荐)

当样式需要应用于很多页面时,外部样式表将是理想的选择。在使用外部样式表的情况下,你可以通过改变一
个文件来改变整个站点的外观。每个页面使用<link> 标签链接到样式表。<link> 标签在(文档的)头部

<link rel="stylesheet" type="text/css" href="url">
03.选择器

全局选择器

可以与任何元素匹配,优先级最低,一般做样式初始化

*{
	margin: 0;
	padding: 0;
}

元素选择器

HTML文档中的元素,p,b,div,a,img,body

标签选择器,选择的是页面上所有这种类型的标签,所以经常描述”共性”,无法描述某一个元素的“个性”

p{
	font-size:12px;
}
  • 所有的标签都可以是选择器。比如ul,li,lable,dt,dl等
  • 选择的是所有

类选择器

.来定义

<h2 class="one">你好</h2>
.one{
	width:800px;
}
  • 类选择器可以被多种标签使用
  • 类名不能以数字开头
  • 同一个标签可以使用多个类选择器。用空格隔开
<h3 class="classone classtwo"></h3>

ID选择器

针对某一个特定的标签来使用,只能使用一次。css中的ID选择器以#来定义

<h2 id="myside"></h2>
#myside{
    border:3px dashed green;
}

id是唯一的

id不能以数字开头

合并选择器

.header,.footer{
	height:200px;
}

选择器的优先级:

优先级从高到低:行内样式> ID选择器>类选择器>元素选择器

04.字体属性

CSS字体属性定义字体,颜色,大小,加粗,文字样式

color:颜色

div{*color:red;}
div{ color:#ff0000;}
div{ color:rgb(255,0,0);}
div{ color:rgba(255,0,0,0.5);}

font-size:字体大小

h1 {font-size:12px}

font-weight:设置文本的粗细

描述
bold 粗体字符
bolder 更粗的字符
lighter 更细的字符
100~900 粗细程度(400默认,700等同bolder)
H1 {font-weight:normal;}
div {font-weight:bolder;}
p {font-weight:900;}

font-style:指定文本的字体样式

描述
normal 默认值
italic 斜体

font-family:属性指定一个元素的字体

每个值用逗号分开

如果字体名称包含空格,它必须加上引号

font-family:"Microsoft YaHei","Simsun";
05.背景属性

CSS背景属性主要有以下几个

属性 描述
background-color 设置背景颜色
background-image 设置背景图片
background-position 设置背景图片显示位置
background-repeat 设置背景图片如何填充
background-size 设置背景图片大小属性

background-color属性

<div class="box"></div>
.box{
    width:300px;
    height:300px;
    background-color:red;
}

background-image属性

元素的背景是元素的总大小,包括填充和边界(不包括外边距)。默认情况下background-image属性放置在元素的左上角,如果图像不够大的话会在垂直方向和水平方向平铺图像,如果图像大小超过元素的大小,从图像的左上角显示元素的大小的那部分

<div class="box"></div>
.box{
    width:300px;
    height:300px;
    background-img:url("img/im1.jpg");
}

background-repeat属性

说明
repeat 默认值
repeat-x 只向水平方向平铺
repeat-y 只向垂直方向平铺
no-repeat 不平铺
<div class="box"></div>
.box{
    width:300px;
    height:300px;
    background-img:url("img/im1.jpg");
    background-repeat:no-repeat;
}

background-size属性

说明
length 设置图片的宽度和高度,第一个为宽,第二个为高,单设一个,第二个自动
percentage 计算相对位置区域的百分比,第一个为宽,第二个为高,单设一个,第二个自动
cover 保持图片纵横比并将图片完全覆盖所属元素
contain 保持图片纵横比并将图片缩放/放大直到图像能完整显示出来,并适应所在区域的宽高
<div class="box"></div>
.box{
    width:300px;
    height:300px;
    background-img:url("img/im1.jpg");
    background-repeat:no-repeat;
    background-size: contain;
}

background-position属性

设置图像的起始位置,其默认值是0% 0%

说明
left top 左上角
left center 左中
left bottom 左下
right top 右上角
right center 右中
right bottom 右下
center top 中上
center center 中中
center bottom 中下
x% y% 左上角是0%,右下角是100%,若只指定了一个值,其他默认值为50%,默认为0% 0%
xpos ypos 单位是像素(px)
<div class="box"></div> 
 .box {
        width: 400px;
        height: 400px;
        background-color: red;
        background-image: url(img/1.webp);
        background-repeat: no-repeat;
        background-position: right center;
  }
06.文本属性

text-align

指定元素文本的水平对齐方式

描述
left 文本居左对齐,默认值
right 把文本排列在右边
center 把文本排列在中间
h1{text-align:center;}

text-decoration

text-decoration属性规定添加到文本的修饰,下划线,上划线,删除线等等

描述
underline 下划线
overline 上划线
line-through 删除线
h1{text-decoration:overline}

text-transform

text-transform控制文本的大小写

描述
capitalize 每个单词开头大写
uppercase 全部大写
lowercase 全部小写
h1{text-transform:lowercase;}

text-indent

text-indent定义首行缩进

p{
 text-indent:50px;
}

负值是允许的,若为负值,将第一行左缩进


07.表格属性

表格边框

指定CSS表格边框,使用border属性

table ,td{	//加了td出现内边框,不加则只有整体的的边框
	border:1px solid black;	//大小,实线,颜色
}

折叠边框

border-collapse属性设置表格的边框是否被折叠成一一个单一 的边框或隔开

table {
	border-collapse:collapse;
}
table ,td{
	border:1px solid black;
}

表格宽度与高度

width和height属性定义表格的宽度和高度

table{
	width:20px;
	height:10px;
}

表格文字对齐

表格文字的水平对齐和垂直对齐

text-align属性设置水平对齐方式,向左,右,中心

td{text-align:center;}

vertical-align属性设置垂直对齐方式,向上(top),向下(bottom)

td{height:50px; vertical-align:bottom}

表格填充

如果在表的内容中控制空格之间的边框, 应使用td和th元素的填充属性,padding表格内边距

td{padding:15px;}

表格颜色

tabel,td,th{
	border:1px solid green;
}
td{
	background-color:green:
	color:white;//表格内字体颜色
}
08.关系选择器

关系选择器分类:

  1. 后代选择器
  2. 子代选择器
  3. 相邻兄弟选择器
  4. 通用兄弟选择器

后代选择器

定义:选择所有被E元素包含的F元素

<ul>
        <li></li>
        <li></li>
        <li></li>
 </ul>
ul li{
            color: #000;
   }

子代选择器

定义:选择所有作为E元素的直接子元素F,对更深一层的元素不起作用,用>表示

<div>
        <a href="#">子元素</a>
        <P><a href="#">孙元素</a></P>
        <a href="#">子元素</a>
    </div>
div>a{
            color: red;
  }

相邻兄弟选择器

定义:选择紧跟E元素后的F元素,用加号表示,选择相邻的第一个兄弟元素

  • 只能对其后面相邻的元素生效,对前面相邻的不生效

  • 只能对F元素生效,E不生效

	<h1>h1元素</h1>    
    <p>第一个元素</p>
    <p>第二个元素</p>
h1+p{
            color: red;
        }

通用兄弟选择器

定义:选择E元素之后的所有兄弟元素F,作用于多个元素,用~隔开

只能对其后面所有的F元素生效,对前面元素的不生效

	<h1>h1元素</h1>    
    <p>第一个元素</p>
    <p>第二个元素</p>
h1~p{
            color: red;
        }
09.CSS盒子模型(Box Model)

概念

​ 所有HTML元素可以看作盒子,在CSS中,"box model"这-术语是用来设计和布局时使用

​ CSS盒模型本质上是一个子封装周围的HTML元素,它包括:外边距(margin) ,边框(border) ,内边距(padding) ,和实际内容(content)

image-20220928231907106

  • margin(外边距)-清除边框外的区域,外边框是透明的
  • border(边框)-围绕在内边距和内容外的边框
  • padding(内边框)-清除内容周围的区域(两个值:第-一个值上下,第二个值左右)
  • content(内容)-盒子的内容,显示文本和图像
10.弹性盒子模型(flex box)

定义

弹性盒子是CSS3的一种新的布局模式
CSS3弹性盒是-种当页面需要适应不同的屏幕大小以及设备类型时确保元素拥有恰当的行为的布局方式
引入弹性盒布局模型的目的是提供-种更加有效的方式来对一 个容器中的子元素进行排列、对齐和分配空白空间

CSS3弹性盒内容

弹性盒子由弹性容器(Flex container)和弹性子元素(Flex item)组成
弹性容器通过设置display 属性的值为flex 将其定义为弹性容器
弹性容器内包含了一个或多个弹性子元素

提示:

弹性容器外及弹性子元素内是正常渲染的。弹性盒子只定义了弹性子元素如何在弹性容器内布局

  • 默认弹性盒里的内容横向摆放
父元素上的属性

display:flex开启弹性盒

flex-direction属性指定了弹性子元素在父容器中的位置

flex-direction:row | row-reverse | column | column-reverse
  • row:横向从左到右排列(左对齐) .默认的排列方式
  • row-reverse:反转横向排列(右对齐,从后往前排,最后一项排在最前面
  • column:纵向排列
  • column-reverse:反转纵向排列,从后往前排,最后一项排在最上面
<div class="container">
        <div class="box1"></div>
        <div class="box2"></div>
        <div class="box3"></div>
    </div>
.container{
            width: 500px;
            height: 500px;
            background-color: red;
            display: flex; //开启弹性盒
            flex-direction: column;	//从默认的横向改为纵向
 }

justify-content属性(垂直方向)

定义:内容对挤(justify-content) 属性应用在弹性容器上,把弹性项沿着弹性容器的主轴线(main axis)对齐

justify-content: flex-start | flex-end | center
  • flex-start 弹性项目向行头紧挨着填充。这个是默认值。第一个弹性项的main-start外边距边线被放置在该行的main-start边线,而后续弹性项依次平齐摆放
  • flex-end弹性项目向行尾紧挨着填充。第一个弹性项的main-end外边距边线被放置在该行的main-end边
    线,而后续弹性项依次平齐摆放
  • center 弹性项目居中紧挨着填充。(如果剩余的自由空间是负的,则弹性项目将在两个方向上同时溢出)

总结:垂直方向上的上,下,中摆放

align-items属性(水平方向)

定义:align-items 设置或检索弹性盒子元素在侧轴(纵轴) 方向上的对齐方式

align-items: flex-start | flex-end | center
  • flex-start 弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴起始边界
  • flex-end 弹性盒子元素的侧轴(纵轴) 起始位置的边界紧靠住该行的侧轴结束边界
  • center 弹性盒子元素在该行的侧轴(纵轴). 上居中放置。 (如果该行的尺寸小于弹性 盒子元素的尺寸,则会向两个方向溢出相同的长度)
.container {
            width: 500px;
            height: 500px;
            background-color: red;
            display: flex; //开启弹性盒
            flex-direction: column;	//从默认的横向改为纵向
            justify-content: center;//垂直方向居中
            align-items:center;//水平方向居中
  }
子元素上的属性

flex-grow/flex

  • flex根据弹性盒子元素所设置的扩展因子作为比率来分配剩余空间
  • 默认为0,即如果存在剩余空间,也不放大
  • 如果只有一个子元素设置, 那么按扩展因子转化的百分比对其分配剩余空间。0.1即10%, 1即100%, 超出按100%
<div class="container">
        <div class="box1"></div>
        <div class="box2"></div>
        <div class="box3"></div>
    </div>
<style>
        .container {
            width: 500px;
            height: 500px;
            background-color: red;
            display: flex;
            flex-direction: row;
            justify-content: center;
            align-items:center;
        }

        .box1 {
            width: 100px;
            height: 100px;
            background-color: aqua;
            flex: 2; 
        }

        .box2 {
            width: 100px;
            height: 100px;
            background-color: green;
            flex: 2;
        }

        .box3 {
            width: 100px;
            height: 100px;
            background-color: black;
            flex: 1;
        }
    </style>

上述代码中将box1和box2的flex设置为2,box为1,则可将其看作2/5,2/5,1/5的比例

注:使用flex可能会改变原本的宽高(具体视其摆放方式而定)

image-20221024002328193
11.文档流

定义:文档流是文档中可显示对象在排列时所占用的位置/空间。例如:块元素自上而下摆放,内联元素,从左到右摆放。标准流里面的限制非常多,导致很多页面效果无法实现

  1. 高矮不齐,底边对齐
  2. 空白折叠现象
    • 无论多少个空格,换行,tab,都会折叠为一个空格
    • 如果我们想让img标签之间没有间隔,必须紧密相连

文档流产生的问题

高矮不齐,底边对齐

<body>
    <span>大课间活动及看完</span>
    <img src="./2.jpeg" alt="">
</body>
<style>
        img{
            width: 300px;
        }
    </style>
image-20221024225242865

空格折叠

<body>
    <span>大课间活动及看完</span>
    <img src="./2.jpeg" alt="">
    <p>大家好,我是      p标签</p>
</body>

image-20221024225452358

元素无空隙

<img src="./2.jpeg" alt=""><img src="./2.jpeg" alt="">
image-20221024225654509

推荐下面写法:

<img src="./2.jpeg" alt="">
<img src="./2.jpeg" alt="">
image-20221024225744121

解决上述问题的方法

脱离文档(文档)流

  1. 浮动
  2. 绝对定位
  3. 固定定位
12.浮动

浮动的定义:float属性定义在哪个方向浮动,任何元素都可以浮动。

描述
left 元素向左浮动
right 元素向右浮动

浮动的原理

  • 浮动以后使元素脱离了文档流
  • 浮动只有左右浮动,没有上下浮动

元素向左浮动

脱离文档流之后,元素相当于在页面上面增加一个浮层来放置内容。此时可以理解为有两层页面, 一层是底层的原页面,一层是脱离文档流的上层页面,所以会出现折叠现象。

image-20221024230648840

当容器不足时

image-20221024230919555

13.清除浮动

浮动的副作用

当元素设置float浮动后,该元素就会脱离文档流并向左/向右浮动,

  • 浮动元素会造成父元素高度塌陷
  • 后续元素会受到影响
 <div class="container">
        <div class="1"></div>
        <div class="2"></div>
        <div class="3"></div>
     	<p>你好</p>
    </div>
<style>
        .container {
            width: 500px;

            background-color: aqua;
        }

        .container div {
            width: 100px;
            height: 100px;
            background-color: red;
            margin: 5px;
            float: left;

        }
    </style>
image-20221024231737686

高度塌陷,父元素无高度

<div class="container">
        <div class="1"></div>
        <div class="2"></div>
        <div class="3"></div>
     	<p>你好</p>
    </div>
image-20221024231936523

影响后续元素


清除浮动

  • 父元素设置高度
  • 受影响的元素增加clear属性
  • overflow清除浮动
  • 伪对象方式

受影响的元素增加clear属性:

 <div class="container">
        <div class="1"></div>
        <div class="2"></div>
        <div class="3"></div>
        <p>你好</p>
    </div>
p{
            clear: left;
            background-color: blue;
        }
image-20221024232422644

overflow清除浮动(常用):

如果有父级塌陷,并且同级元素也收到了影响,可以使用overflow清除浮动
这种情况下,父布局不能设置高度,父级标签的样式里面加: overflowhiddenclear;

.container {
            width: 500px;
            background-color: aqua;
            overflow: hidden;
            clear: both;
        }
image-20221024232905428

父级元素适应子元素的高度

伪对象方式

如果有父级塌陷,并且同级元素也收到了影响,还可以使用伪对象方式处理,为父标签添加伪类after ,设置空的内容,并且使用clear:both;
这种情况下,父布局不能设置高度

.container::after {
            content: "";
            display: block;
            clear: both;
        }
14.定位

定义

position属性指定了元素的定位类型

描述
relative 相对定位
absolute 绝对定位
fixed 固定定位

其中,绝对定位和固定定位会脱离文档流

设置定位之后:可以使用四个方向的值进行调整位置:left,right,top,botton

相对定位

.box {
            width: 200px;
            height: 200px;
            background-color: red;
            position: relative;
            left: 200px;
            top:100px
        }
<div class="box"></div>
image-20221030134417514

绝对定位

可以使用绝对定位来做元素压盖(多层次)

<div class="box"></div>
    <div class="box1"></div>
    <div class="box2"></div>
 .box {
            width: 200px;
            height: 200px;
            background-color: red;
            position: absolute;
            left: 200px;
            top:100px
        }
        .box1{
            width: 300px;
            height: 300px;
            background-color: blue;
            
        }
 /* box2压盖box */
        .box2{
            width: 100px;
            height: 100px;
            background-color:black;
            position: absolute;
            top: 100px;
            left: 250px;
        }
image-20221030135154018

绝对定位与浮动不同,两者都是脱离了标准文档流,但是绝对定位有多层,浮动只有一层

固定定位

  1. 脱离文档流
  2. 固定位置,不随页面移动而改变(即始终处于显示器的某个位置)
<div class="box1"></div>
    <div class="box2"></div>
.box1 {
            width: 100px;
            height: 100px;
            background-color: red;
            position: fixed;
            left: 100px;
            top: 100px;
        }

        .box2 {
            width: 400px;
            height: 400px;
            background-color: aqua;
        }

温馨提示

设置定位之后,相对定位和绝对定位他是相对于具有定位的父级元素进行位置调整,如果父级元素不存在定位,则继续向上逐级寻找,直到顶层文档

<div class="box2">
        <div class="test"></div>
    </div>
 .box2 {
            width: 400px;
            height: 400px;
            background-color: aqua;
            /*父级无定位,则往上找,即body,相互对于body进行定位*/
          /* position: relative; */
            margin: 100px;
        }
        .test{
            width: 100px;
            height: 100px;
            background-color: red;
            position: absolute;
            left: 100px;
        }
image-20221030142338407
 .box2 {
            width: 400px;
            height: 400px;
            background-color: aqua;
     /* 父级有定位*/
        	position: relative; 
            margin: 100px;
        }
        .test{
            width: 100px;
            height: 100px;
            background-color: red;
            position: absolute;
            left: 100px;
        }
image-20221030142453899

总结:若小盒子想相对于父级盒子进行定位,则需要对父级添加定位(一般父级relative,子级absolute)

Z-index

z-index属性设置元素的堆叠顺序。拥有更高堆叠顺序的元素总是会处于堆叠顺序较低的元素的前面

<div class="box2"></div>
    <div class="test"></div>
.box2 {
            width: 400px;
            height: 400px;
            background-color: aqua;
            position: relative;
            /* z-index: 100; */
        }

        .test {
            width: 400px;
            height: 100px;
            background-color: red;
            position: absolute;
            top: 100px;
            left: 100px;
            /* z-index: 50; */
        }
image-20221030143658714
.box2 {
            width: 400px;
            height: 400px;
            background-color: aqua;
            position: relative;
            z-index: 100;
        }

        .test {
            width: 400px;
            height: 100px;
            background-color: red;
            position: absolute;
            top: 100px;
            left: 100px;
            z-index: 50;
        }
image-20221030143742069
15.CSS3的新特性

圆角

使用css3boder-radius属性,可以给任何元素制作“圆角”

  • 四个值:第一个值为左上角,第二个值为右上角,第三个值为右下角,第四个值为左下角
  • 三个值:第一个值为左上角,第二个值为右上角和左下角,第三个值为右下角
  • 两个值:第一个值为左上角与右下角,第二个值为右上角与左下角
  • 一个值:四个圆角值相同
<div class="box1"></div>
    <div class="box2"></div>
    <div class="box3"></div>
.box1 {
            width: 100px;
            height: 100px;
            background-color: red;
            border-radius: 10px;
        }

        .box2 {
            width: 100px;
            height: 100px;
            background-color: blue;
            border-radius: 100%;
        }

image-20221030144614636

阴影

box-shadow向边框添加一个或多个阴影

box-shadow:h-shadow v-shadow bulr color;
描述
h-shadow 必选,水平阴影的位置
v- shadow 必选,垂直阴影的位置
biur 可选,模糊距离
color 可选,阴影的颜色
<div class="box1"></div>
    <div class="box2"></div>
    <div class="box3"></div>
.box1 {
            width: 100px;
            height: 100px;
            background-color: red;
            border-radius: 10px;
            box-shadow: 3px 3px 10px rgba(0, 0, 0);
        }

        .box2 {
            width: 100px;
            height: 100px;
            background-color: blue;
            border-radius: 100%;
            box-shadow: 10px 10px 20px rgba(0,0,0);
        }

image-20221030145720671

16.动画

动画是使元素从一种样式逐渐变化为另-种样式的效果

您可以改变任意多的样式任意多的次数

请用百分比来规定变化发生的时间,或用关键词"from"和"to",等同于0%和100%

0%是动画的开始,100%是动画的完成。

@keyframes创建动画

使用@keyframes规则,可以创建动画

@keyframes name{
    from/0%{
		css样式
    }
    percent(百分之几){
    	css样式
    }
    to/100%{
    	css样式
    }
}

name:动画名称,开发人员自己命名;

percent:为百分比值,可以添加多个百分比值;

animation执行动画

animation:name duration timing-function delay iteration-count direction
描述
name 设置动画名称
duration 设置动画的持续时间
timing-function 设置动画的速率(如下)
delay 设置动画的开始时间(延时执行)
iteration-count 设置动画循环的次数,infinite为无限次
direction 设置动画播放的方向(如下)
animation-play-state 控制动画的播放状态:running(播放),paused(停止)
timing-function值 描述
ease 逐渐变慢(默认)
linear 匀速
ease-in 加速
ease-out 减速
ease-in-out 先加后减
direction值 描述
normal 默认值为normal表示向前播放
alternate 动画播放次数在偶数次向前播放,奇数次向反方向播放

代码演示

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {
            width: 200px;
            height: 200px;
            background-color: red;
            animation: slide 3s linear 0s infinite;
        }

        div:hover {
            /* background-color: green; */
            /* 鼠标放上面停止播放动画 */
            animation-play-state: paused;
        }
        @keyframes slide {
            0% {
                width: 200px;
                background-color: red;
            }
            50% {
                width: 400px;
                background-color: blue;
            }
            100% {
                width: 200px;
                background-color: green;
            }
        }
    </style>
</head>

<body>
    <div></div>
</body>

</html>

呼吸效果

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .box {
            width: 500px;
            height: 400px;
            margin: 40px auto;
            background-color: #2b92d4;
            border-radius: 5px;
            box-shadow: 0 1px 2px rgba(0, 0, 0, .3);
            animation: breath 1.5s ease-in-out infinite alternate;
        }

        @keyframes breath {
            0% {
                opacity: 0.2;
                box-shadow: 0 1px 2px rgba(255, 255, 255, 0.1);
            }

            50% {
                opacity: 0.5;
                box-shadow: 0 1px 2px rgba(18, 190, 84, 0.76);

            }

            100% {
                opacity: 1;
                box-shadow: 0 1px 2px rgba(59, 255, 255, 1);
            }
        }
    </style>
</head>

<body>
    <div class="box"></div>
</body>

</html>
17.媒体查询

媒体查询能使页面在不同在终端设备下达到不同的效果

媒体查询会根据设备的大小自动识别加载不同的样式

设置meta标签

使用设备的宽度作为视图宽度并禁止初始的缩放。在<chead>标签里加入这个meta标签。

<meta name="viewport" content="width=device-width, initial-scale=1.0,initial-scale=1,maximun-scale=1,user-scalable=no">

参数解释

  1. width=device-width宽度等于当前设备的宽度
  2. initial-scale初始的缩放比例(默认为1.0)
  3. maximun-scale允许用户缩放到的最大比例(默认1.0)
  4. user-scalable用户是否可以手动缩放(默认为no)
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .box {
            width: 300px;
            height: 300px;
        }

        /*屏幕宽度小于768时  */
        @media screen and (max-width:768px) {
            .box {
                background-color: aqua;
            }

            .p1,
            .p2 {
                display: none;
            }
        }

        /* 屏幕宽度在768和996间 */
        @media screen and (min-width:768px) and (max-width:996px) {
            .box {
                background-color: black;
            }

            .p1 {
                display: none;
            }
        }

        @media screen and (min-width:996px) {
            .box {
                background-color: red;
            }
        }
    </style>
</head>

<body>
    <div class="box"></div>
    <p class="p1">hhhh</p>
    <p class="p2">xxxxxx</p>
</body>

</html>
18.雪碧图

CSS Sprite也叫CSS精灵图、CSS雪碧图, 是一种网页图片应用处理方式。它允许你将一个页面涉及到的所有零星图片都包含到一张大图中去

优点:

  • 减少图片的字节
  • 减少网页的http请求,从而大大的提升页面的性能

原理:

  • 通过background-image引入背景图片
  • 通过background-position把背景图片移动到自己需要的位置
<i class="icon1"></i>
<i class="icon2"></i>
.icon1{
	display:block;
	background-img:url(1.png);/*此图中含有icon1所需的背景,调整位置使它显示出来*/
	background-position:-20px 0;
	width:45px;
	height:70px;
}
19.字体图标

我们会经常用到一些图标。但是我们在使用这些图标时,往往会遇到失真的情况,而且图片数量很多的话,页面加载就越慢。所以,我们可以使用字体图标的方式来显示图标,既解决了失镇的问题,也解决了图片占用资源的问题

常用字体图标库:阿里字体图标库

优点:

  1. 轻量性:加载速度快,减少http请求
  2. 灵活性:可以利用CSS设置大小颜色等
  3. 兼容性:网页字体支持所有现代浏览器,包括IE低版本

使用字体图标

  1. 注册账号并登录
  2. 选取图标或搜索图标
  3. 添加购物车
  4. 下载代码
  5. 选择font-class引用
  <link rel="stylesheet" href="./font/iconfont.css">
 <span class="iconfont icon-zhifeiji test"></span>

具体引入方法可见下载文件中的demo_index.html

JavaScript学习笔记

01.JavaScript简介

JavaScript 是一种轻量级的脚本语言。所谓"脚本语言”,指的是它不具备开发操作系统的能力,而是只用来编写控制其他大型应用程序的"脚本”。

JavaScript是一种嵌入式(embedded) 语言。它本身提供的核心语法不算很多

为什么学习JavaScript

  • 操控浏览器的能力
  • 广泛的使用领域
  • 易学性

JavaScript与ECMAScript的关系

ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的-种实现。在日常场合,这两个词是可以互换的。

JavaScript版本

image-20221103143829766
02.JavaScript的语句、标识符

语句

JavaScript程序的单位是行(line) ,也就是一行一行地执行。一般情况下,每一行就是一个语句

var num = 10;

语句以分号结尾,一个分号就表示一个语句结束

标识符

标识符(identifier) 指的是用来识别各种值的合法名称。最常见的标识符就是变量名

标识符是由:字母、元符号($)、下划线( )和数字组成,其中数字不能开头

温馨提示

中文是合法的标识符,可以用作变量名(不推荐)

JavaScript保留关键字

以以关键字不需要强行记忆!

JavaScript有一 些保留字, 不能用作标识符: arguments、 break. case、 catch、 class、 const、continue、debugger. default、 delete、 do、 else、 enum、 eval、 export、 extends、 false、 finally.for、function. if、 implements. import. in、 instanceof. interface. let. new. null、 package、private、protected、 public、 return、 static、 super、 switch、 this、 throw、 true、 try、 typeof、var、void、 while、 with、 yield。

03.变量
var num = 10;
console.log(num);

变量提升
JavaScript引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再- -行一 行地运行。 这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部,这就叫做变量提升(hoisting) 。

console.log(num);
var num = 10;

转到浏览器后相当于以下代码(此过程被称为“变量提升”)

var num;
console.log(num);
num = 10;

浏览器的console控制台会输出undefined

04.JavaScript引入到文件

JavaScript常用引入方式

  1. 嵌入到HTML文件中
  2. 引入本地独立的JS文件
  3. 引入网络来源的文件

嵌入到HTML文件中

<body>
    <script>
        var num = 20;
    </script>
</body>

引入本地独立的JS文件

<body>
    <Script type="text/javascript" src="./font/iconfont.js"></Script>
</body>

引入网络来源的文件

<body>
    <Script type="text/javascript" src="http://code.jquery.com/jquery1.2.1.min.js"></Script>
</body>
05.JavaScript注释与常见输出方式
image-20221103150912317

JavaScript注释

源码中注释是不被引擎所解释的,它的作用是对代码进行解释。JavaScript 提供两种注释的写法: 一种是单行注释,用//起头;另-种是多行注释,放在/和之间。

//这是单行注释
/*
这是
多行
注释
*/

嵌入在HTML文件中的注释

<!-- 注释 -->

JavaScript的输出方式

alert("弹窗提示");
document.write("我是输出到页面");
console.log("控制台输出");
06.数据类型
image-20221103151850808

数据类型分类

JavaScript语言的每-个值, 都属于某一种数据类型。JavaScript 的数据类型,共有六种。(ES6 又新增了第七种Symbol类型的值和第八种BigInt类型,当前课程暂不涉及)

数据类型分类

原始数据类型(基础类型)

image-20221103152128388
var age = 10; 
var name = "张三";
var learn = "ture";
//对象(引用数据类型或合成数据类型)
var user = {
    age:17,
    name:"lisi",
    hunyin:false,
}

温馨提示

undefine和null,一般将其看作特殊值

07.typeof运算符
image-20221103152826726
var num = 20;
        var name = "lisi";
        var flag = true;
        var user={};
        document.write(typeof num);//number
        document.write(typeof name);//string
        document.write(typeof flag);//boolean
        document.write(typeof user);//object(不准确,可返回object1的类型很多)

unlI和undefined的区别
null与undefined都可以表示“没有”,含义非常相似。将一个变量赋值为undefined或null,老实说,语法效果几乎没区别。既然含义与用法都差不多,为什么要同时设置两个这样的值,这还是无端增加复杂度,令初学者困扰吗?这与历史原因有关

null一般代表对象为“没有”

undefined一般代表数值为“没有”

08.运算符基础知识
image-20221103155054629

加减乘除运算符

加减乘除运算符就是基本的数学运算符效果

10+10;
100-10;
10*2;
10/5;

余数运算符

余数运算符是比较常用的,因为在逻辑思维上寻找规律,余数运算符是很好用的

13%5

自增和自减运算符有一个需要注意的地方, 就是放在变量之后,会先返回变量操作前的值,再进行自增/自减
操作;放在变量之前,会先进行自增/自减操作,再返回变量操作后的值。

var x =1;
x++;
++x;
01.运算符之赋值运算符
image-20221103155654021

赋值运算符(Assignment Operators)用于给变量赋值

最常见的赋值运算符,当然就是等号(=)

赋值运算符还可以与其他运算符结合,形成变体。

var x = 1;
var x = y;
x+=y;
x-=y;
02.运算符之比较运算符
image-20221103155934195
var x1 = 10;
var x2 = "10";
console.log(x1 == x2); //ture
// === 严格比较,除了数值本身还比较类型
console.log(x1 === x2); //false
03.条件语句if…else
//基本使用
if(m===3){

}else{

}
//多情况判断
if(m===3){
}else if{

}else if{

}else if{

}
04.运算符之switch
switch(){
	case 条件一:
		//...
		break;
	case 条件二:
		//...
		break;
	....
    case 条件n:
    	//...
		break;
	default:
    	//...
}
05.三元运算符
(条件)?表达式1:表达式2
06.for循环语句
for(数值初始化;条件; 数值变化){
    
}
07.while循环
while(条件){
	语句;
}
08.break和continue

break语句和continue语句都具有跳转作用,可以让代码不按既有的顺序执行

break语句用于跳出代码块或循环

for(vari=0;i<5;i++){
    if (i === 3){
        break;
    }
	console.1og(i);
}

continue语句用于立即终止本轮循环,返回循环结构的头部,开始下一轮循环

for(vari=0;i<5;i++){
    if (i === 3){
        continue ;
    }
	console.1og(i);
}
09.字符串

字符串就是零个或多个排在一起的字符,放在单引号或双引号之中

“dsagdyu”
'asuifhiasuy'

单引号字符串的内部,可以使用双引号。双引号字符串的内部,可以使用单引号

'key="value"'
"It's a long dmas"

如果要在单引号字符串的内部,使用单引号,就必须在内部的单引号前面加上反斜杠,用来转义。双引号字符串内部使用双引号,也是如此

'Did she say \'hello\'?'
//"Did she say 'hello'?"
"Did she say\"hello\"?"

温馨提示

字符串默认只能写在一-行内, 分成多行将会报错

如果长字符串必须分成多行,可以在每一行的尾部使用反斜杠

var str1 = “hello word\Im coming!”//word后面换行
01.charAt()

charAt方法返回指定位置的字符,参数都是从0开始编号的

var S = new String('hello');
s.charAt(1)//h
s.charAt(s.length-1)//o

如果参数为负数,或大于等于字符串的长度,charAt返回空字符串

s.charAt(-1)//""
s.charAt(10)//""
02.concat()

concat方法用于连接两个字符串,返回一个新字符串,不改变原字符串

var s1 = "hello ";
var s2 = "world";
s1.concat(s2)//"hello world"
03.substring()

substring方法用于从原字符串取出子字符串并返回,不改变原字符串。它的第一个参数表示子字符串的开始位置,第二个位置表示结束位置(返回结果不含该位置);如果省略第二个参数, 则表示子字符串一直到原字符串的结束

"hello world".substring(0,2);//"he"
"hello world".substring(7);//"world"

如果第一个参数大于第二 个参数, substring 方法会自动更换两个参数的位置

"hello world".subString(2,0);//"he"

如果参数是负数,subtring 方法会自动将负数转为0

'itbaizhan'.substring(-3) // "itbai zhan"
'itbaizhan'.substring(2, -3) // "it"
04.substr()

substr方法用于从原字符串取出子字符串并返回,不改变原字符串,跟substing方法的作用相同
substr方法的第一个参数是子字符串的开始位置(从0开始计算) , 第二个参数是子字符串的长度

"hello world".substr(0,5);//hello
"hello world".substr(0);//省略第二个参数则表示从子字符串到结束

如果第一个参数负数,表示倒数计算的字符位置。如果第二个参数负数,将被自动转为0,因此会返回空字符串

'itbaizhan'.substr(-7) // "baizhan" 
'itbaizhan'. substr(4, -1) // ""
05.indexOf()

indexOf方法用于确定一个字符串在另一个字符串中第一次出现的位置,返回结果是匹配开始的位置。如果返回-1,就表示不匹配

'he1lo world'. indexof('o') // 4
'i tbaizhan'. indexof('sxt') // -1

indexOf方法还可以接受第二个参数,表示从该位置开始向后匹配

'he1lo world'. indexOf('o',6) // 7 从位置6往后查找
06.trim()

trim方法用于去除字符串两端的空格,返回一个新字符串,不改变原字符串

' he11o world '.trim()  //"hel1o world"

该方法去除的不仅是空格,还包括制表符(t、w) .换行符(n)和回车符®

'\r\nitbaizhan \t'.trim() //'itbai zhan'

ES6扩展方法,trimEnd()trimStart)方法:分别去除尾部的空格和头部的空格

"  itbaizhan  ".trimEnd();   //  itbaizhan
"  itbaizhan  ".trimStartO); // itbaizhan
07.split()

split方法按照给定规则分割字符串,返回一个由分割出来的子字符串组成的数组

'it|sxt|baizhan'.split('|') //["it", "sxt", "baizhan"]

如果分割规则为空字符串,则返回数组的成员是原字符串的每一个字符。

'alblc'.split('') // ["a", "I","b","I", "c"] 

如果省略参数,则返回数组的唯一成员就是原字符串

'it|sxt|bz'.split() // [it|sxt|bz]

split方法还可以接受第二个参数,限定返回数组的最大成员数。

'it|sxt|bz'.split('|', 0) // []
'it|sxt|bz'.split('|',1) // ["it"]
'it|sxt|bz'.splitC'|', 2) // ["it". "sxt"]
10.数组

数组(array) 是按次序排列的一组值。每个值的位置都有编号(从0开始), 整个数组用方括号表示。

var arr = ['xa','dsad','saf'] //xa是0号位置

除了在定义时赋值,数组也可以先定义后赋值。

vararr=[];
arr[0] ='sxt';
arr[1] = 'baizhan '
arr[2]='it';

任何类型的数据,都可以放入数组

var arr = [ 100, [1,2,3],false ];

如果数组的元素还是数组,就形成了多维数组

var a = [[1,2],[3,4]];
a[0][1] // 2
a[1][1] // 4

length属性

数组的length属性,返回数组的成员数量

['sxt', ' bai zhan', 'it']. length // 3
01.数组的遍历

数组的遍历可以考虑使用for循环或while循环

var a = ['sxt', 'baizhan', 'it'];
// for循环
for(vari=0;i<a.length;i++){
	console.1og(a[i]);
}
// while循环
var i=0;
while (i < a. 1ength) {
	console.1og(a[i]);
	i++ ;
}

for…in遍历数组

var a = ['sxt', 'baizhan', 'it'];
for(var i in a){
	console.1og(a[i]);
}
02.数组的静态方法

Aray.srray方法返回一个布尔值,表示参数是否为数组。它可以弥补typeof运算符的不足

var arr = ["尚学堂",100, true];
console.1og(typeof arr); // object
Array.isArray(arr) //ture
03.数组方法push()/pop()

push方法用于在数组的末端添加一个或多个元素,并返回添加新元素后的数组长度。注意,该方法会改变原数组

var arr= [];
arr.push("尚学堂") // 1
arr.push('itbaizhan') // 2
arr.push(true, {}) // 4
arr // [尚学堂,'itbaizhan', true, {}]
var length = arr.push("world"); //length为6

pop方法用于删除数组的最后一个元素,并返回该元素。注意,该方法会改变原数组

var arr = ['尚学堂', 'itbaizhan' ,'WEB前端 '];
arr.pop() // 'WEB前端'
arr // ['尚学堂', 'itbaizhan']
04.数组方法shift()/unshift()

shift方法用于删除数组的第一个元素,并返回该元素。注意,该方法会改变原数组

var arr = ['尚学堂','itbaizhan', 'WEB前端'];
arr.shiftO // '尚学堂
arr // ['itbaizhan', 'WEB前端']

shift方法可以遍历并清空一个数组

varlist=[1,2,3,4,5,6];
var item;
while (item = list.shift()){ //list.shift()有可删除元素时返回该元素,此时判定为ture
	console. log(item);
}
1ist // []

unshit方法用于在数组的第一个位置添加元素,并返回添加新元后的数组长度。注意,该方法会改变原数组

var arr = ['尚学堂','itbaizhan', 'WEB前端'];
arr. unshift('baizhan'); // 4
arr // ['baizhan', '尚学堂','itbaizhan', 'WEB前端']

unshit 方法可以接受多个参数,这些参数都会添加到目标数组头部

var arr = [ '尚学堂','itbaizhan' ];
arr . unshift('WEB前端', 'baizhan') // 4
arr // [ 'WEB前端', ' baizhan', '尚学堂','itbaizhan' ]
05.数组方法join

join 方法以指定参数作为分隔符,将所有数组成员连接为一个字符串返回。如果不提供参数,默认用逗号分隔

vara=[1,2,3,4];
a.join(' ') //'1 2 3 4'
a.join('|')//“1|2|3|4"
a.join() // "1,2,3,4"

如果数组成员是undefined或null或空位,会被转成空字符串

[undefined, nu11].join('#') // '#'
['a',,'b'].join('-')  // 'a--b'

数组的join配合字符串的split可以实现数组与字符串的互换

var arr = ["a","b","c"];
var myArr = arr.join("");	//a,b,c,d
console.1og(myArr); 
console.1og(myArr.split(""));	//["a","b","c"]
06.数组方法concat

concat方法用于多个数组的合并。它将新数组的成员,添加到原数组成员的后部,然后返回-个新数组,原数组不变

['he11o']. concat(['wor1d']) 	// ["he11o", "world"]
['hello']. concat(['world'], ['!'])  	
// ["he11o", "world", "!"] 

除了数组作为参数,concat 也接受其他类型的值作为参数,添加到目标数组尾部。

[1,2,3].concat(4, 5,6)	//[1,2,3,4,5,6]

应用场景

上拉加载,合并数据

07.数组方法reverse

reverse方法用于颠倒排列数组元素,返回改变后的数组。注意,该访法将改变原数组

var a = ['a', 'b', 'c'];
a.reverse(); 		// ["C", "b", "a"]
a 		// ["c","b",'a"]

实现一个字符串反转排列

var str = "he11o" ;
str.split("").reverse().join("")
08.数组方法indexOf

indexOf方法返回给定元素在数组中第一次出现的位置, 如果没有出现则返回1

var arr = ['a', 'b','c'];
arr. indexof('b') // 1
arr. indexof('y') // -1

indexOf方法还可以接受第二个参数,表示搜索的开始位置

1 ['尚学堂','百战程序员','itbai zhan']. indexof('尚学堂',1) //-1
11.函数

函数的声明
function命令: function命 令声明的代码区块,就是一个函数。function命 令后面是函数名,函数名后面是一对圆括号,里面是传入函数的参数。函数体放在大括号里面。

function print(s) {
	console.1og(s);
}
print(11);//调用函数

函数名的提升
JavaScript引擎将函数名视同变量名,所以采用function命令声明函数时,整个函数会像变量声明一样,被提升到代码头部

//写法上可以先调用再创建
add();
function add() {}

函数返回值
JavaScript函数提供两个接口实现与外界的交互,其中参数作为入口,接收外界信息;返回值作为出口,把运算结果反馈给外界

function getName (name){
	return name ;
}
var myName = getName("i tbai zhan")
console.1og(myName); // itbaizhan
12.对象

什么是对象?对象(object) 是JavaScript语言的核心概念,也是最重要的数据类型
简单说,对象就是一组"键值对” (key-value)的集合,是一种无序的复合数据集合

image-20221104205910975
varuser={
	name: 'itbaizhan',
	age: '13'
};

对象的每一个键名又称为“属性” (property) ,它的“键值”可以是任何数据类型。如果一个属性的值为函数,通常把这个属性称为方法,它可以像函数那样调用

var user= {
	getName: function (name) {
	return name ;
	}
};
user.getName("itbaizhan") // itbaizhan

如果属性的值还是一个对象, 就形成了链式引用

var user = {
	name:"itbaizhan",
	age:13,
	container:{
		frontEnd:["web前端","Android","ios"],
		backEnd:["Java","Python"]
	}
}
coosole.log(user.container.frontEnd);//链式调用
13.Math对象

Math是JavaScript的原生对象,提供各种数学功能。
Math.abs方法返回参数值的绝对值

Math.abs(1) // 1
Math.abs(-1) // 1
Math.max(), Math.min()

Math.max方法返回参数之中最大的那个值,Math.min 返回最小的那个值。如果参数为空,Math.min 返回Infinity ,Math.max返回Infinity 。

Math.max(2,-1,5) // 5
Math.min(2,-1,5) // -1
Math.min() // Infinity
Math.max() // -Infinity

Math.foor方法返回小于参数值的最大整数,Math.ceil()返回大于参数值的最小整数

Math.floor(3.2) //3
Math.floor(-3.2) //-4
Math.ceil(3.2) //4
Math.ceil(-3.2) //-3

Math. random()返回0到1之间的一个伪随机数,可能等于0, 但是一定小于1

Math. random() // 0.28525367438365223

任意范围的随机数生成函数如下

function getRandomArbitrary(min, max) {
	return Math. random() * (max 一min) + min;
} 
getRandomArbitrary(5, 10)
14.Date对象

Date对象是JavaScript原生的时间库。它以1970年1月1日00:00:00作为时间的零点,可以表示的时间范围是前后各1亿天(单位为毫秒)

Date. now方法返回当前时间距离时间零点(1970年1月1日00:00:00 UTC)的毫秒数,相当于Unix时间戳乘以
1000

Date . now() ;/ / 1635216733395

时间戳

时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。
格林威治和北京时间就是时区的不同

Unix是20世纪70年代初出现的一个操作系统,Unix认为1970年1 月1日0点是时间纪元。JavaScript也就遵循了这一约束

Date对象提供了一系列get方向,用来获取实列对象某个方面的值

实例方法get类
getTime() : 返回实例距离1970年1月1日00:00:00的毫秒数
getDate() : 返回实例对象对应每个月的几号(从1开始)
getDay() : 返回星期几,星期日为0,星期-为1,以此类推
getYear() : 返回距离1900的年数
getFullYear() : 返回四位的年份
getMonth() : 返回月份(0表示1月,11表示12月)
getHours() : 返回小时(0-23)
getMilliseconds() : 返回毫秒(0-999)
getMinutes() : 返回分钟(0-59)
getSeconds() : 返回秒(0-59)

var d = new Date('January 6,2022')
d.getDte() //6
d.getMonth() //0
d.getYear() //122
d.getFullYear() //2022

编写函数获得本年度剩余天数

function leftDays() {
	var today = new Date();
	var endYear = new Date(today{getFu11Year(), 11, 31, 23, 59, 59, 999);
	varmsPerDay=24*60*60*1000;	//一天的毫秒数
	return Math. round((endYear.getTime()-today.getTime()/msPerDay);
}
15.DOM概述

DOM是JavaScript操作网页的接口,全称为“文档对象模型”(Document Object Model)。它的作用是将网页转为-个JavaScript对象,从而可以用脚本进行各种操作(此如对元素增删内容)

浏览器会根据DOM模型,将结构化文档HTML解析成-系列的节点,再由这些节点组成一个树状结构(DOMTree)。所有的节点和最终的树状结构,都有规范的对外接口

DOM只是-一个接口规范,可以用各种语言实现。所以严格地说,DOM不是JavaScript语法的一部分,但是DOM操作是JavaScript最常见的任务,离开了DOM, JavaScript 就无法控制网页。另-方面,JavaScript 也是最常用于DOM操作的语言

节点
DOM的最小组成单位叫做节点(node) 。文档的树形结构(DOM树),就是由各种不同类型的节点组成。每个节点可以看作是文档树的一片叶子

image-20221104215329331

节点的类型有7种

Document:整个文档树的顶层节点
DocumentType: doctype标签
Element:网页的各种HTML标签
Attribute:网页元素的属性(比如class=“right”)
Text:标签之间或标签包含的文本
Comment:注释
DocumentFragment:文档的片段

节点树

一个文档的所有节点,按照所在的层级,可以抽象成一种树状结构。这种树状结构就是DOM树。它有一一个顶层节点,下一层都是顶层节点的子节点,然后子节点又有自己的子节点,就这样层层衍生出一一个金字塔结构,倒过来就像一棵树

浏览器原生提供document节点,代表整个文档

document	//整个文档树

除了根节点,其他节点都有三种层级关系

父节点关系(parentNode) :直接的那个上级节点
子节点关系(childNodes) :直接的下级节点
同级节点关系(sibling) :拥有同一个父节点的节点

Node.nodeType属性

不同节点的node Type属性值和对应的常量如下

文档节点(document) : 9,对应常量Node.DOCUMENT _NODE

元素节点(element) : 1, 对应常量Node.ELEMENT_ NODE

属性节点(attr) : 2,对应常量Node.ATTRIBUTE_ NODE

文本节点(text) : 3,对应常量Node.TEXT. NODE

document.nodeType //9
document.nodeType == Node.DDOCUMENT _NODE //ture
16.document对象方法
01.获取元素
image-20221104220417533

documentgetElementsByTagName()
document gelElementsByTegName方法搜索HTML标签名,返回符合条件的元素。它的返回值是一个类似数组对象( HTMCLCllection实例), 可以实时反映HTML文档的变化。如果没有任何匹配的元素,就返回一个空集

var paras = document.getE1ementsByTagName('p');

如果传入*就可以返回文档中所有HTML元素

var a11Elements = document. getE1ementsByTagName('*');

document.getElementsByClassName()
document. getElementsByClassName方法返回-个类似数组的对(HMCOllection实例) ,包括了所有class名字符合指定条件的元素,元素的变化实时反映在返回结果中

var elements = document . getElementsByClassName (names) ;

由于class是保留字,所以JavaScript-律使用 dassName示CSS的class,参数可以是多个class,它们之间使用空格分隔

var elements = document .getElementsByClassName('foo bar');

document.getElementsByName()
document. getElementsByName方法用于选择拥有name属性的HTML元素(比如<form><radio><img> 等) ,返回一个类似数组的的对象( NodeList实例),因为name属性相同的元素可能不止一个

//表单为<form name="itbaizhan"> </form>
var forms = document.getE1 ementsByName('itbaizhan' );

document.getElementByld()
document gelElementByld方法返回匹配指定id属性的元素节点。如果没有发现匹配的节点,则返回null

var elem = document.getElementById(' paral');

注意,该方法的参数是大小写敏感的。比如,如果某个节点的id属性是main ,那么document geElemenByld(Main)将返回null

document.querySelector()

document. querSeletor方法接受一个CSS选择器作为参数,返回匹配该选择器的元素节点。如果有多个节点满足匹配条件,则返回第一个匹配的节点。如果没有发现匹配的节点,则返回null

var e11 = document.querySelector(' .myclass');

document.querySelectorAIl()

document quesSeletoAll方法与querySelecor用法类似,区别是返回一个NodeList 对象,包含所有匹配给定选择器的节点

var elementList = document.querySelectorA1l(' .myclass');
02.创建元素
image-20221104224844164

document.createElement()

document createElement方法用来生成元素节点,并返回该节点

var newDiv = document.createElement('div');

document.createTextNode()

document ceateTextNote方法用来生成文本节点( Text实例),并返回该节点。它的参数是文本节点的内容

var newDiv = document .createElement( 'div');
var newContent = document.createTextNode('He11o');
newDiv.appendChild(newContent);

document.createAttribute()

document cereltribtle方法生成一个新的属性节点 ( Atr实例),并返回它

var attribute = document.createAttribute(name);
var root = document.getElementById('root');
var it = document.createAttribute('itbaizhan');
it.value = 'it';
root.setAttri buteNode(it);
17.Element对象属性
image-20221105160824658

Element对象对应网页的HTML元素。每-个 HTML元素,在DOM树上都会转化成一个Element节点对象(以下简称元素节点)
Element.id
Elementid属性返回指定元素的id属性,该属性可读写

HTML代码为<p id="foo">
var p = document.querySelector('p');
p.id // "foo"

Element.className
className属性用来读写当前元素节点的class属性。它的值是一个字符串, 每个class之间用空格分割

// HTML代码<div class="one two three" id="myDiv"></div>
var div = document.getElementById('myDiv');
div.c1assName //one two three

Element.classList

  • classList对象有下列方法
  • add() :增加一个class。
  • remove(): 移除一个 class。
  • contains(): 检查当前元素是否包含某个class.
  • toge(): 将某个class移入或移出当前元素。
var div = document.getElementById(' myDiv');
div.classList.add(' myCssClass');
div.classList.add('foo', 'bar');
div.classList.remove(' myCssClass');
div.classList.toggle('myCssClass'); //如果myCssClass不存在就加入,否则移除
div.classList.contains(' myCssClass'); //返回true或者false
18.Element获取元素位置
属性 描述
clientHeight 获取元素高度包括padding部分,但是不包括border. margin
clientWidth 获取元素宽度包括padding部分,但是不包括border、margin
scrollHeight 元素总高度,它包括padding,但是不包括border、margin 包括溢出的不可见内容
scrollWidth 元素总宽度,它包括padding,但是不包括border、margin 包括溢出的不可见内容
scrollLeft 元素的水平滚动条向右滚动的像素数量
scrollTop 元素的垂直滚动条向下滚动的像素数量
offsetHeight 元素的CSS垂直高度(单位像素),包括元素本身的高度、padding 和border
offsetWidth 元素的CSS水平宽度(单位像素), 包括元素本身的高度、padding 和border
offsetLeft 到定位父级左边界的间距
offsetTop 到定位父级上边界的间距

Element.clientHeight, Element.clientWidth

Element. cientHeight属性返回-个整数值,表示元素节点的CSS高度(单位像素),只对块级元素生效,对于行内元素返回0。如果块级元素没有设置CSS高度,则返回实际高度

除了元素本身的高度,它还包括padding 部分,但是不包括border、margin。 如果有水平滚动条,还要减去水平滚动条的高度。注意,这个值始终是整数,如果是小数会被四舍五入。

Element. cinWidth属性返回元素节点的CSS宽度,同样只对块级元素有效,也是只包括元素本身的宽度和padding,如果有垂直滚动条,还要减去垂直滚动条的宽度。

document. documentElement的cientHeight属性,返回当前视口的高度(即浏览器窗口的高度)。document.body 的高度则是网页的实际高度。

//视口高度(显示屏高度)
doucument.doucumentElement.clientHeight
//网页总高度(页面的高度)
doucument.body.clienHeight

Element.scrollHeight, Element.scrollWidth

Element solHlight属性返回一个整数值(小数会四舍五入) , 表示当前元素的总高度(单位像素),它包括padding,但是不包括border、margin 以及水平滚动条的高度(如果有水平滚动条的话)

Element. solid属性表示当前元素的总宽度( 单位像素),其他地方都与srollHeight属性类似。这两个属性只读整张网页的总高度可以从document documentElement或documentbody .上读取

1 //返回网页的总高度
document.documentElement.scro11Height
document.body.scrollHeight

Element.scrollLeft, Element.scrollTop

Element.croll eft属性表示当前元素的水平滚动条向右侧滚动的像素数量,Element scolITop属性表示当前元素的垂直滚动条向下滚动的像素数量。对于那些没有滚动条的网页元素,这两个属性总是等于0

如果要查看整张网页的水平的和垂直的滚动距离,要从document. documentElement元素上读取

document.documentE1ement.scrollLeft
document.documentE1ement.scro11Top

Element.offsetHeight, Element.offsetWidth

Element. fsetHeight属性返回-个整数,表示元素的CSS垂直高度(单位像素),包括元素本身的高度、padding和border,以及水平滚动条的高度(如果存在滚动条)。

Element. ofetWidth属性表示元素的CSS水平宽度(单位像素),其他都与Element ofsetHeight -致。

这两个属性都是只读属性,只比Element.lientHeight和Element.lintWidth多了边框的高度或宽度。如果元素的CSS
设为不可见(比如display: none;),则返回0

19.CSS操作

HTML元素的style属性
操作CSS样式最简单的方法,就是使用网页元素节点的setribute方法直接操作网页元素的style属性

div. setAttribute(
	'style',' background-color:red;' + ' border:1px solid black;'
);

元素节点的style属性

var divsty1e = document.querySelector('div').style;
divstyle.backgroundColor = 'red' ;
divsty1e.border = ' 1px solid b1ack';
divstyle.width = ' 100px' ;
divstyle.height = ' 100px' ;
divStyle.fontSize =' 10em' ;

cssText属性

var divstyle = document .querySelector('div').style;
divstyle. cssText = 'background-color: red;'
	+ 'border: 1px solid black;
	+ 'height: 100px;
	+ 'width: 100px;' ;

总结:

<div class="box" id="box"></div>
    <script>
        var box = document.getElementById("box")
        //方法1
        // box.setAttribute("style", "width:200px; height:200px;background:red;");
        //方法2
        // box.style.width = "200px";
        // box.style.height = "200px";
        // box.style.background = "red";
        //方法3
        box.style.cssText = "width:200px; height:200px;background:red;"
    </script>
20.事件处理程序

事件处理程序分为:

  • HTML事件处理
  • DOM0级事件处理
  • DOM2级事件处理

HTML事件:

缺点:HTML代码和JS没有分开

<body>
    <button onclick="clickHandle()">按钮</button>
    <script>
        function clickHandle(){
            alert("点击了按钮!");
        }
    </script>
</body>

DOM0级事件处理:

优点:HTML和JS是分离的

缺点:无法同时添加多个事件

<body>
    <button id="btn">按钮</button>
    <script>
        var btn = document.getElementById("btn");
        btn.onclick = function () {
            alert("哈哈哈,点击了按钮!")
        }
        //哈哈哈被覆盖
        btn.onclick = function () {
            alert("呵呵呵,点击了按钮!")
        }
    </script>
</body>

DOM2级事件处理

优点:事件不会被覆盖

<body>
    <button id="btn">按钮</button>
    <script>
        var btn = document.getElementById("btn");
        btn.addEventListener("click", function () {
            alert("呃呃呃,点击了按钮!");
        })
    </script>
</body>

单事件选DOM0,多事件选DOM2

21.事件类型之鼠标事件

鼠标事件
鼠标事件指与鼠标相关的事件,具体的事件主要有以下一些

  • click: 按下鼠标时触发
  • dblclick:在同一个元素上双击鼠标时触发
  • mousedown:按下鼠标键时触发
  • mouseup:释放按下的鼠标键时触发
  • mousemove:当鼠标在节点内部移动时触发。当鼠标持续移动时,该事件会连触发。
  • mouseenter:鼠标进入一个节点时触发,进入子节点不会触发这个事件
  • mouseleave:鼠标离开一个节点时触发,离开父节点不会触发这个事件
  • mouseover:鼠标进入一个节点时触发,进入子节点会再一次触发这个事件
  • mouseout:鼠标离开一个节点时触发,离开父节点也会触发这个事件
  • wheel:滚动鼠标的滚轮时触发
<style>
        .box1 {
            width: 200px;
            height: 200px;
            background-color: red;
        }

        .box2 {
            width: 200px;
            height: 200px;
            background-color: green;
        }
    </style>
<body>
    <button id="bt1">单击</button>
    <button id="bt2">双击</button>
    <button id="bt3">鼠标按下</button>
    <button id="bt4">鼠标抬起</button>
    <div id="bt5" class="box1"></div>
    <div id="bt6" class="box2"></div>

    <script>
        var bt1 = document.getElementById("bt1");
        bt1.onclick = function () {
            alert("单击事件")
        }
        var bt2 = document.getElementById("bt2");
        bt2.ondblclick = function () {
            alert("双击事件")
        }
        var bt3 = document.getElementById("bt3");
        bt3.onmousedown = function () {
            alert("鼠标按下")
        }
        var bt4 = document.getElementById("bt4");
        bt4.onmouseup = function () {
            alert("鼠标抬起")
        }
        var bt5 = document.getElementById("bt5");
        bt5.onmousemove = function () {
            console.log("鼠标移动了");
        }
        var bt6 = document.getElementById("bt6")
        bt6.addEventListener("mouseenter", function () {
            alert("鼠标进入!");
            bt6.style.backgroundColor = "black";
        })
        bt6.addEventListener("mouseout", function () {
            alert("鼠标离开!");
            bt6.style.backgroundColor = "green";
        })
        bt6.addEventListener("wheel", function () {
            alert("鼠标滚动!");
            bt6.style.backgroundColor = "red";
        })
    </script>
</body>
22.Event事件对象

事件发生以后,会产生一个事件对象,作为参数传给监听函数。

Event对象属性

  1. Event.Target
  2. Event.type

Event.target属性返回事件当前所在的节点

<button id="btn">按钮</button>
    <script>
        var btn = document.getElementById("btn")
        btn.onclick = function (event) {
            console.log(event.target);
            event.target.innerHTML = "点击后"; //点击后修改内容
            console.log(event.type); // click
        }
    </script>

Event对象方法

  1. Event.preventDefault()
  2. Event.stopPropagation()

Event.preventDefault方法取消浏览器对当前事件的默认行为。比如点击链接后,浏览器默认会跳转到另一个页面,使用这个方法以后,就不会跳转了

btn.onclick = function(e){
	e.preventDefau1t(); // 阻止默认事件
	console.1og("点击A标签") ;
}

stopPropagation方法阻止事件在DOM中继续传播,防止再触发定义在别的节点上的监听函数,但是不包括在当前节点上其他的事件监听函数

btn. onclick = function(e){
	e.stopPropagation(); //阻止事件冒泡
	console.1og("btn") ;
}

事件冒泡:

<div class="root" id="root">
        <div class="box" id="box"></div>
    </div>
<script>
        var root = document.getElementById("root");
        var box = document.getElementById("box");
        root.onclick = function (e) {
            console.log("root");
        }
        box.onclick = function (e) {
            e.stopPropagation();//阻止事件冒泡
            console.log("box");
        }
    </script>

点击box后,控制台会打印box和root

23.事件类型之键盘事件

键盘事件由用户击打键盘触发,主要有keydown. keypress. keyup三个事件

  1. keydown:按下键盘时触发。
  2. keypress:按下有值的键时触发,即按下Ctrl、Alt. Shift. Meta 这样无值的键,这个事件不会触发。对于有值的键,按下时先触发keydown事件,再触发这个事件。
  3. keyup: 松开键盘时触发该事件
username.onkeypress = function(e){
	console.1og("keypress事件");
}
<input type="text" id="username">
    <script>
        var username = document.getElementById("username")
        username.onkeydown = function (e) {
            console.log("按下了");//vaule的属性就是输入框的内容
        }
        username.onkeyup = function (e) {
            console.log(e.target.value);//vaule的属性就是输入框的内容
        }
        username.onkeypress = function (e) {
            console.log("keypress");//vaule的属性就是输入框的内容
        }
    </script>

event对象

keyCode:唯一标识

<input type="text" id="password">
<script>
    var password = document.getElementById("password")
    password.onkeyup = function (e) {
        //keyCode代表每一个按键的唯一 如输入a为65
        console.log(e.keyCode);
        if (e.keyCode == 13)//13为回车键
            console.log("开始搜索");
    }
</script>
24.事件类型之表单事件

表单事件是在使用表单元素及输入框元素可以监听的一系列事件

  1. input事件
  2. select事件
  3. Change事件
  4. reset事件
  5. submit事件

input事件
input事件当<input><select><textarea> 的值发生变化时触发。对于复选框( <input type=checkbox> )或单选框( <input type-radio>),用户改变选项时,也会触发这个事件

input事件的一个特点,就是会连续触发,比如用户每按下一-次按键, 就会触发- -次input事件。

var username = document.getE1 ementById("username");
username.oninput = function(e){
	console.1og(e.target.value);
}

select事件
select事件当在<input><textara> 里面选中文本时触发

// HTML 代码如下
// <input id="test" type="text" value="Select me!" />
var elem = document.getElementById('test');
elem. addEventListener('select', function (e) {
	console.log(e. type); // "select"
},false);

Change事件

Change事件当<input><selec><textarea> 的值发生变化时触发。它与input事件的最大不同, 就是不会连续触发,只有当全部修改完成时才会触发

//失去焦点(点击输入框以外的区域)和回车时触发
var emai1 = document.getE ementById("email");
email. onchange = function(e){
	console.1og(e.target.value);
}

reset事件,submit 事件

这两个事件发生在表单对象<form>, 上而不是发生在表单的成员上。

reset事件当表单重置(所有表单成员变回默认值)时触发。

submit事件当表单数据向服务器提交时触发。注意, submit事件的发生对象是<from>元素,而不是<button>元素,因为提交的是表单,而不是按钮

<form id="myForm" onsubmi t="submitHandle">
	<button onclick=" resetHandle">重置数据</button>
	<button>提交</button>
</form>
var myForm = document.getElementById("myForm")
function resetHandle(){
	myForm. reset();
}
function submitHandle(){
	console.1og("提交");
}
25.事件代理(事件委托)

由于事件会在冒泡阶段向上传播到父节点,**因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件。**这种方法叫做事件的代理(delegation)

var u1 = document.querySelector('u1');
u1.addEventListener('click', function (event) {
	if (event.target.tagName.toLowercase() === '1i') {//toLowercase()方法用于将大写转为小写
		//some code
        console.log("点击了li标签");
        console.log(event.target.innerHTML);//打印当前点击的li标签内的内容
	}
});
26.定时器

JavaScript提供定时执行代码的功能,叫做定时器(timer) ,主要由setTmeout()和setnteval)这两个函数来完成。它们向任务队列添加定时任务

01.setTimeout

setTmeout函数用来指定某个函数或某段代码,在多少毫秒之后执行。它返回-个整数,表示定时器的编号,以后可以用来取消这个定时器。

var timerId = setTimeout(func|code, delay);

setTmeout函数接受两个参数,第一个参数func|code是将要推迟执行的函数名或者一段代码,第二个参数delay是推迟执行的毫秒数

setTimeout(function (){
	console.log("大家好!");
}, 3000)	//3秒后打印

温馨提示

还有一个需要注意的地方,如果回调函数是对象的方法,那么setTimeout使得方法内部的this关键字指向全局环境,而不是定义时所在的那个对象

var name = "world";
var user = {
    name: "hello",
    getname: function () {
        var that = this;
        setTimeout(function () {
            console.log(this.name); //word 此时的this是全局this
            //console.log(that.name); //hello 此处的that相当于user里面的this
        }, 1000)
    }
}
user.getname();

取消定时器

var timer = setTimeout(function () {
	console.log("大家好!");
}, 3000)
//取消定时器
clearTimeout(timer);
02.setInterval

setInterval
函数的用法与seTTmeout完全一致, 区别仅仅在于setInterval指定某个任务每隔一段时间就执行一次,也就是无限次的定时执行

var timer = setInterval(function () {
	console.log("大家好!");
}, 3000)//每3秒打印一次

实现透明度减少效果

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .box1 {
            width: 200px;
            height: 200px;
            background-color: red;
            opacity: 1;
        }
    </style>
</head>

<body>
    <div class="box1" id="box1"></div>
    <script>
        var box1 = document.getElementById("box1")
        var opacity = 1;
        var fader = setInterval(function () {

            if (opacity > 0) {
                opacity -= 0.05;
                box1.style.opacity = opacity;
            } else clearInterval(fader)

        }, 100)
    </script>

</body>
</html>
27.防抖

防抖严格算起来应该属于性能优化的知识,但实际上遇到的频率相当高,处理不当或者放任不管就容易引起浏览器卡死。

从滚动条监听的例子说起

function showTop () {
var scro11Top = document.documentElement. scro11Top;
	console.1ogC'滚动条位置: ' + scro11Top);
}
window.onscro11 = showTop

在运行的时候会发现存在一个问题:这个函数的默认执行频率,太高了!高到什么程度呢? 以chrome为例,我们可以点击选中一个页面的滚动条,然后点击一次键盘的[向下方向键],会发现函数执行了8-9次!

然而实际上我们并不需要如此高频的反馈,毕竟浏览器的性能是有限的,不应该浪费在这里,所以接着讨论如何优化这种场景。

基于上述场景,首先提出第一种思路:在第一次触发事件时,不立即执行函数,而是给出一个期限值比如200ms,然后

  1. 如果在200ms内没有再次触发滚动事件,那么就执行函数
  2. 如果在200ms内再次触发滚动事件,那么当前的计时取消,重新开始计时

效果:如果短时间内大量触发同一事件,只会一次函数

实现:既然前面都提到了计时,那实现的关键就在于setTimeout这个函数,由于还需要一个变量来保存计时,考虑维护全局纯净,可以借助闭包来实现

function debounce(fn,delay){
	var timer = null;//借助闭包
	return function(){
		if(timer){
			clearTimeout(timer)
		}
		timer = setTimeout(fn,delay)
	}
}
//滚动事件
window.onscroll = debounce(scrollHandle,200)//200ms监听一次
function scrollHandle() {
	// console.log("页面滚动");
	var scrollTop = document.documentElement.scrollTop;
	console.log(scrollTop);
}

防抖定义
对于短时间内连续触发的事件(上面的滚动事件),防抖的含义就是让某个时间期限(如上面的200毫秒)内,事件处理函数只执行一次

28.节流

节流严格算起来应该属于性能优化的知识,但实际上遇到的频率相当高,处理不当或者放任不管就容易引起浏览器卡死。

继续思考,使用上面的防抖方案来处理问题的结果是

如果在限定时间段内,不断触发滚动事件(比如某个用户闲着无聊,按住滚动不断的拖来拖去),只要不停止触发,理论上就永远不会输出当前距离顶部的距离
但是如果产品同学的期望处理方案是:即使用户不断拖动滚动条,也能在某个时间间隔之后给出反馈呢?

其实很简单:我们可以设计-种类似控制阀门-样定期开放的函数,也就是让函数执行一次后, 在某个时间段内暂时失效,过了这段时间后再重新激活(类似于技能冷却时间)

效果:如果短时间内大量触发同一事件,那么在函数执行一次之后,该函数在指定的时间期限内不再工作,直至过了这段时间才重新生效实现.

这里借助setTimeout来做一个简单的实现, 加上一个状态位valid来表示当前函数是否处于工作状态

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        h3 {
            height: 400px;
        }
    </style>
</head>

<body>
    <h3>hhhhhh</h3>
    <h3>hhhhhh</h3>
    <h3>hhhhhh</h3>
    <h3>hhhhhh</h3>
    <h3>hhhhhh</h3>
    <h3>hhhhhh</h3>

    <script>
        //节流
        function throttle(fn, delay) {
            var valid = true;
            return function () {
                if (!valid) {
                    return false;
                }
                valid = false;
                setTimeout(function () {
                    fn();
                    valid = true;
                }, delay)
            }
        }
        //滚动事件
        window.onscroll = throttle(scrollHandle, 2000)
        function scrollHandle() {
            // console.log("页面滚动");
            var scrollTop = document.documentElement.scrollTop;
            console.log(scrollTop);
        }
    </script>
</body>

</html>

如果一直拖着滚动条进行滚动,那么会以2000ms的时间间隔,持续输出当前位置和顶部的距离

讲完了这两个技巧,下面介绍一下平时开发中常遇到的场景:

  1. 搜索框input事件,例如要支持输入实时搜索可以使用节流方案(间隔一段时间就必须查询相关内容),或实现输入间隔大于某个值(如500ms),就当做用户输入完成,然后开始搜索,具体使用哪种方案要看业务需求
  2. 页面resize事件,常见于需要做页面适配的时候。需要根据最终呈现的页面情况进行dom渲染(这种情形一般是使用防抖,因为只需要判断最后一次的变化情况)

ES6学习笔记

01.命令行工具

在正式讲解ES6新特性之前,我们需要了解一些命令行工具, 在日后的课程中,我们会经常用到命令行

常用命令行工具有两种

  1. CMD命令行工具
  2. PowerShell 命令行工具

CMD命令行

  1. 打开命令行窗口
    1. win:左下角开始,找到运行,点击,输入cmd, 回车
    2. win: win+r 快速打开命令行窗口
    3. mac: command +空格,输入terminal
  2. 选择盘符:盘符名加冒号E:
  3. 查看盘符及目录下文件与文件夹: win:dir mac:is
  4. 清空命令行信息: win:cls mec:clear
  5. 进入文件夹或目录: cd 文件夹名称
  6. 返回到上一级目录:cd …/
  7. 快速补全目录或文件夹名称: tab
  8. 创建文件夹: mkdir 文件夹名称
  9. 查看历史输入过的命令:.上下按键

PowerShell

  1. 打开方式

    1. 开始位置搜索PowerShell打开

    2. 在对应目录按住shif+右键,打开

  2. 其他保持一致

02.ECMAScript 6简介

ECMAScript和JavaScript的关系

ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的一种实现,常场合,这两个词是可以互换的。

名称详解

ECMAScript6 (以下简称ES6)是JavaScript语言的标准,在2015年6发布。它的目标,是使得JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。

版本 官方名称 发布日期
ES1 ECMAScript 1 1997
ES2 ECMAScript 2 1998
ES3 ECMAScript 3 1999
ES4 ECMAScript 4 从未发布过
ES5 ECMAScript 5 2009
ES5.1 ECMAScript 5.1 2011
ES6 ECMAScript 2015(ECMAScript 6) 2015
ES7 ECMAScript 2016 2016
ES8 ECMAScript 2017 2017

因此,ES6既是一个历史名词,也是一个泛指, 含义是5.1版以后的JavaScript的下一代标准, 涵盖了ES2015、ES2016、 ES2017 等等

ES6带来的新特性

  1. let 和const命令
  2. 变量的解构赋值
  3. 字符串扩展
  4. 函数扩展
  5. 对象扩展
  6. 数组扩展
  7. 运算符扩展
  8. Promise对象
  9. Class
  10. Class继承
03.Node.js安装

大量的库

在安装Nodeis的同时,会附带一个ppm命令,npm是Node的包管理工具,这样正是接下来我们要用到的npm的简单结构有助于Node.js生态系统的激增,现在npm仓库托管了超过1,000,000个可以自由使用的开源库包

npm镜像

由于服务器在国外,所以下载速度比较慢,我们可以用国内的镜像

阿里镜像地址

https://npmmirror.com/

在命令行运行如下命令即可

npm insta1l -g cnpm --registry=https://regi stry. npmmi rror . com
04.Babel转码器

Babel是一个广泛使用的ES6转码器,可以将ES6代码转为ES5代码,从而在老版本的浏览器执行。这意味着.你可以用ES6的方式编写程序,又不用担心现有环境是否支持

浏览器支持性查看

https://caniuse.com/

Babel官网

https://babeljs.io/

转码示例

原始代码用了箭头函数,Babel 将其转为普通函数,就能在不支持箭头函数的JavaScript环境执行了

//转码前
input . map(item => item + 1);
//转码后
input . map(function (item) {
	return item + 1;
});

Babel安装流程

第一-步:安装Babel

选择项目,在其中使用shell命令

npm insta11 --save-dev @babe1/core

或者在vscode选择项目,右键,在集成终端中打开

cpm insta11 --save-dev @babe1/core

第二步:配置文件.babelre
Babel的配置文件是babelrc,存放在项目的根目录下。使用Babel的第一步, 就是配置这个文件。该文件用来设置转码规则和插件,基本格式如下

{
	"presets": [],
	"plugins": []
}

第三步:转码规则

presets字段设定转码规则,官方提供以下的规则集,你可以根据需要安装

npm insta11 --save-dev @babe1/ preset-env //vs中为cnpm

第四步:将规则加入.babelr

{
	'presets": ["@babe1/env"],
	"plugins": []
}

Babel命令行转码

Babel提供命令行具@babelvcl, 用于命令行转码

npm insta11 --save-dev @babe1/cli //项目根目录安装

基本用法如下

基本用法如下.

#转码结果输出到标准输出
$ npx babe1 example.js
#转码结果写入一个文件
# --out-file 或-0参数指定输出文件
$ npx babe1 examp1e.js --out-file compiled.js
#或者
$ npx babe1 example.js -0 compiled.js
#整个目录转码
# --out-dir或-d参数指定输出目录
$ npx babe1 src --out-dir 1ib
#或者
$ npx babel src -d 1ib
05.Let命令

ES6新增了let 命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。

let块级作用域

{
	1et itbaizhan = 10;
	var sxt = 1;
}
itbaizhan // ReferenceError: itbaizhan is not defined.
sxt//1

var关键词:函数级的作用域

if(true){
var i =10
}
console.log(i);//可输出

function f1(){
	var i = 10;
}
f1();
console.log(i);//会报错

let块级作用域:可理解为{}级的作用域

if(true){
let i =10
}
console.log(i);//会报错

for循环的计数器,就很合适使用let命令

for(let i=0;i<10;i++){
	//...
}
console.1og(i);
// ReferenceError: i is not defined
for(let i=0;i<10;i++){
	//...
}
//可继续使用i
for(let i=0;i<10;i++){
	//...
}

对比var和let在循环中的应用

//每次存入的是function(i)并没有打印,最后到i=10停止,此时a[6]()进行调用打印,打印出来的i为10
var a=[];
for(var i=0;,i<10;i++){
	a[i] = function () {
	console.1og(i);
};
a[6](); // 10

上面代码,输出的10 ,而我们期待的是6

//每存入一次,下一次的i即为新的i,所以调用的时候i就是我们预想的
var a=[];
for(let i=0;i<10;i++){
a[i] = function () {
	console.1og(i);
};
a[6](); // 6

上面代码,输出的6

var:只有一个i,每次为其赋值

let:有多个let,每个i不同

let没有变量提升

console.1og(i);	//undefined
var i = 10;

console.1og(i);	//会报错
let i = 10;

let不能重复声明

let不允许在相同作用域内,重复声明同一个变量。

let i = 10
let i = 20
console.1og(i);	//会报错
06.Const命令

const声明一个只读的常量。一旦声明,常量的值就不能改变

const PI = 3.1415;
PI // 3.1415
PI=3;
// TypeError: Assignment to constant variable.

const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值

const foo;
// SyntaxError: Missing initializer in const declaration !

const命令声明的常量:

  1. 声明时必须初始化
  2. 为块级作用域
  3. 没有变量提升
  4. 不能重复声明
07.对象解构赋值

基本概念:

var user = {
	name: "dada",
	age: 20
}
console.log(user.name);
//对象解构赋值
const { name, age } = user;
console.log(age);

解构可以用于对象

1et {name,age} = {name: "iwen",age:20};

温馨提示
对象的属性没有次序,变量必须与属性同名,才能取到正确的值

let {age ,name} = {name :"iwen" , age :20};
age // 20
let {sex, age ,name} = {name :"iwen" , age :20};
sex // undefined

对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量

let {age ,name} = {name :"iwen" , age :20};
1et { random, floor } = Math; //将Math.floor直接替换为floor
1et { 1og } = console;
log(name); //将console.log直接用log替换

注意事项,如果要将-一个已经声明的变量用于解构赋值,必须非常小心

var user = {
	name:"dada"
}
let name = "hello"
let { name } = user; //报错

({ name } = user); //正确
08.字符串扩展

字符串Unicode表示法

ES6加强了对Unicode的支持,允许采用\uxxxx形式表示一个字符, 中xxxx表示字符的Unicode码点。

Unicode

统一码(Unicode),也叫万国码、单一码,是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯-的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。

"\u0061"  //"a"

字符串遍历器接口

for...of循环遍历

var str = "hello";
for (var i of str) {
	console.log(i);
}
//等效于
for(var i=0; i<str.length; i++) {
	console.log(i);
}

模板字符串

模板字符串(template string)是增强版的字符串,用反引号(门) 标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。

var href = "https://itbaizhan.com";
var text = "百战";
//当我向页面动态写入标签的时候,标签的数据一般来源于服务器
var itbaizhan = "<a href='" + href + "'>" + text + "</a>";
//字符串模板
var itbaizhan1 = `<a href="${href}">${text}</a>`
console.log(itbaizhan);
console.log(itbaizhan1);  //<a href="https://itbaizhan.com">百战</a>
09.字符串新增方法

includes(), startsWith(), endsWith()
传统上, JavaScript 只有indexOf方法,可以用来确定一个字符串是否包含在另一 个字符串中。ES6 又提供了三种新方法。

  1. includes(): 返回布尔值,表示是否找到了参数字符串
  2. startsWith():返回布尔值,表示参数字符串是否在原字符串的头部
  3. endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部
var s = "Hello, world";
var s1 = "llo";
console.log(s.includes(s1)); //true
console.log(s.startsWith(s1)); //false
console.log(s.endsWith(s1)); //false

这三个方法都支持第二个参数,表示开始搜索的位置

let S = 'He11o world!';
s.startswith( 'wor1d',6) // true
s.endsWith('He11o',5) // true 
s.includes('He11o',6) // false

repeat()

repeat方法返回一个新字符串,表示将原字符串重复n次。

'hello'.repeat(2); //hellohello

padStart(),padEnd()

ES2017引入了字符串补全长度的功能。如果某个字符串不够指定长度,会在头部或尾部补全。padStart() 用于头部补全,padEnd() 用于尾部补全。

var h = "hello";
console.log(h.padStart(10, "ab"));//ababahello
console.log(h.padEnd(10, "ab")); //helloababa

trimStart(),trimEnd()
ES2019对字符串实例新增了trimStr()trimEnd()这两个方法。它们的行为与trim0一致, trimstar() 消除字符串头部的空格,trimEnd() 消除尾部的空格。它们返回的都是新字符串,不会修改原始字符串。

var h = "  hello   ";
console.log(h.trim());//"hello"
console.log(h.trimStart());//"hello   "
console.log(h.trimEnd());//"  hello"

at()
at()方法接受-个整数作为参数,返回参数指定位置的字符,支持负索引(即倒数的位置)

const str = 'hello';
str.at(1) //"e"
str.at(-1) //"o"
str.at(8) //undefined

温馨提示

如果参数超出位置,返回undefined

10.数组的扩展—扩展运算符

扩展运算符(spread)是三个点(…)。将一个数组转为用逗号分隔的参数序列

var arr = [10, 20, 30]
for (var i = 0; i < arr.length; i++) {
	console.log(arr[i]);
}
//扩展运算符
console.log(...arr); //10 20 30

替代函数的apply方法

由于扩展运算符可以展开数组,所以不再需要apply方法,将数组转为函数的参数了

 //求数组中的最大值
 var arr = [10, 20, 30]
 //ES5写法
 console.log(Math.max.apply(null, arr));
 //ES6写法
 console.log(Math.max(...arr));
 //等同于
 Math.max(10,20,30);

合并数组

 var arr1 = [10, 20, 30];
 var arr2 = [40, 50];
 console.log(arr1.concat(arr2)); //返回的是数组对象
 console.log(...arr1, ...arr2); //返回的字符串
 //若要返回数组对象,如下
 console.log([...arr1, ...arr2]);
11.数组扩展—新增方法

Array.from()
Aray.from()方法用于将类数组转为真正的数组

温馨提示

常见的类数组有三类:

arguments

//类数组(伪数组),只能使用数组的读取方式和length属性,不能使用数组方法:push
function add() {
    console.log(arguments); //读取到10,20,30
    console.log(arguments[0]); //10
    //arguments.push(40) 报错
    var result = Array.from(arguments); //转化
    result.push(40);
    console.log(result); //成功添加进去
}
add(10, 20, 30);

元素集合

<h3>标题1</h3>
<h3>标题2</h3>
<h3>标题3</h3>
<script>
//元素集合
let titles = document.querySelectorAll("h3");
console.log(titles[1]);  //<h3>标题2</h3>
console.log(Array.from(titles)) //转化
</script>

类似数组的对象

var user = {
	"0": "lili",
	"1": 20,
	"2": "男",
length: 3
}
console.log(user[0]); //lili
console.log(user[1]); //20
console.log(user.length); //3
console.log(Array.from(user)) //转化

Array.of()

Array.of()方法用于将一组值,转换为数组

Array.of(3,11,8) //[3,11,8]
12.对象的扩展

属性的简洁表示法

ES6允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。

var name = "iwen";
var user = {
//属性名和属性值为同样变量名称可省略
	name,   //等同于name:name
	age: 20,
//方法简写
	getname() {
		console.log(this.name);
	},
/*等同于
     getname:function(){
         console.log(this.name);
     }
*/
}
console.log(user.name);
user.getname(); 

这种写法用于函数的返回值,将会非常方便

function getPoint(){
	var x = 10.22;
	var y = 10.22;
	return {x,y};
	/*等同于
	return {x:x,y:y}*/
}
console.log(getPoint().x,getPoint().y);

属性名表达式

ES6允许字面量定义对象时,用表达式作为对象的属性名,即把表达式放在方括号内

//动态key
var ib = "hello"
var user = {
	[ib]: "web,java",
	age: 13,
	['a'+'bc']:31  //"[]"内可放语法
}
console.log(user);

对象的扩展运算符

//由于“...z”解开后不能打印
var z = { a: 10, b: 20 }
var x = { z }
var n = { ...z } //解开z对象,再放入“{}”中
console.log(x);     //{z: {…}}
console.log(n);     //{a: 10, b: 20}
13.函数的扩展—箭头函数

基本用法
ES6允许使用"箭头”(=>) 定义函数

var add=(x)=>x;
//等同于
var add = function (x) {
	return x;
};

如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分

var add = (x,y) => x+y;
//等同于
var add = function (x,y) {
	return x+y;
};

var add=()=>100;
//等同于
var add = function () {
	return 100;
};

如果箭头函数的代码块部分多于一条语询, 就要使用大括号将它们括起来,并且使用returm语句返回

var add = (x,y) => {
	var Z=10;
	return x+y+Z
};
//等同于
var add = function (x,y) {
	var Z=100
	return x+y+Z
};

由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。

var add = (x,y) => ({x:10,y:20});

箭头函数的一个用处是简化回调函数(匿名函数)

var arr = [10,20,30]
arr. map(item =>{
	console.log(item);
})

使用注意点
对于普通函数来说,内部的this指向函数运行时所在的对象,但是这一点对箭头函数不成立。它没有自己的this对象,内部的this就是定义时上层作用域中的this

var name ="itbaizhan"
var user= {
	name: "iwen" ,
	getName() {
		setTimeout(()=>{
			console.1og(this .name); // iwen
		})
        /*
        var that = this;
        setTimeout(function(){
        	console.1og(that.name); //iwen
			console.1og(this.name); // itbaizhan
		})
        */
	}	
}
user.getName()

温馨提示

箭头函数里面根本没有自己的this,而是引用外层的this

14.Set数据结构

基本用法

ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

Set本身是一一个构造函数,用来生成Set数据结构。

const = new Set();
[2,3,5,4,5,2,2]. forEach(x => s.add(x));
for(letiofs){
	console.1og(i);
}
//2 3 5 4

通过add()方法向Set结构加入成员,结果表明Set结构不会添加重复的值。

Set函数可以接收一个数组作为参数

const set = new Set([1,2,3,4]);
[...set]  //[1,2,3,4]

数组去除重复成员的方法

// 去除数组的重复成员
var array = [10,20,10,40,20]
[...new Set(array)]	//[10,20,40]

字符串去除重复字符

[...new Set(' ababbc')].join('')
// "abc"

向Set加入值的时候,不会发生类型转换,所以5和"5"是两个不同的值。

var mySet = new Set() ;
mySet.add("5")
mySet.add(5)
console. 1og(mySet); // Set(2) {'5', 5};

size属性

返回Set实例的成员总数

const items = new Set([1, 2, 3, 4,5, 5,5,5]);
items.size // 5
15.Set数据结构的方法

add()

set添加方法

var mySet = new Set() ;
mySet.add("5")
console.1og(mySet) ;

delete()

删除某个值,返回一个布尔值,表示删除是否

var mySet = new Set();
mySet.add("5")
var flag = mySet.delete("5");
console.1og(flag); // true

has()

返回一个布尔值,表示该值是否为Set的成员

var mySet = new Set();
mySet.add("5")
var flag = mySet.has("5");
console.1og(f1ag); // true

clear()

清除所有成员,没有返回值

var mySet = new Set();
mySet.add("5")
mySet.clear();
console.1og(mySet); // Set(0) {size: 0}
16.Promise对象

基本概念
Promise是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。 它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作) 的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的API,各种异步操作都可以用同样的方法进行处理

有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise 对象提供统一的接口, 使得控制异步操作更加容易

基本用法

ES6规定,Promise 对象是一个构造函数, 用来生成Promise实例

const promise = new Promi se(function(resolve,reject) {
	// ... some code
	if (/* 异步操作成功*/){
		resolve(value);
	} else {
	reject(error);
	}
});

Promise构造函数接受一个函数作为参数, 该函数的两个参数分别是resolve和reject。它们是两个函数,由JavaScript引擎提供,不用自己部署

Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。

promise.then(function(value) {
	// success
},function(error) {
	// failure
});

图片加载实例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="box"></div>
    <script>
        var box = document.getElementById("box");

        function loadImageAsync(url) {
            const promise = new Promise(function (resolve, reject) {
                //异步处理,消耗时间的代码
                const image = new Image(); //创建image对象
                image.src = url;
                image.onload = function () {
                    resolve(image);
                }
                image.onerror = function () {
                    reject(new Error("不能找到路径图片" + url))
                }
            })
            return promise;
        }
        const promise = loadImageAsync("http://edou.vip/nu_eacdq");
        promise.then(function (data) {
            //成功
            box.appendChild(data);
        }, function (error) {
            //失败
            box.innerHTML = "图片加载失败";
        })
    </script>
</body>

</html>
17.Promise对象—Ajax

Promise封装Ajax,让网络请求的异步操作变得更简单

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        //XHR对象
        const getJSON = function (url) {
            const promise = new Promise(function (resolve, reject) {
                //异步请求,网络请求代码
                const handler = function () {
                    if (this.readyState !== 4) {
                        return;
                    }
                    if (this.status == 200) {
                        resolve(this.response);
                    } else {
                        reject(new Error(this.statusText));
                    }
                }

                const client = new XMLHttpRequest();
                client.open("GET", url);
                client.onreadystatechange = handler;
                client.responseType = "json";
                client.setRequestHeader("Accept", "application/json");
                client.send();
            })

            return promise;
        }
        //实际操作中,只需要写以下代码,上述代码由框架提供
        getJSON("http://edou.vip/nu_eacdq")
            .then(data => {
                console.log(data);
            }, error => {
                console.log(error);
            })
    </script>
</body>

</html>
18.Async函数

ES2017标准引入了async函数——Generator函数的语法糖,使得异步操作变得更加方便

async函数可以将异步操作变为同步操作

//定时器是异步的
setTimeout(() => {
	console.log("定时器");
}, 10)
	console.log("hello");
}
print(); //hello 定时器


//Async
function timeout(ms) {
	//resolve是一个函数
	const promise = new Promise((resolve, reject) => {
		setTimeout(function () {
			console.log("定时器");
			resolve();
		}, ms);
	})
	return promise;
}

async function AsyncPrint(ms, value) {
	//把具有异步操作的代码前面放入:await
	await timeout(ms);  //先执行
	console.log(value); //再执行
}
AsyncPrint(100, "hello"); //定时器 hello

例子:如3个接口,第二接口需要第一个传入参数,第三个需要第二个传入参数

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./jquery-3.6.1.js"></script>
</head>

<body>
    <script>
//网络请求之间有没有用依赖关系?很多接口可能要依赖遇上一个接口的数据才能执行
        //异步变同步
        function ajax(url) {
            return new Promise(function (resolve, reject) {
                $.getJSON(url, function (result) {
                    resolve(result)
                }, function (error) {
                    reject(error)
                })
            })
        }
        //执行顺序并不是我们想法既定的,
        function getInfo() {
            var id = ajax("http://iwenwiki.com/api/generator/list.php");
            var info = ajax("http://iwenwiki.com/api/generator/id.php?id=" + id[0]);
            var result = ajax("http://iwenwiki.com/api/generator/name.php?name=" + info.name);
            result.then(data => {
                console.log(data);
            }, error => {
                console.log(error);
            })
        }
        getInfo();
        //使用async进行顺序既定
        async function asyncgetInfo() {
            var id = await ajax("http://iwenwiki.com/api/generator/list.php");
            var info = await ajax("http://iwenwiki.com/api/generator/id.php?id=" + id[0]);
            var result = await ajax("http://iwenwiki.com/api/generator/name.php?name=" + info.name);
            console.log(result);
        }
        asyncgetInfo();
    </script>
</body>

</html>
19.class的基本语法

类的由来
JavaScript语言中,生成实例对象的传统方法是通过构造函数

//ES5类的表现形式
function Person(name,age){
    this.name = name;
    this.age = age;
}   
Person.prototype.getName = function(){
    console.log(this.name);
}
var p =new Person("iwen",20);
p.getName();

ES6提供了更接近传统语言的写法,引入了Class (类)这个概念作为对象的模板。通过class关键字,可以定义类

基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能, ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已

//ES6
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    getName() {
        console.log(this.name);
    }
}
var p = new Person("iwen", 20);
p.getName();

constructor方法
constructor)方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一 个类必须有constuctor() 方法,如果没有显式定义,一个空的constructoro方法会被默认添加

class Person{
    
}
//等同于
class Person{
    constructor(){}
}

类的实例

生成类的实例的写法,与ES5完全-样,也是使用new命令

class Person{
    
}
var Person = new Person();

注意:

类不存在变量提升,这与ES5不同(变量提升:可先使用后定义,不会报错)

var Person = new Person();
class Person{
    
}
//报错
20.class的属性与方法

实例方法

通过类的实例对象调用方法

class People{
	say(){
		console.1og("He11o");
	}
}
var p = new Peop1e();
p.say()

实例属性

实例属性指的是类的实例对象可调用的属性

class People{
    constructor(name,age){
        this.name = name;
        this.age = age;
    }
    say(){
        console.1og(this.name,this.age);
    }
}
var p = new People("iwen" ,20);
p.say()
console.1og(p.name, p.age);

静态方法

类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前, 加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为"静态方法”

class Person {
    static classMethodO {
        console. 1og("He11o");
    }
}
Person.classMethodO // He11o
var p = new PersonO);
p.classMethod() // p.classMethod is not a function

温馨提示

注意,如果静态方法包含this关键字,这个this指的是类,而不是实例。

class People {
    static getsay() {
        this. say();
    }
    static say( {
        console.1og('he11o');
    }
    say() {
        console.1og('wor1d');
    }
People.getsay() // he11o

静态属性

静态属性指的是Class本身的属性,即ClasspropName

class Peop1e{}
People.status = "等待" //静态属性
console.1og(Peop1e.status); //等待
21.class的继承

基础用法

Class可以通过extends关键字实现继承,让子类继承父类的属性和方法。extends 的写法比ES5的原型链继承,要清晰和方便很多

class Point{
    
}
class ColorPoint extends Point{
    
}

ES6规定,子类必须在constructor()方法中调用super(),否则就会报错,这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,添加子类自己的实例属性和方法。如果不调用super()方法,子类就得不到自己的this对象

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    getname() {
        console.log(this.name);
    }
    static getInfo() {
        console.log("hello world");
    }
}
class Student extends Person {
    constructor(name, age, sno) {
        super(name, age,) //需要写
        this.sno = sno;
    }
    getsno() {
        console.log(this.sno);
    }
}
var s = new Student("小明", 24, 1001);
s.getname();
Student.getInfo();
s.getsno();
22.Module语法

历史上,JavaScript 一直没有模块(module) 体系,无法将一个大程序拆分成互相依赖的小文件, 再用简单的方法拼装起来。其他语言都有这项功能,比如Ruby的require. Python 的import,甚至就连CSS都有@import,但是JavaScript任何这方面的支持都没有,这对开发大型的复杂的项目形成了巨大障碍

ES6模块是通过export命令显式指定输出的代码,再通过import命令输入。

export var He11o = "he11o"// hel1o.js文件
import { He11o }from"./he11o.js" // index.js文件

测试方式

我们采用Nodejs方式进行测试Module语法

但是nodejs采用的是CommonJS的模块化规范,使用require引入模块;而import是ES6的模块化规范关键字。想要使用import,必须引入babe|转义支持,通过babei进行编译,使其变成node的模块化代码。

疑惑:为啥不用前端方式测试,前端方式测试会更加麻烦

第一步:全局安装babel-cli npm installl -g babel-cli

第二步:安装babel-preset- env npm install -D babel-preset-env

第三步:运行代码babel-node -presets env index.js

export命令

export命令导出变量

export var firstName =' sxt' ;
export var lastName = 'itbaizhan';
export var year = 2000;

export命令导出函数

export function add(x,y) {
	return X + y;
};
import { firstName,lastName,add } from "..."; //用”,“分隔

import命令

使用export命令定义了模块的对外接口以后,其他JS文件就可以通过import命令加载这个模块

// name.js
export var firstName = 'sxt';
export var lastName = 'itbaizhan';
export var year = 2000;
// main.js
import { firstName,lastName, year } from '. /profile.js';

如果想为输入的变量重新取一个名字,import 命令要使用as关键字,将输入的变量重命名

// value.js
export var value = 1;
// main.js
import { value as val } from './value.js';

除了指定加载某个输出值,还可以使用整体加载,即用星号(*) 指定一个对象,所有输出值都加载在这个对象上面

// circle.js
export function area(radius) {
	return Math.PI * radius * radius;
}
export function circumference(radius) {
	return 2 * Math.PI * radius;
}
// main.js
import { area, circumference } from ' ./circle';
//可以修改如下
import * as circle from './circle';
//调用
circle.area(11);

export default命令

从前面的例子可以看出,使用import 命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。但是,用户肯定希望快速上手,未必愿意阅读文档,去了解模块有哪些属性和方法为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export default命令,为模块指定默认输出。

// export-default.js
export default function () {
	console.1og(' foo');
}

其他模块加载该模块时,import 命令可以为该匿名函数指定任意名字

// import-default.js
import customName from ' ./export-default' ;
customName(); // 'foo'

注意:

一个文件中只能存在一个export default

JQuery学习笔记

​ jQuery 是一个快速、简洁的 JavaScript 框架。jQuery 设计的宗旨是“write Less,Do More”, 即倡导写更少的代码,做更多的事情。它封装 JavaScript 常用的功能代码,提供一种简便的 JavaScript 设计模式,优化 HTML 文档操作、事件处理、动画设计和 Ajax 交互。

​ jQuery 的核心特性可以总结为:具有独特的链式语法和短小清晰的多功能接口;具有高效灵活的 css 选择器,并且可对 CSS 选择器进行扩展;拥有便捷的插件扩展机制和丰富的插件。

​ 目前主版本号有 1、2、3 三个版本。最新版分别是 1.12.4、2.2.4(jquery-2.0 以上版本不再支持 IE 6/7/8)、3.6.1。

​ 详细的内容请参考对应版本的 API 文档。https://jquery.com/ 在线 API 1.12.1:http://hemin.cn/jq/index.html

优点:

​ (1)提供了强大的功能函数

​ (2)解决浏览器兼容性问题

​ (3)实现丰富的UI和插件

​ (4)纠正错误的脚本知识

安装:

在页面引入即可

<script src="./jquery-3.6.1.js"></script>

JQuery核心:

$符号在jQuery中代表对jQuery对象的引用, "jQuery"是核心对象。通过该对象可以获取jQuery对象,调用jQuery提供的方法等。只有Query对象才能调用jQuery提供的方法。

01.基本语法与对象

基本语法:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./jquery-3.6.1.js"></script>
</head>

<body>
    <div id="div1"></div>
    <script type="text/javascript">
        $(document).ready(function(){
            $("#div1").html("hello world");
        });
    </script>
</body>

</html>
02.Dom对象与Jquery包装集对象

原始的Dom对象只有DOM接口提供的方法和属性,通过js代码获取的对象都是dom对象;而通过jQuery获取的对象是jQuery包装集对象,简称jQuery对象,只有jQuery对象才 能使用jQuery提供的方法。

Dom对象

javascript中获取Dom对象,Dom对象只有有限的属性和方法:

 var divDom = document.getElementById("div");

Jquery包装集对象

可以说是Dom对象的扩充在jQuery的世界中将所有的对象,无论是一个还是一 组, 都封装成一个jQuery包集比如获取包含一个元素的jQuery包装集:

var divJquery = $("#div1");
console.log(divJquery);

获取的对象存在时,Dom返回的是Dom对象,或者对象集合,Jquery返回的是一个包装集

获取的对象不存在时,Dom返回的是unll,Jquery返回的依然是一个包装集(空的包装集)

Dom对象转Jquery对象

Dom对象转为jQuery对象,只需要利用$()方法进行包装即可

 var divDom = document.getElementById("div1");
 divJquery = $(divDom)

Jquery转对象Dom对象

jQueny对象转Dom对象,只需要取数组中的元素即可

var divjqueryTOdom = divJquery[0];//取Jquery包装集对象divJquery的元素

通过遍历jQuery对象数组得到的对象是Dom对象,可以通过$()转为jQuery对象

$(' #mydiv').each(unction() {//遍历
	var jquery = $(this);
});
03.Jquery选择器

​ 和使用j操作Dom-样,获取文档中的节对象是很频繁的一个操作,在jQuery中提供了简便的方式供我们查找|定位元素,称为jQuery选择器,选择器可以说是最考验-个人jQuery功力的地方,通俗的讲, Selector选择器就是"一个表示特殊语意的字符串"。只要把选择器字符串传入 上面的方法中就能够选择不同的Dom对象并且以jQuery包装集的形式返回。

​ jQuery选择器按照功能主要分为"选择和"过滤"。并且是配合使用的, 具体分类如下。基础选择器掌握即可,其他用到再查阅。

3.1基础选择器
选择器 名称 举例
id选择器 #id $(“#testDiv”)选择id为testDiv的元素
元素名称选择器 element $(“div”)选择所有div元素
类选择器 .class $(“.box1”)
选择所以选择器 * $(“*”)
组合选择器 selector1,selector2 $(“#testDiv,.box1”)
<div id="div1">id选择器</div>
<div class="t1">类目选择器</div>
<span>样式选择器</span>
<script type="text/javascript">
	var div1 = $("#div1");
	console.log(div1);
	var t1 = $(".t1");
	console.log(t1);
	var spans = $("span")
	console.log(spans);
</script>
3.2层次选择器
选择器 名称 举例
后代选择器 ancestor descendeant $(“#parent div”)选择id为parent的所有div元素
子代选择器 parent>child $(“#parent>div”)选择id为parent的直接div元素(第一代)
相邻选择器 prev+next $(“.blue+img”)选择css类为blue的下一个img元素
同辈选择器 prev~sibling $(“.blue~img”)选择css类为blue的之后的所有img元素
<div id="parent">层次择器
    <div id="child" class="testColor">父选择器
        <div class="gray">子选择器</div>
        <img src="https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png" width="270" height="129" />
        <img src="https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png" width="270" height="129" />
    </div>
    <div>
        选择器2<div>选择器2中的div</div>
    </div>
</div>
<script>
    var hd = $("#parent div")
    console.log(hd);
    var zd = $("#parent > div")
    console.log(zd);
    var xl = $("#child+div")
    console.log(xl);
    var tb = $(".gray~img")
    console.log(tb);
</script>
image-20221108105212242
3.3表单选择器
Forms 名称 举例
表单选择器 :input 查找所有的input玩素: $(“:input”); 注意:会匹配所有的input. textarea. select和button元素。
文本框选择器 :text 查找所有文本框: $(“:text”)
密码框选择器 :password 查找所有密码框: $(“:password”)
单选按钮选择器 :radio 查找所有单选按钮: $(“:radio”)
复选框选择器 :checkbox 查找所有复选框: $(“:checkbox”)
提交按钮选择器 :submit 查找所有提交按钮: $(“:submit”)
图像域选择器 :image 查找所有图像域: $(“:image”)
重置按钮选择器 :reset 查找所有重置按钮: $(“:reset”)
按钮选择器 :button 查找所有按钮: $(“:button”)
文件域选择器 :file 查找所有文件域: $(“:file”)
<form id=' myform' name="myform" method="post">
        <input type="hidden" name="uno" value="9999" disabled="disabled" />
        姓名:<input type="text" id="uname" name="uname" /><br />
        密码:<input type="password" id="upwd" name="upwd" value="123456" /><br />
        年龄: <input type="radio" name="uage" value="0" checked=" checked" />小屁孩
        <input type="radio" name="uage" value="1" />你懂得<br />
        爱好:<input type="checkbox" name="ufav" value="篮球" />篮球
        <input type="checkbox" name="ufav" value=“爬床" />爬床
        <input type="checkbox" name="ufav" value="代码" />代码<br />
        来自:<select id="ufrom" name="ufrom">
            <option value="-1" selected="selected">请选择</option>
            <option value="0">北京</option>
            <option value="1"> 上海</option>
        </select><br />
        简介:<textarea rows="10" co1s="30" name="uintro"></textarea><br />
        头像:<input type="file" /><br />
        <input type="image" src="http://www.baidu.com/img/bd_logo1.png'
        width=" 20" height="20" />
        <button type="submit" onclick="return checkForm();">提交 </button>
        <button type="reset">重置</button>
</form>

    <script>
        var input = $(":input");
        console.log(input);		//14个,包含了input,select,button,textarea
        var input2 = $("input")
        console.log(input2);	//10个 只找input
    </script>
04.Jquery Dom操作

​ jQuery也提供了对HTML节点的操作,而且在原生js的基础之上进行了优化,使用起来更加方便。常用的从几个方面来操作,查找元素(选择器已经实现) ;创建节点对象;访问和设置节点对象的值,以及属性;添加节点;删除节点;删除.添加、修改、设定节点的CSS样式等。注意**:以下的操作方式只适用于jQuery对象。**

4.1 操作元素的属性

获取属性

方法 说明 举例
attr 获取指定的属性值,操作checkbox时,选中返checked,没有选中返回undefined. attr('checked")
attr(‘name’)
prop 获取具有true和false两个属性的属性值 prop’"checked’)

操作元素的属性:

固有属性元素本身就有的属性 id name. class. style,特殊的img有src,a有href,等等
返回值是boolean的属性”checked.selected. disabled
自定义属性用户自己定义的属性

<input type="Checkbox" name="ch" checked="checked" id="aa" abc="aabbcc" />aa
<input type="Checkbox" name="ch" id="bb" />bb

<script>
//获取固有属性
var name1 = $("#aa").attr("name");
var name2 = $("#aa").prop("name");
console.log(name1);
console.log(name2);
//设置了checked属性的
var ck1 = $("#aa").attr("checked");
var ck2 = $("#aa").prop("checked");
console.log(ck1);
console.log(ck2);
//未设置checked属性
var ck3 = $("#bb").attr("checked");
var ck4 = $("#bb").prop("checked");
console.log(ck3);
console.log(ck4);
//获取自定义属性
var abc1 = $("#aa").attr("abc");
var abc2 = $("#aa").prop("abc");
console.log(abc1);
console.log(abc2);
</script>

image-20221108211556325

总结

attr与prop获取固有属性的元素返回的值相同

attr与prop获取boolean返回类型的元素属性时:

  • 元素属性设置了值的时候,attr返回的是相应的属性值,prop返回的是ture
  • 元素属性未设置值的时候,attr返回的是undefined,prop返回的是false

attr与prophu获取自定义返回类型的元素属性时:

  • attr可获取
  • prop不可获取(undefined)

设置属性

$("#aa").attr("value", "1")
$("#bb").attr("value", "2")
//设置返回值布尔类型的属性
$("#bb").attr("checked", "checked"); //设置checked属性为选中
$("#bb").prop("checked", false) //不选中
$("#bb").prop("checked", true)  //选中
//设置自定义属性
$("#aa").attr("uname","admin")  
$("#aa").prop("upwd","18") //不能操作,未设置

移除属性

//移除属性
$("#aa").removeAttr("checked", "checked") //移除checked属性

总结:如果属性的类型是boolean(checked,select,disable), 则使用prop()方法;否则使用attr()方法。

4.2 操作元素的样式

​ 对于元素的样式,也是一种属性, 由于样式用得特别多,所以对于样式除了当做属性处理外还可以有专门的方法进行处理。

方法 说明
attr(“class”) 获取class属性的值,即样式名称(类名)
attr(“class”,“样式名”) 修改class属性的值,修改样式
addClass(“样式名”) 添加样式名称
css() 添加具体的样式
removeClass(class) 移除样式名称
<input type="text" class="input1" id="i1">
    <p id="p1">hello world</p>
    <div id="div1"></div>
    <script>
        var in1 = $("#i1").attr("class");
        console.log(in1); //获取input1
        $("#i1").attr("class", "input2"); //成功修改为input2
        console.log($("#i1").attr("class"));
        $("#i1").addClass("hello")
        console.log($("#i1").attr("class")); //成功修改为input2 hello
        /* 相当于添加行内样式,优先级高
        格式:
        css("具体样式","样式值") 设置单个
        css({"具体样式":"样式值","具体样式":"样式值".....}) 设置多个
         */
        $("#p1").css("font-size", "40px");
        $("#div1").css({ "background-color": "red", "width": "200px", "height": "200px" })
        //移除样式
        $("#i1").removeClass("hello") //移除hello
    </script>

attr(“class”),attr(“class”,“样式名”),addClass(“样式名”),removeClass(class):对应增删改查功能,但都只作用于class(即类名值)

css()有两种添加样式的方式,可添加各种样式(如背景颜色,字体大小)

4.3操作元素的内容
方法 说明
html() 获取元素的html内容(非表单元素)
html(“内容”) 设定元素的html内容(非表单元素)
text() 获取元素的文本内容,不包含html(非表单元素)
text(“内容”) 设置元素的文本内容,不包含html(非表单元素)
val() 获取元素value值(表单元素)
val(值) 设定元素的value值(表单元素)

表单元素:

​ 文本框text,密码password,单选框radio,复选框checkbox,隐藏域hidden,文本域textarea,下拉框select

非表单元素:

​ div,span,h1~h6,table,tr,td,li,p等

<h3><span>html( )和text( )方法设置元素内容</span></h3>
    <div id="html"></div>
    <div id="text"></div>
    <div id="text1"></div>
    <div id="text2"></div>
    <div id="text3">
        <h2>北京</h2>
    </div>
    <input type="text" name="uname" value="oop" id="op" />

    <script>
        console.log($("#html").html());
        $("#html").html("<h2>上海</h2>");//标签正常识别
        $("#text").html("上海")
        $("#text1").text("北京")
        $("#text2").text("<h1>北京<h1>") //相当于传入文本<h1>北京<h1>
        console.log($("#html").html());
        console.log($("#text").html());
        console.log($("#text1").text());
        console.log($("#text2").text());
        console.log($("#text3").text()); //只能识别纯文本

        console.log($("#op").val());
        $("#op").val("hello")
        console.log($("#op").val());
    </script>
image-20221109224638501

总结:

只有使用html方法进行取值和赋值,才能识别标签

text方法只能识别文本,不能识别html标签

4.4创建元素和添加元素
方法 说明
prepend(content) 在被选元素内部的开头插入元素或内容,被追加content参数,可以是字符、HTML元素标记。
$(content).prependTo(selector) 把content元素或内容加入selector元素开头
append(content) 把content元素或内容插入selector元素内,默认是在尾部
$(content).appendTo(selector) 把content元素或内容插入selector元素内,默认是在尾部
before() 在元素前插入指定的元素或内容:$(selector).before(content)
after() 在元素后插入指定的元素或内容:$(selector).after(content)

创建元素:

$("内容")

添加元素:

  1. 前追加子元素
    1. 在指定元素内部的最前面追加内容,内容可以是字符串、htm1元素 或jquery对象。
指定元素. prepend(内容)

​ 2. 把内容追加到指定元素内部的最前面,内容可以是字符串、htm1元素或jquery对象。

$(内容). prependTo(指定元素) //若内容为字符串将其转换为jQuery对象
  1. 后追加子元素

    1. 在指定元素内部的最后面追加内容,内容可以是字符串、htm1元素 或jquery对象。
    指定元素. append(内容)
    
    1. 把内容追加到指定元素内部的最后面,内容可以是字符串、htm1元素或jquery对象。
    $(内容). append(指定元素) //若内容为字符串将其转换为jQuery对象
    
  2. 前追加同级元素

$(指定元素).before(内容)
  1. 后追加同级元素
$(指定元素).after(内容)
div {
    margin: 10px 0px;
}

span {
    color: white;
    padding: 8px
}

.red {
    background-color: red;
}

.blue {
    background-color: blue;
}

.green {
    background-color: green;
}

.pink {
    background-color: pink;
}

.gray {
    background-color: gray;
}
<body>
    <h3>prepend( )方法前追加内容</h3>
    <h3>prependTo( )方法前追加内容</h3>
    <h3>append()方法后追加内容</h3>
    <h3>appendTo( )方法后追加内容</h3>
    <span class="red">男神</span>
    <span class="blue">偶像</span>
    <div class="green">
        <span>小鲜肉</span>
    </div>

    <script>
        var span = "<span>hello</span>";
        $(".green").prepend(span);
        var span2 = "<span>word</span>";
        $(span2).prependTo($(".green"));
        $(".green").prepend($(".red")); //剪切类似
        //后追加与前追加相同
        var n1 = "<span class='pink'>奶奶滴</span>";
        var n2 = "<span class='gray'>奶奶滴</span>";
        $(".blue").before(n1);
        $(".blue").after(n2);   
    </script>
</body>

温馨提示:

在添加元素时,若元素本身为新定义的元素,会将元素添加,但若添加的元素为已有元素(本身存在),则相当于剪切元素到指定位置

4.5删除元素和遍历元素

删除元素

方法 说明
remove() 删除所选元素及其子元素,包括整个标签和内容一起删
empty() 清空所选元素的内容,保留标签
<style type="text/css">
span {
    color: white;
    padding: 8px;
    margin: 5px;
    float: left;
}

.green {
    background-color: green;
}

.blue {
    background-color: blue;
}
</style>
 <h3>删除元素 </h3>
<span class="green">jquery<a>删除 </a></span>
<span class="blue">javase</span>
<span class="green">http协议</span>
<span class="blue">servlet</span>
<script>
    $(".blue").remove();
    $(".green").empty();
</script>

遍历元素

each()

$(selector).each(function(index,element)) :遍历元素

参数function为遍历时的回调函数,

index为遍历元素的序列号,从0开始。

element是当前的元素,此时是dom元素。

<h3>遍历元素 eachO</h3>
<span class="green"> jquery</span>
<span class=" green"> javase</span>
<span class="green">http协议</span>
<span class="green">serv1et</span>
<script>
    // $(".green").each(function (index, element) {
    //     console.log(index);
    //     console.log(element);
    //     console.log(this);
    // });
    $('span').each(function (index, element) {
        console.log(index + "---->" + $(element).text());
    });
</script>
05.jQuery事件
5.1 ready加载事件

ready0类似于onLoad()事件

ready()可以写多个,按序执行

$(document).ready(function){)等价于$(function){})

作用:用于将script代码写在前面,必须进行预加载才能实现

<p id="p1">hello</p>
console.log($("#p1")); //找不到,空值 
//预加载
$(document).ready(function () {
	console.log($("#p1")); //可找到
})
//简写
$(function () {
	console.log($("#p1"));
})
5.2 bind绑定事件

为被选元素添加一个或多个事件处理程序,并规定事件发生时运行的函数。

$(selector).bind(eventType[,eventData], handler(eventobject));

eventType :是一个字符串类型的事件类型,就是你所需要绑定的事件。
这类类型可以包括如下:
lur, focus, focusin, focusout, load, resize, scroll, unload, click, dblclick,mousedown, mouseup, mousemove, mouseover, mouseout, mouseenter,mouseleave,change, select, submit, keydown, keypress, keyup, error
[,eventData]:传递的参数,格式: {名:值名2:值2}
handler(eventObject):该事件触发执行的函数

绑定单个事件

//bind绑定
$("元素").bind("",function(){
//...
})
//直接绑定
$("元素").事件名(function(){
//...
})
<h3>bindO方简单的绑定事件</h3>
<div id="test" sty1e=" cursor: pointer">点击查看各言</div>
<input id="btntest" type="button" value="点击就不可用了" />
<script>
    $("#test").bind("click", function () {
        console.log("hello world");
    });
    $("#btntest").click(function () {
        console.log(this);
        $(this).prop("disabled", true);
    })
</script>

绑定多个事件

//bind绑定
//1.同时为多个事件绑定同一个函数
指定元素.bind("事件1 事件2",function(){
//...
})
//2.为元素绑定多个事件,并设置对应的函数
指定元素.bind("事件类型",function)(){
   //... 
}).bind("事件类型",function)(){
    //...
})....
//3.为元素绑定多个事件,并设置对应的函数
事件类型.bind({"事件类型":function(){
    //...
},"事件类型":function(){
    //...
},...})
//直接绑定(常用)
指定元素.事件名(function(){
    //...
}).事件名(function(){
    //...
})
<button id="btn1">按钮1</button>
<button id="btn2">按钮2</button>
<button id="btn3">按钮3</button>
<button id="btn4">按钮4</button>
<script>
$("#btn1").bind("click mouseout", function () {
	console.log(this);
})

$("#btn2").bind("click", function () {
	console.log("按钮2点击");
}).bind("mouseout", function () {
	console.log("按钮2移开");
})

$("#btn3").bind({
	"click": function () {
		console.log("按钮3点击");
	},
	"mouseout": function () {
		console.log("按钮3移开");
	}
})


$("#btn4").click(function () {
	console.log("按钮4点击");
}).mouseout(function () {
	console.log("按钮4移开");
})
</script>
06.jQuery Ajax

Ajax:

1.异步无刷新技术

2.4种请求方式:$.ajax$.get$.post$.getJSON

6.1 $.ajax

jquery调用ajax方法:

​ 格式: $.ajax({});

​ 参数:
type:请求方式GET/POST

url:请求地址url

​ async:是否异步,默认是true表示异步

data:发送到服务器的数据

​ dataType:预期服务器返回的数据类型

​ contentType:设置请求头

success:请求成功时调用此函数

​ error:请求失败时调用此函数

get请求

data.json

[
    {
        "userId": 1,
        "userName": " zhangsan",
        "userAge": 18
    },
    {
        "userId": 2,
        "userName": "lisi",
        "userAge": 19
    },
    {
        "userId": 3,
        "userName ": "wangwu",
        "userAge": 20
    },
    {
        "userId": 4,
        "userName": " zhaoliu",
        "userAge": 21
    }
]
<!-- 点击按钮,通过ajax传递数据到页面 -->
    <button type="button" id="btn">查询数据</button>
    <script>
        $("#btn").click(function () {
            $.ajax({
                type: "get",
                url: "./data.json",
                data: {
                    //username: "张三" //如果没有参数,不需要设置
                },
                dataType: "json", //预期后端传入的类型,若为json格式,接收时自动封装为json对象
                success: function (data) { //data是形参名,代表的是后端传入的数据
                    console.log(data);
                    //dataType默认为txt的情况下,进行以下转化
                    //var obj = JSON.parse(data)
                    //console.log(obj);
                    
                    //Dom操作
                    var ul = $("<ul></ul>");
                    for (var i = 0; i < data.length; i++) {
                        var user = data[i];
                        var li = "<li>" + user.userName + "</li>";
                        ul.append(li);
                    }
                    $("body").append(ul);
                }
            })
        })
    </script>
6.2 get,.post,getJSON

​ 这是一个简单的GET请求功能以取代复杂$.ajax .
​ 请求成功时可调用回调函数。如果需要在出错时执行函数,请使用$.ajax

// 1. 请求json文件,忽略返回值
$.get('js/cuisine_ area. json');
//2.请求json文件,传递参数,忽略返回值
$.get(' js/cuisine. area. json' ,{name:"tom",age:100});
// 3. 请求json文件,拿到返回值,请求成功后可拿到返回值
$.get('js/cuisine_ area. json', function(data){
	console.1og(data);
});
// 4.请求json文件,传递参数,拿到返回值
$.get('js/cuisine_ area. json', {name:"tom",age:100},function(data){
	console.1og(data);
});
<script>
$.get("./data.json", {}, function (data) {
	console.log(data);
});
//需要服务器
$.post("./data.json", {}, function (data) {
	console.log(data);
});
//要求返回类型为JSON
$.getJSON("./data.json", {}, function (data) {
	console.log(data);
});
</script>

Node.js学习笔记

01.Node.js基础知识

Node.js是一个javascript运行环境。 它让javascript可以开发后端程序, 实现几乎其他后端语言实现的所有功能,可以与PHP、Java、 Python、 .NET. Ruby等后端语言 平起平坐。Nodejs是基于V8引擎, V8是Google发布的开JavaScript引擎 ,本身就是用于Chrome浏览器的js解释部分,但是Ryan Dahl这哥们,鬼才般的,把这个V8搬到了服务器上,用于做服务器的软件。

01.node.js的特性

  • Nodejs语法完全易is语法,只要你懂js基础就可以学会Nodejs后端开发
  • NodeJs超强的高并发能力,实现高性能服务器
  • 开发周期短、开发成本低、学习成本低

02.使用Node.js需要了解多少JavaScript

http://nodejs.cn/learn/how-much-javascript-do-you-need-to-know-to-use-nodejs

03.浏览器环境

image-20221125203602865

Node.js可以解析JS代码(没有浏览器安全级别的限制)提供跟多系统的API,如:

  • 文件的读写(File System)

    const fs = require('fs')
    fs. readFile(' ./ajax.png','utf-8', (err, content) => {
    	console. log(content)
    })
    
  • 进程的管理(Process)

    function main(argv) {
    console.1og(argv)
    main(process. argv. s1ice(2))
    
  • 网络通信(HTTP/HTTPS)

    const http = requi re ("http")
    http.createserver((req,res) => {
        res. writeHead(200,{
        	"content-type": "text/plain"
        })
        res. . write("he11o nodejs")
        res. end()
    }). listen(3000)
    

02.Node.js安装

大量的库

在安装Nodeis的同时,会附带一个ppm命令,npm是Node的包管理工具,这样正是接下来我们要用到的npm的简单结构有助于Node.js生态系统的激增,现在npm仓库托管了超过1,000,000个可以自由使用的开源库包

npm镜像

由于服务器在国外,所以下载速度比较慢,我们可以用国内的镜像

阿里镜像地址

https://npmmirror.com/

在命令行运行如下命令即可

npm insta1l -g cnpm --registry=https://regi stry. npmmi rror . com

03.模块-包-commonJS

01.为什么要有模块化开发

image-20221125205722410

02.CommonJS规范

image-20221125210549077

image-20221125210617539

03.modules模块化规范写法
我们可以把公共的功能抽离成为一个单独的js文件作为一个模块,默认情况下面这个模块里面的方法或者属性,外面是没法访问的。如果要让外部可以访问模块里面方法或者属性,就必须在模块里面通过exports或者module.exports暴露属性或者方法。

//a.js
function test() {
    console.log("aaa");
}
function upper() {
    console.log("ahh");
}
//暴露方法一:以对象形式
module.exports = {
    test, upper
}
//b.js
function test() {
    console.log("bbb");
}
//暴露方法二:直接使用exports
module.exports = test

//index.js
var moduleA = require('./a')
var moduleB = require('./b')
console.log(moduleA); 
//{ test: [Function: test], upper: [Function: upper] }
console.log(moduleB);
//[Function: test]
moduleA.test(); //调用对象里面的属性调用方法
moduleB();
moduleA.upper();

04.Npm&Yarn

4.1 npm的使用

npm init
npm insta11包名-g (uni nstal1 , update) //全局安装
npm insta11 包名--save-dev (uni nsta11,update )
npm list -g (不加-g, 列举当前目录下的安装包)
npm info包名(详细信息) npm info包名versi on(获取最新版本)
npm instal1 md5@1 (安装指定版本)
npm outdated( 检 查包是否已经过时)
"dependencies": { "md5": "^2.1.0” } ^ 表示如果直接npm insta11 将会安md5  2.*.*
最新版本
"dependencies": { "md5": "~2.1.0” } ~表示如果直接npm insta11 将会安装md5 2.1.*
最新版本
"dependencies": {"md5": "*”}  * 表示如果直接npm install将会安装md5最新版本
npm init //初始化(相当于在本地建一个库)
nmp i md5 //install简写为i,以md5为例子,添加别人的库

4.2 nrm全局安装

NRM (npm registry manager)是npm的镜像源管理工具,有时候国外资源太慢,使用这个就可以快速地在npm源间切换。

手动切换方法:

npm config set registry https://registry.npm.taobao. org

安装nrm

在命令行执行命令,npm install -g nrm,全局安装nrm.

使用nrm

执行命令nrm Is查看可选的源。其中, 带*的是当前使用的源,上面的输出表明当前源是官方源。

切换nrm

如果要切换到taobao源,执行命令nrm use taobao.

测试速度

你还可以通过nrm test测试相应源的响应时间。

nrm test

扩展(CNPM):

中国NPM镜像

这是一个完整nmpjs.org镜像,你可以用此代替官方版本(只读).同步频率目前为10分钟一次以保证尽量与官方服务同步。

npm insta11 -g cnpm --registry=https://registry. npmmi rror. com

CNPM与NPM相同,只不过CNPM安装后默认镜像为taobao

4.3 yarn的使用

npm install -g yarn
对比npm: 
	速度超快: Yarn 缓存了每个下载过的包,所以再次使用时无需重复下载。同时 利用并行下载以最大化资源利用
率,因此安装速度更快。
	超级安全:在执行代码之前,Yarn 会通过算法校验每个安装包的完整性。
开始新项目
	yarn init
添加依赖包
	yarn add [package]
	yarn add [package]@[version]
	yarn add [package] - -dev
升级依赖包
	yarn upgrade [package]@[version]
移除依赖包
	yarn remove [package]
安装项目的全部依赖
	yarn install

05.内置模块

5.1 http模块

要使用HTTP服务器和客户端,则必须require( 'http')

var http = require('http');
//创建服务器
http.createServer((req, res) => {
    //接收浏览器传的参数(req),返回渲染的内容(res)
    res.writeHead(200, { "Content-Type": "text/html;charset=utf-8" })
    //设置相应格式 200为状态码如404失败
    res.write(`
        <html>
            <b>我是加粗的字体</b>
        </html>
    `)
    res.end();
    // res.end("[1,2,3]")  //结束标志
}).listen(3000, () => {
    console.log("server started");
});

根据url不同,进行不同的操作:

var http = require('http');
//创建服务器
http.createServer((req, res) => {
    //接收浏览器传的参数(req),返回渲染的内容(res)
    if (req.url == "/favicon.ico") {
        //todo 读取本地图标
        return
    }
    console.log(req.url);
    res.writeHead(readerStatus(req.url), { "Content-Type": "text/html;charset=utf-8" })
    //设置相应格式 200为状态码如404失败
    res.write(readerHTML(req.url))
    res.end();
    // res.end("[1,2,3]")  //结束标志
}).listen(3000, () => {
    console.log("server started");
});
//根据url返回状态码
function readerStatus(url) {
    var arr = ["/home", "/list"]
    return arr.includes(url) ? 200 : 404
}
//根据url返回不同的页面/接口/对象
function readerHTML(url) {
    switch (url) {
        case "/home":
            return `
            <html>
                <b>我是home</b>
            </html>
            `
        case "/list":
            return `
            <html>
                <b>我是list</b>
            </html>
            `
        default:
            return `
            <html>
                <b>404</b>
            </html>
            `
    }
}

注意:

当访问url后接参数时,以上代码会失败,需要获取请求的url后进行进一步的拆解

如访问http:localhost://3000/list?name=100返回的url则是/list?name=100需要将?后面的部分拆解掉,可用下面的url模块

var http = require('http');
var url = require('url');
//创建服务器
http.createServer((req, res) => {
    //接收浏览器传的参数(req),返回渲染的内容(res)
    if (req.url == "/favicon.ico") {
        //todo 读取本地图标
        return
    }
    var urlObj = url.parse(req.url, true)
    //其中query返回的即uurl中的参数部分,(true)将参数封装为一个query对象
    var pathname = url.parse(req.url).pathname //进行url拆解,“?”后的参数截掉
    console.log(pathname);
    console.log(urlObj.query.name);
    res.writeHead(readerStatus(pathname), { "Content-Type": "text/html;charset=utf-8" })
    //设置相应格式 200为状态码如404失败
    res.write(readerHTML(pathname))
    res.end();
    // res.end("[1,2,3]")  //结束标志
}).listen(3000, () => {
    console.log("server started");
});
//根据url返回状态码
function readerStatus(url) {
    var arr = ["/home", "/list"]
    return arr.includes(url) ? 200 : 404
}
//根据url返回不同的页面/接口/对象
function readerHTML(url) {
    switch (url) {
        case "/home":
            return `
            <html>
                <b>我是home</b>
            </html>
            `
        case "/list":
            return `
            <html>
                <b>我是list</b>
            </html>
            `
        case "/apo":
            return {
                name: "apo",
                age: 18
            }
        default:
            return `
            <html>
                <b>404</b>
            </html>
            `
    }
}

5.2 url模块

1.pares

const ur1 = require('ur1')
const urlstring = 'https ://www. baidu. com:443/ad/i ndex. htm1?id=8&name=mouse#tag=11P '
const parsedstr = ur1.parse(urlstring)
console.1og(parsedstr)

2.format(已弃用)

const ur1 = require('ur1')
const ur1object = {
protocol: ' https:',
slashes: true ,
auth: nu11 ,
host: " www. bai du. com:443',
port: '443'
hostname:' www. baidu. com',
hash:' #tag=110' ,
search: ' ?id=8&name=mouse '
query: { id: '8', name: " mouse' },
pathname:, /ad/index. htm1',
path:' /ad/index. htm1?i d=8&name=mouse,
}
const parsedobj = ur1. format(ur1object) //将对象转为URL
console.1og(parsedobj)

3.resolve

//url的拼接
const ur1 = require('ur1')
// 注意最后加/,不加/的区别
var a = ur1. resolve(' /one/two/three', 'four') // /one/two/four
var a = ur1. resolve(' /one/two/three/', 'four') ///one/two/three/four
//域名/后的的内容都会被替换
var b = ur1. resolve('http://examp1e.com/', ' /one') //http://examp1e.com/one
var C = ur1. resolve('http://example.com/one', '/two') // http://examp1e.com/one
console.1og(a+","+b+","+c)

4.url模块新版

var urlObj = url.parse(req.url, true)
//其中query返回的即uurl中的参数部分,(true)将参数封装为一个query对象
var pathname = url.parse(req.url).pathname //进行url拆解,“?”后的参数截

新版:

const myURL = new URL(req.url, 'http://localhost:3000')
//相当于solve的拼接,然后new对象
console.log(myURL);
const pathname = myURL.pathname;
console.log(myURL.searchParams.get("name")); //myURL.searchParams返回的是一个集合
for (var [key, value] of myURL.searchParams) {
    console.log(key, value);
}

新版本参考文档

5.3 querystring模块

parse,stringify

var str = "name=zhangsan&age=18"
var queryString = require("querystring")
var obj = queryString.parse(str)
console.log(obj);
//[Object: null prototype] { name: 'zhangsan', age: '18' }
var myobj = {
    a: 1,
    b: 2,
    c: 3
}
var mystr = queryString.stringify(myobj)
console.log(mystr); //a=1&b=2&c=3

escape/unescape:防止sql注入

image-20221128195043725

这时正常情况下能查询到一条数据,如果将param修改成

let param= 'ns"-- ';

sq|语句就会变成

select * from tb_ nature where nature = "ns"--" and del _status=1

后面的del. status就会被参数中的–注释掉,失去作用,能查询到多条数据。

如果对param使用escape包装下,就能将参数中的特殊字符进行转义,防止sql的注入。

let sql= 'select * from tb. nature where nature = ' + mysql.escape(param) + ' and del status=1";
const querystring = require(' querystring')
var str = 'id=3&city=北京&ur1=https://www.baidu.com'
var escaped = querystring. escape(str)
console.1og(escaped)
const querystring = require(' querystring ')
var str = 'id%3D3%26city%3D%E5%8C%97%E4%BA%AC%26ur 1%3Dhttps%3A%2F%2Fwww.baidu.com '
var unescaped = querystring. unescape(str)
console.1og(unescaped)

5.4 http模块补充

5.4.1 跨域请求(jsonp和cors)

1.jsonp实现跨域请求

//jsonp.js
const http = require('http')
const url = require('url')
const app = http.createServer((req, res) => {
    let urlobj = url.parse(req.url, true)
    console.log(urlobj.query.callback); //从前端获取的callback
    switch (urlobj.pathname) {
        case '/api/aaa':
            res.end(`
            ${urlobj.query.callback} (${JSON.stringify(
                {
                    name: "hello",
                    age: 10
                }
            )})`)
            break
        default:
            res.end('404. ')
            break
    }
})
app.listen(3000, () => {
    console.log('localhost:3000')
})
//index.html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        var oscript = document.createElement("script")
        oscript.src = "http://localhost:3000/api/aaa?callback=test"
        document.body.appendChild(oscript)
        function test(obj) {
            console.log(obj);
        }
    </script>
</body>

</html>

2.cors可实现普通json的跨域

//cirs.js
const http = require('http')
const url = require('url')
const app = http.createServer((req, res) => {
    let urlobj = url.parse(req.url, true)
    // console.log(urlobj.query.callback);

    res.writeHead(200, {
        "Content-Type": "application/json,charset=utf-8",
        //cors头,解决跨域
        "access-control-allow-origin": "*"
    })
    switch (urlobj.pathname) {
        case '/api/aaa':
            res.end(`${JSON.stringify(
                {
                    name: "hello",
                    age: 10
                }
            )}`)
            break
        default:
            res.end('404. ')
            break
    }
})
app.listen(3000, () => {
    console.log('localhost:3000')
})
//index.html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        fetch("http://localhost:3000/api/aaa")
            .then(res => res.json())
            .then(res => {
                console.log(res);
            })
    </script>
</body>

</html>

5.4.2 get和post

1.get

Node作为客户端,向接口(API)发送请求,得到数据,在作为服务端向前端发送拿到的数据,这样就避免了前端对API的跨域请求拿不到数据的问题

//get.js
const http = require('http')
const https = require('https')
const url = require('url')
const app = http.createServer((req, res) => {
    let urlobj = url.parse(req.url, true)
    // console.log(urlobj.query.callback);

    res.writeHead(200, {
        "Content-Type": "application/json,charset=utf-8",
        //cors头,解决跨域
        "access-control-allow-origin": "*"
    })
    switch (urlobj.pathname) {
        case '/api/aaa':
            //客户端,去要猫眼数据
            httpget((data) => {
                res.end(data)
            })
            break
        default:
            res.end('404. ')
            break
    }
})
app.listen(3000, () => {
    console.log('localhost:3000')
})

function httpget(cb) {
    var data = ""
    //若请求域名为http开头则:
    // http.get()
    //若请求域名为https开头则:
    https.get(`https://i.maoyan.com/api/mmdb/movie/v3/list/hot.json?ct=%E4%B9%90%E5%B1%B1&ci=310&channelId=4`, (res) => {
        res.on("data", (chunk) => {
            data += chunk
        })
        res.on("end", () => {
            // console.log(data);
            // response.end(data)
            cb(data)
        })
    })
}
//index.html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        fetch("http://localhost:3000/api/aaa").then(res => res.json()).then(res => {
            console.log(res);
        })
    </script>
</body>

</html>

2.post

//post.js
const http = require('http')
const https = require('https')
const url = require('url')
const app = http.createServer((req, res) => {
    let urlobj = url.parse(req.url, true)
    // console.log(urlobj.query.callback);

    res.writeHead(200, {
        "Content-Type": "application/json,charset=utf-8",
        //cors头,解决跨域
        "access-control-allow-origin": "*"
    })
    switch (urlobj.pathname) {
        case '/api/aaa':
            //客户端,去要小米优品数据
            httppost((data) => {
                res.end(data)
            })
            break
        default:
            res.end('404. ')
            break
    }
})
app.listen(3000, () => {
    console.log('localhost:3000')
})

function httppost(cb) {
    var data = ""
    var options = {
        hostname: "m.xiaomiyoupin.com",
        port: "443",
        path: "/mtop/market/search/placeHolder",
        method: "POST",
        headers: {
            "Content-Type": "application/json"
        }
    }
    var req = https.request(options, (res) => {
        res.on('data', chunk => {
            data += chunk;
        })
        res.on('end', () => {
            cb(data)
        })
    })
    req.write(JSON.stringify([{}, { "baseParam": { "ypClient": 1 } }]))
    req.end();
}
//index.html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        fetch("http://localhost:3000/api/aaa").then(res => res.json()).then(res => {
            console.log(res);
        })
    </script>
</body>

</html>

5.4.3 爬虫

const http = require('http')
const https = require('https')
const url = require('url')
const cheerio = require('cheerio') //需要cheerio模块
const app = http.createServer((req, res) => {
    let urlobj = url.parse(req.url, true)
    // console.log(urlobj.query.callback);

    res.writeHead(200, {
        "Content-Type": "application/json,charset=utf-8",
        //cors头,解决跨域
        "access-control-allow-origin": "*"
    })
    switch (urlobj.pathname) {
        case '/api/aaa':
            //客户端,去要猫眼数据
            httpget((data) => {
                res.end(spider(data))
            })
            break
        default:
            res.end('404. ')
            break
    }
})
app.listen(3000, () => {
    console.log('localhost:3000')
})

function httpget(cb) {
    var data = ""
    //若请求域名为http开头则:
    // http.get()
    //若请求域名为https开头则:
    https.get(`https://i.maoyan.com/`, (res) => {
        res.on("data", (chunk) => {
            data += chunk
        })
        res.on("end", () => {
            console.log(data);
            // response.end(data)
            cb(data)
        })
    })
}

function spider(data) {
    //cheerio
    let $ = cheerio.load(data)
    let $moviewlist = $(".column.content")
    // console.log($moviewlist);
    let movies = []
    $moviewlist.each((index, value) => {
        movies.push({
            title: $(value).find(".title").text(),
            grade: $(value).find(".grade").text(),
            actor: $(value).find(".actor").text(),
        })
    })
    console.log(movies);
    return JSON.stringify(movies)
}

5.5 envent模块

可自定义事件监听和触发

const EventEmitter = require('events');
const event = new EventEmitter();
event.on("play", (data) => {        //监听事件play
    console.log("事件触发", data);
})
event.emit("play", "1111"); //可传值

5.6 fs文件操作模块

const fs = require('fs');
//创建目录
fs.mkdir("./avatar", (error) => {
    if (error && error.code === "ENOENT") {
        console.log("目录存在");
    }
})
//更改目录名
fs.rename("./avatar", "./hello", (err) => {
    // console.log(err);
    if (err && err.code === "ENOENT") {
        console.log("目录不存在");
    }
})
//删除目录(需其内无文件)
fs.rmdir("./hello", err => {
    console.log(err);
})
//读取目录内文件
fs.readdir("./avatar", (err, data) => {
    if (!err) {
        console.log(data);
    }
})
//创建文件
fs.writeFile("./avatar/a.txt", "hello world", (data) => {
    console.log(data);
}) //无文件则创建,有文件则覆盖
//追加内容
fs.appendFile("./avatar/a.txt", "\nhhh", (data) => {
    console.log(data);
}) 
//删除文件
fs.unlink("./avatar/a.txt", err => {
    console.log(err);
})
//读取文件
fs.readFile("./avatar/a.txt", "utf-8", (err, data) => {
    if (!err) {
        // console.log(data.toString("utf-8"));
        console.log(data);
    }
})
//目录中文件详细信息
fs.stat("./avatar", (err, data) => {
    console.log(data);
})

注意:以上操作都是异步操作

//同步读取文件
try {
	const content = fs. readFilesync('. /1ogs/1og-1.txt','utf-8')
	console.1og(content)
	console.1og(0)
} catch (e) {
	console.1og(e . message)
}
//异步读取文件:方法一
fs. readFile(' ./1ogs/1og-0.txt','utf-8', Cerr, content) => {
console. log(content)
console.1og(0)
})
console.1og(1)
//异步读取文件:方法二
const fs = require("fs"). promises
fs.readFile('./1ogs/1og-0. txt', 'utf-8').then(resut => {
console.1og(resu1t)
})

在fs模块中,提供同步方法是为了方便使用。那我们到底是应该用异步方法还是同步方法呢?

由于Node环境执行的JavaScript代码是服务器端代码,所以,绝大部分需要在服务器运行期反复执行业务逻辑的代码,必须使用异步代码,否则,同步代码在执行时期,服务器将停止响应,因为JavaScript只有一 个执行线程。

服务器启动时如果需要读取配置文件,或者结束时需要写入到状态文件时,可以使用同步代码,因为这些代码只在启动和结束时执行一次,不影响服务器正常运行时的异步执行。

5.7 stream流

stream是Node.js提供的又一个仅在服务区端可用的模块,目的是支持流’这种数据结构。

什么是流?流是一种抽象的数据结构。 想象水流,当在水管中流动时,就可以从某个地方(例如自来水厂)源源不断地到达另一个地方(比如你家的洗手池)。我们也可以把数据看成是数据流,比如你敲键盘的时候,就可以把每个字符依次连起来,看成字符流。这个流是从键盘输入到应用程序,实际上它还对应着-个名字:标准输入流(stdin)。

如果应用程序把字符一个一个输出到显示器上,这也可以看成是一一个流, 这个流也有名字:标准输出流(stdout)。流的特点是数据是有序的,而且必须依次读取,或者依次写入,不能像Array那样随机定位。

有些流用来读取数据,比如从文件读取数据时,可以打开-一个文件流, 然后从文件流中不断地读取数据。有些流用来写入数据,比如向文件写入数据时,只需要把数据不断地往文件流中写进去就可以了。

在Node.js中,流也是一个对象, 我们只需要响应流的事件就可以了: data 事件表示流的数据已经可以读取了,end事件表示这个流已经到末尾了,没有数据可以读取了,error 事件表示出错了。

//打开文件流
const fs = require('fs')
const rs = fs.ReadStream("./1.txt", "utf-8")
rs.on("data", (chunk) => {
    console.log("chunk", chunk);
})
rs.on("end", () => {
    console.log("end");
})
rs.on("error", (err) => {
    console.log(err);
})

要注意,data 事件可能会有多次,每次传递的chunk是流的一部分数据。
要以流的形式写入文件,只需要不断调用write(方法,最后以end()结束:

//写入文件流
const fs = require('fs')
const ws = fs.WriteStream("./2.txt", "utf8")
ws.write("11111111")
ws.write("12222222")
ws.write("11133333")
ws.write("111114544")
ws.end();

pipe就像可以把两个水管串成一个更长的水管-样,两个流也可以串起来。-个Readable流和-个writable流串起来后,所有的数据自动从Readable流进入writable流,这种操作叫pipe。

在Node.js中,Readable 流有一个pipe()方法,就是用来干这件事的。
让我们用pipe()把一个文件流和另一一个文件流串起来,这样源文件的所有数据就自动写入到目标文件里了,所以,这实际上是一一个复制文件的程序:

const fs = require('fs');
//高性能的复制文件的方法
const readStream = fs.createReadStream("./1.txt");
const writeStream = fs.createWriteStream("./2.txt");
readStream.pipe(writeStream); //管道连接

5.8 zlib

在服务端与客户端传输文件过程中对文件进行类似于压缩的形式传递,即服务端采用(zlib)方式将文件传输到客户端,客户端浏览器在用响应方式解压

image-20230220212121485
const fs = require('fs')
const z1ib = require('z1ib')
const gzip = zlib.createGzip()

const readstream = fs.createReadstream(' ./note.txt')
const writestream = fs.createwritestream(' ./note2.txt ' )
readstream
    . pipe(gzip)
    . pipe(writestream)

5.9 cryto

crypto模块的目的是为了提供通用的加密和哈希算法。用纯JavaScript代码实现这些功能不是不可能, 但速度会非常慢。Nodejs用C/C++实现这些算法后,通过cypto这个模块暴露为JavaScript接口,这样用起来方便,运行速度也快。

MD5是一种常用的哈希算法,用于给任意数据一个“签名”。这个签名通常用一个十六进制的字符串表示:

const crypto = require('crypto');
const hash = crypto.createHash('md5');
//可任意多次调用update():
hash.update('He11o,world! ');
hash.update('He11o, nodejs!');
console.log(hash.digest('hex'));

update()方法默认字符串编码为UTF-8,也可以传入Buffer.

如果要计算SHA1,只需要把’md5’改成’shal’,就可以得到SHA1的结果


Hmac算法也是一种哈希算法,它可以利用MD5或SHA1等哈希算法。不同的是,Hmac还需要一个密钥 :

const crypto = require('crypto');
const hmac = crypto.createHmac('sha256','secret-key');
hmac. update(' He11o, world!');
hmac. update(' He11o, nodejs!');
console. log(hmac.digest('hex)); // 80f7e22570...

只要密钥发生了变化,那么同样的输入数据也会得到不同的签名,因此,可以把Hmac理解为用随机数“增强"的哈希算法。


AES是一-种常用的对称加密算法,加解密都用同一个密钥。crypto模块提供了AES支持,但是需要自己封装好函数,便于使用:

const crypto = require("crypto");
function encrypt (key,iv, data) {
    let decipher = crypto.createCipheriv('aes-128-cbc', key, iv);
    // decipher.setAutopadding(true);
    return decipher.update(data,'binary', 'hex') + decipher.final('hex');
}
function decrypt (key,iv,crypted) {
    crypted = Buffer.from(crypted, 'hex').tostring('binary');
    1et decipher = crypto.createDecipheriv(C'aes-128-cbc', key, iv);
    return decipher.update(crypted, 'binary', 'utf8') + decipher.final('utf8');
}

可以看出,加密后的字符串通过解密又得到了原始内容。

06.路由

6.1 基础1

//server.js 创建服务器
const { log } = require('console');
const route = require("./route")
const http = require('http')
http.createServer((req, res) => {
    const myURL = new URL(req.url, "http://localhost")
    // route(res, myURL.pathname) 方案一,方法形式
    route[myURL.pathname](res);
    res.end()
}).listen(3000, () => {
    console.log("server started");
})
//route.js
const { Module } = require("module")
const fs = require("fs")
//最原始方案
// function route(res, pathname) {
//     switch (pathname) {
//         case "/login":
//             res.writeHead(200, { 'Content-Type': 'text/html;utf-8' })
//             res.write(fs.readFileSync("./static/login.html"), "utf-8")
//             break
//         case "/home":
//             res.writeHead(200, { 'Content-Type': 'text/html;utf-8' })
//             res.write(fs.readFileSync("./static/home.html"), "utf-8")
//             break
//         default:
//             res.writeHead(404, { 'Content-Type': 'text/html;utf-8' })
//             res.write(fs.readFileSync("./static/404.html"), "utf-8")
//     }
// }

//写为对象
const route = {
    "/login": (res) => {
        res.writeHead(200, { 'Content-Type': 'text/html;utf-8' })
        res.write(fs.readFileSync("./static/login.html"), "utf-8")
    },
    "/home": (res) => {
        res.writeHead(200, { 'Content-Type': 'text/html;utf-8' })
        res.write(fs.readFileSync("./static/home.html"), "utf-8")
    },
    "/404": (res) => {
        res.writeHead(404, { 'Content-Type': 'text/html;utf-8' })
        res.write(fs.readFileSync("./static/404.html"), "utf-8")
    }
}
module.exports = route

6.2 基础2

加入图标,解耦合,加入api

//index.js
const server = require('./server')
const route = require("./route")
const api = require("./api")
//注册路由
server.use(route)
server.use(api)
server.start()
//server.js
const route = require("./route")
const http = require('http')
const api = require('./api')

const Router = {}

function use(obj) {
    Object.assign(Router, obj)
}

function start() {
    http.createServer((req, res) => {
        const myURL = new URL(req.url, "http://localhost")
        try {
            Router[myURL.pathname](res);
        } catch (error) {
            Router["/404"](res)
        }
    }).listen(3000, () => {
        console.log("server started");
    })
}
exports.use = use;
exports.start = start;
//route.js 
const { Module } = require("module")
const fs = require("fs")
const route = {
    "/login": (res) => {
        render(res, "./static/login.html")
    },
    "/home": (res) => {
        render(res, "./static/home.html")
    },
    "/404": (res) => {
        render(res, "./static/404.html", 404)
        res.end()
    },
    "/favicon.ico": (res) => {
        render(res, "./static/bitbug_favicon.ico", 200, "image/X-icon")
    }
}
function render(res, path, code = 200, type = "text/html;utf-8") {
    res.writeHead(code, { 'Content-Type': type })
    res.write(fs.readFileSync(path), "utf-8")
    res.end()
}
module.exports = route
//api.js
function render(res, data, type = "application/json;utf-8") {
    res.writeHead(200, { 'Content-Type': type })
    res.write(data)
    res.end()
}
const apiRouter = {
    "/api/login": (res) => {
        render(res, `{ok:1}`)
    }
}
module.exports = apiRouter

6.3 获取请求参数

在基础2的情况下,添加对请求参数的传递与操作

//login.html
<body>
    <div>
        用户名:<input type="text" id="username">
    </div>
    <div>
        密 码:<input type="password" id="password">
    </div>
    <div>
        <button id="login">登录</button>
        <button id="login2">登录post</button>
    </div>
    <script>
        var login = document.getElementById("login");
        var login2 = document.getElementById("login2");
        var password = document.getElementById("password");
        var username = document.getElementById("username");
        login.onclick = () => {
            //get请求
            fetch(`/api/login?username=${username.value}&password=${password.value}`).then(res => res.text()).then(res => {
                console.log(res);
            })
        }
        login2.onclick = () => {
            //post请求
            fetch(`/api/loginpost`, {
                method: 'POST',
                body: JSON.stringify({
                    username: username.value,
                    password: password.value
                }),
                headers: {
                    "Content-Type": "application/json"
                }
            }).then(res => res.text()).then(res => {
                console.log(res);
            })
        }
    </script>
</body>
function render(res, data, type = "application/json;utf-8") {
    res.writeHead(200, { 'Content-Type': type })
    res.write(data)
    res.end()
}
const apiRouter = {
    "/api/login": (req, res) => {
        const myURL = new URL(req.url, "http://localhost")
        if (myURL.searchParams.get("username") == "zhangsan" && myURL.searchParams.get("password") == "123456") {
            render(res, `{"ok":ture}`)
        } else {
            render(res, `{"ok":false}`)
        }
    },
    "/api/loginpost": (req, res) => {
        var post = ''
        req.on("data", chunk => {
            post += chunk
        })
        req.on("end", () => {
            // console.log(post);
            post = JSON.parse(post)
            if (post.username == "zhangsan" && post.password == "123456") {
                render(res, `{"ok":ture}`)
            } else {
                render(res, `{"ok":false
            }
        })
    }
}
module.exports = apiRouter

6.4 静态资源

在上面的基础上对login.html添加css,同时将之前的js单独拿出来,js和css都分别单独放在static文件夹下的js和css文件夹下

const { Module } = require("module")
const fs = require("fs")
const mime = require("mime") //需要npm安装该模块
const path = require("path")
const route = {
    "/login": (req, res) => {
        render(res, "./static/login.html")
    },
    "/home": (req, res) => {
        render(res, "./static/home.html")
    },
    "/404": (req, res) => {
        if (readStaticFiles(req, res)) {
            return
        }
        render(res, "./static/404.html", 404)
        res.end()
    },
    //添加静态资源管理后,默认找favicon.ico时可找到
    // "/favicon.ico": (req, res) => {
    //     render(res, "./static/favicon.ico", 200, "image/X-icon")
    // }
}
function render(res, path, code = 200, type = "text/html;utf-8") {
    res.writeHead(code, { 'Content-Type': type })
    res.write(fs.readFileSync(path), "utf-8")
    res.end()
}
//静态资源管理
function readStaticFiles(req, res) {
    //获取路径
    const myURL = new URL(req.url, "http://localhost")
    const pathname = path.join(__dirname, "/static", myURL.pathname)
    if (myURL.pathname === "/") return false
    //判断是否存在
    if (fs.existsSync(pathname)) {
        render(res, pathname, 200, mime.getType(myURL.pathname.split(".")[1]))
        return true
    } else {
        return false
    }
}
module.exports = route

Vue学习笔记