前端手写复习资料

HTML

标题标签

<h1>我是一个标签<h1>

  • 标题一共分六级
  • 文字加粗一行选
  • 由大到小依次减
  • 从重到轻随之变
  • 语法规范书写后
  • 具体效果刷新见

段落和换行标签

<p>我是一个段落<p>

  • 标签独占一行,行与行之间有间距

<br />我是一个换行标签

  • 换行标签,唯一一个单标签,换行后行与行之间没有间距

文本格式化标签

<strong> <\strong>、<em> <\em>、<del> <\del>、<ins> <\ins>我是文本可是化标签

语义标签
加粗strong
倾斜em
删除线del
下划线ins

盒子标签

<span> <div>我是盒子标签

盒子类型说明
div盒子独占一行
span盒子一行中可以有多个

图像标签

<img>我是图像标签

属性说明
src路径,必要属性
alt替换文本
title提示文本
width图像宽度
height图像高度
border图像边框粗细

超链接

<a>我是一个超链接

属性说明
href用于链接目标的url地址
target用于链接页面的打开方式,_self为默认值,_blank为新窗口打开方式

超链接分类

  1. 外部链接:例如

    <a href="hettp://www.baidu.com">百度<a />
  2. 内部链接:例如

    <a href="index.html">首页<a />
  3. 空链接:

    <a href="#">
  4. 下载链接:

    <a href="文件地址">下载<a />
  5. 网页元素链接:

    <a href="XXXX"><xxx><xxx /><a />
  6. 描点链接:

    <a href="#id值"><a />

表格标签

<table> 
    <tr><td><td /><tr />
    <tr><td><td /><tr />
<table />
我是表格标签

属性说明
align对其反方式:left、right、center
border边框
cellsapadding单元边与内容的空白
cellsapacing单元边之间的空白
width规定表格的宽度

合并单元格

属性说明
rowspan行合并
colspan列合并

表头标签

<th> 我是表头标签

列表标签

有序列表

<ol>
    <li></li>
    <li></li>
</ol>
我是无序列表
1、<ol></ol>中只能嵌套<li></li>,直接在<ol></ol>标签中输入其他标签或者文字的做法是不被允许的。
2、<li>与<li>之间相当于一个容器,可以容纳说有元素。
3、有序列表会带有自己样式属性,但在实际使用时,我们会使用Css来设置

无序列表

<ul>
    <li></li>
    <li></li>
</ul>
我是有序列表
1、<ul></ul>中只能嵌套<li></li>,直接在<ul></ul>标签中输入其他标签或者文字的做法是不被允许的。
2、<li>与<li>之间相当于一个容器,可以容纳说有元素。
3、有序列表会带有自己样式属性,但在实际使用时,我们会使用Css来设置

自定义列表

<dl>
    <dt></dt>
    <dd></dd>
    <dd></dd>
</dl>
我是自定义列表
1、<dl></dl>里面只能包含<dt>和<dd>。
2、<dt>和<dd>个数没有限制,经常是一个<dt>对应多个<dd>

表单标签

表单域

<form> 只是表单标签

属性说明
actionurl地址
methodget/post设置表单数据的提交方式
name名称,区分不同的表单域

表单元素

<input> 只是表单元素

type属性的属性值及其说明描述如下:

属性值描述
button点选按钮
checkbox复选框
file文件上传
hidden隐藏的输入字段
image义图像按钮
password密码字段
radio单选按钮
reset重置按钮
submit提交按钮
text输入字段

<lable for="id值">    
<select>   下拉表单元素
<textarea>  文本域标签

HTML5

HTML新增加的语义化标签

<header>: 头部标签
<nav>: 导航标签
<article>: 内容标签
<section>: 定义文档某个区域
<aside>: 侧边栏标签
<footer>: 尾部标签
        <header>
         <nav>
<article>       <aside>
<section>
        <footer>

HTML新增的多媒体标签

1、视频<video>
当前<video>元素支持三种视频格式:尽量使用MP4格式。
    <video 
        src:   视频url地址
        autoplay:   视频就绪自动播放
        controls:   向用户显示播放控件
        width:   设置播放器宽度
        height:   设置播放器高度
        loop:   播放完是否预加载视频(如果有了autoplay 就忽略该属性)
        preload:  规定是否预加载视频
        poster:   加载等待的画图图片
        muter:   静音播放
    >
2、音频<audio>
当前<audio>在不使用插件的情况下,也可以原生的支持音频格式文件的播放,当然支持的格式是有限的。
    <audio
        autoplay:   如果出现该属性,则音频在就绪后马上播放
        controls:   如果出现该属性,则向用户显示控件,比如播放按钮。
        loop:如果出现该属性,则每当音频结束时重新开始播放。
        scr:要播放的音频的URL。
    >

HTML5新增的input类型

type='email'           限制用户输入必须为email类型
type='url'             限制用户输入必须为URL类型
type='date'            限制用户输入必须为日期类型
type='time'
type='month'
type='week'
type='number'
type='tel'
type='search'
type='color'

HTML5新增的表单属性

required        表单拥有该属性表示其内容不能为空
placeholder     表单的提示信息,存在默认值将不显示
autofocus       自动聚焦属性,页面加载完成自动聚焦到指定表单
autocomplete    当用户在字段开始键入时,浏览器基于之前键入过的值,应当显示出在字段中填写的选项。 
multiple        可以多选文件提交。

CSS

基础选择器

标签选择器          h1 {}
类选择器           .类名{}
id选择器           #id值{}
通配符选择器        *{}        

复合选择器

后代选择器         h1  p{}   
子元素选择器       h1 > p{}  
并集选择器        h1,h2{}
链接伪类选择器     a:hover{}  a:link{}  a:visited{}    a:action{}  

字体

font-family  设置字体系列
font-size    设置字号大小
font-weight  设置字体粗细
font-style   设置字体样式

文本

color        设置文本颜色
text-align   设置文本对齐
text-decoration 设置文本装饰
text-indent   设置文本缩进
line-hight   设置文本行间距

元素显示模式

块元素<h1>~<h6>、<p>、<div>、<ol>、<ul>、<li>
行内元素<a>、<Strong>、<i>、<del>、<s>、<ins>、<u>、<span>
行类块元素<img>、<input>、<td>

背景

背景颜色  background-color
背景图片  background-image
背景平铺  background-repeat
背景固定  background-attachment
背景位置  background-position

三大特性

层叠性    样式冲突就近原则,样式不冲突,不会层叠
继承性    子标签会继承父标签的某些样式。
优先级    选择器的权重。

盒子模型

边框 border
    边框粗细 border-width
    边框样式 border-style
    边框颜色 border-color
    注意边框会影响盒子大小
内容 content 
内边距 padding
    左内边距  padding-left
    右内边距  padding-right
    上内边距  padding-top
    下内边距  padding-bottom
    注意内边距会影响盒子大小
外边距 margin
    左外边距  margin-left
    右外边距  margin-right
    上外边距  margin-top
    下外边距  margin-bottom

块级盒子水平居中

1、盒子必须指定宽度。
2、盒子左右的外边距都设置为auto。

行内级、行内块盒子居中

1、父类盒子加上text-align。

外边距合并问题

1、相邻元素垂直外边距合并---取大值。
2、嵌套块元素塌陷---取大值。  
	解决方法:
		为父元素定义上边框。
		为父元素定义上内边距。
		为父元素添加overflower:hidden。

圆角边框

圆角边框半径  boder-radius

盒子阴影

水平阴影  h-shadow
垂直阴影  v-shadow
模糊距离  blur
阴影尺寸  spread
阴影颜色  color
内部阴影  inset
注意不占用空间,不会影响其他盒子排列。

文字阴影

水平阴影  h-shadow
垂直阴影  v-shadow
模糊距离  blur
阴影颜色  color

浮动

1、浮动脱离标准流
2、浮动的盒子不再保留原来的位置
一行显示
具有行内块特性
浮动可以压住盒子,不会压住文字
浮动 float

定位

定位 postion
相对定位  postion:relative   它于原来的位置
静态定位  postion:static   没有边偏移,遵循标准流
绝对定位  postion:absolute   没有父元素或者父元素没有定位,按照文档对齐。脱标不占有以前位置。
固定定位  postion:fixed  不占原来的位置
	注意子绝父相。
定位在父盒子类的纸盒子的定位
上边线距离:top
下边线距离:bottom
左边线距离:left
右边线距离:right
定位叠放次序: z-index
绝对定位和固定定位会压住文字和盒子

绝对定位的盒子居中对齐

position:absolute
top:50%
left:50%
marger-left: -length
marger-top: -length

元素的显示和隐藏

显示隐藏 display
显示隐藏 visibility
溢出隐藏 overflow

精灵图

利用background-postion原理

字体图标

http://icomoon.io  

CSS三角

盒子为0
设置边框

CSS3

CSS3新增选择器

1、属性选择器
    E[att]          选择具有att属性的E元素
    E[att="val"]    选择具有att属性且属性值等于val的E元素
    E[att^="val"]   匹配具有att属性且值以val开头的E元素
    E[att$="val"]   匹配具有att属性且值以val结尾的E元素
    E[att*="val"]   匹配具有att属性且值中含有val的E元素。
2、结构伪类选择器
    E:first-child  匹配父元素中的第一个子元素E
    E:last-child   匹配父元素中最后一个E元素
    E:nth-child(n)   匹配父元素的第n个子元素E
    E:first-of-type  指定类型E的最后一个
    E:last-of-type    指定类型E的最后一个
    E:nth-of-type(n)   指定类型E的第n个
3、伪类元素选择器
    ::before      在元素内部的前面插入内容 
    ::after       在元素内部的后面插入内容

CSS3盒子模型

CSS3中可以通过box-size来指定盒模型,有两个值:即可指定为content-box、border-box,这样我们计算盒子大小的方式就发生了改变,
分为两种情况:
    1.box-sizing:content-box 盒子大小为width+padding+border
    2.box-sizing:border-box  盒子大小为width

CSS3滤镜模糊

filter: 函数();  例如:filter:blur(5px); blur模糊处理数值越大越模糊

CSS3其他特性

calc()此CSS函数让你在声明CSS属性值时执行一些计算。
width:calc(100%-80px);

括号里面可以使用+-*/来计算。

CSS3过渡

transition
transition:要过渡的属性  花费时间 运动曲线 何时开始;
1、属性: 想要变化的CSS属性,宽度高度背景颜色内外边距都可以。如果想要所有的属性都变化过渡,写一个ALL就可以。
2、花费时间:单位时秒(必须写单位) 比如0.5s。
3、运动曲线:默认是ease。
4、何时开始:单位是秒可以设置延迟触发时间默认是0s。

2D转换

2D转换之移动效果
盒子x,y移动 transfrom:translate(x,y);
盒子x移动 transfrom:translateX(n);
盒子y移动 transfrom:translateY(n);
不会影响原来的位置。
2D转换之旋转效果
盒子旋转 transfrom:rotate(X);
不会影响其他盒子
2D旋转中心点 transform-origin: x y;
不会影响其他盒子
2D转换之缩放 transform:scale(x,y);
不会影响其他盒子

CSS3三角

原理:旋转+边框+伪类选择器+定位

CSS动画

制作动画:
    1、先定义动画
    @keyframes 动画名称{
        0%{
            //下面加样式
            width: 100px;
        }
        100%{
            //下面加样式
            width: 200px;
        }
    }
    2、再使用(调用)动画
    div{
        width:200px;
        height:200px;
        background-color:aqua;
        margin:100px auto;
        animation-name:动画名称;
        animation-duration:持续时间;
    }
动画常用属性
    animation-name 规定@keyframes动画的名称。
    animation-duration 规定动画完成一个周期所花费的秒或毫秒,默认是0.
    animation-timing-function 规定动画的速度曲线默认是"ease"。
    animation-delay 规定动画何时开始,默认是0。
    animation-iteration-count 规定动画被播放的次数,默认是1,还有infinite。
    animation-direction 规定动画是否在下一个周期逆向播放,默认是"normal"。
    animation-play-state 规定动画是否正在运行或者暂停。
    animation-fill-mode 规定动画结束后状态,保持forwords回到起初backwards
animation-timing-function:
匀速 linear 
加速-减速 ease
低速开始   ease-in
低速结束   ease-out
低速开始结束 ease-in-out
时间函数中的间隔数量(步长) steps

3D转换

近大远小
物体后面遮挡不可见
3D位移 translate3d(x,y,z);
3D旋转 rotate3d(x,y,z);
透视   prespective
3D呈现  transfrom-style

移动web

视口

布局视口 layout viewport
视觉视口 visual viewport
理想视口 ideal viewport

mate视口标签

<meta name="viewport" content="width=device-width, user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0">
width 宽度设置
initial-scale 初始化缩放比,大于0的数字
maximum-scale 最大缩放比,大于0的数字
minimum-scale 最小缩放比,大于0的数字
user-scalable 用户是否可以缩放,yes或no

物理像素&物理像素比

物理像素点指定是屏幕显示的最小颗粒,是物理真实存在的。
我们开发的时候的1px不是等价于一个物理像素的。
pc端的页面,1px等于1个物理像素的,但是移动端就不尽相同。
一个px的能显示的物理像素点的个数,称为物理像素比或屏幕像素比。

二倍图

背景缩放 background-size:图片的宽度|图片的高度
cover 完全覆盖盒子
content 最大适合尺寸

盒子css3

//css3盒子模型
box-size=border-box;
//传统盒子模型
box-size=content-box;

移动端高亮解决

-webkit-tap-highlight-color: transparent;

单独制作移动端

流式布局,就是百分比布局,也称非固定像素布局。

通过盒子的宽度设置成百分比来根据屏幕的宽度来进行伸缩,不受固定像素限制。

flex布局

操作方便,布局极为简单,移动端应用广泛
pc端流浪器支持情况较差
iE 11或低版本,不支持或部分支持
display: flex;
当我们为父盒子设为flex布局后,子元素的float、clear和vertical-align属性将失效。
伸缩布局=弹性布局=伸缩盒子布局=弹性盒布局=flex布局
flex-direction:设置主轴的方向
justify-content:设置主轴上的元素排列方式
flex-wrap:设置子元素是否换行
align-content:设置侧轴上的子元素的排列方式(多行)
align-item:设置侧轴上的子元素的排列方式(单行)
flex-flow:复合属性,相对于同时设置了flex-direction和flex-wrap
flex-direction:  主奏方向
row  从左到右
row-reverser 从右到左
column  从上到下
column-reverser 从下到上
justify-content:
flex-start:默认从左到右
flex-end:从右到左
flex-center:居中对齐
space-around: 平分剩余空间
space-between: 先连边贴边再平分剩余空间
当父盒子为flex盒子:当一排塞不下时且不换行,会缩小子盒子属性,让其塞下,
flex-wrap:子元素是否换行
wrap 换行
align-items:
flex-start:默认从左到右
flex-end:从右到左
center:居中对齐
stretch: 拉伸
align-content:
flex-start:默认从左到右
flex-end:从右到左
flex-center:居中对齐
space-around: 平分剩余空间
space-between: 先连边贴边再平分剩余空间
stretch: 拉伸

flex布局子项常用属性

flex:<number>;  分配剩余空间
align-self: flex-end;
order: -1  默认时0;
background: linear-gradient
background: -webkit-linear-gradient(left,red,blue)
background: -webkit-linear-gradient(left top,red,blue)

rem适配布局

响应式布局

JavaSprite

书写位置:

1、行内式的js
onclick
2、内嵌式的js
<script>
3、外部式的js
<script src="">

注释:

单行注释 //  ctrl+/
多行注释 /* */ ctrl+alt+a

输入输出语句:

window.alter() 弹出警告框。
document.write()方法将内容写到HTML文档中。
innerHTML写入到HTML元素。
console.log()写入到浏览器的控制台。

变量:

什么是变量:
    本质:变量是在程序中在内存中申请的一块用来存放数据的空间。
声明变量:
    var是一个js关键字,用来声明变量。使用该关键字声明变量后,计算机会自动为变量分配内存空间,不需要程序员管。

JS DOM

document:
    getElementById      id
    getElementsByName    name属性
    getElementsByTagNAme   标签
节点指针:
    firstChild 
    lastChild
    childNodes
    previousSibling
    nextSilbing
    parentNode
节点操作:
    createElement  创建元素
    createAttribute  创建属性节点
    createTextNode 创建文本节点
    appendChild  末尾插入节点
    insertBefor  之前插入节点
    replaceChild 将某个子节点替换为另一个
    cloneNode  复制系欸但
    removeChild 删除指定的节点

事件基础

左键点击 onclick
经过  onmouseover
鼠标离开 onmouseout
获得鼠标焦点 onfocus
失去鼠标焦点 onblur
鼠标移动  onmousemoves
鼠标弹起  onmouseup
鼠标按下  onmousedown

修改元素内容

增加文本 innerText
增加HTML innerHTML

修改元素属性

变量.属性

修改表单元素属性

变量.属性

修改元素样式

element.style 行内样式操作
element.className 类名样式操作

自定义属性

H5自定义的属性一般以data开头比如data-index。

获得自定义属性

element.getAttribute('属性')

设置自定义属性值

element.setAttribute("属性","值")

移除属性值

element.removeAttribute("属性")

获得自定义属性集合

element.dataset
element.dataset['index'] 获得指定的自定义属性

注册事件

注册事件有两个方式:传统方式和方法监听注册事件

传统注册事件:
    element.on***=function(){
    
    }
方法监听注册方式:
eventTarget.addEventListener(type,listener[,useCapture)
type:事件类型字符串,比如clicl、mouseover,注意这里不要带on。
listener:事件处理函数,事件发生时,会调用该监听函数。
useCapture:可选参数,一个是布尔值,默认是false。学完DOM事件流后,我们再进一步学习。
ture: 捕获阶段
flase: 冒泡阶段

删除事件

eventTarget.οnclick=null;
eventTarget.removeEventListener(type,listener[,useCapture);

事件流

捕获阶段
当前点击事件阶段
冒泡阶段

事件对象

event 
返回触发事件的对象    e.target
返回触发事件的对象    e.srcElement
返回事件的类型       e.type
该属性阻止冒泡       e.cancelBubble
该属性组织默认事件    e.preventDefault()
阻止冒泡            e.stopPropagation()

事件委托

事件委托的原理:
    不是每一个子节点单独设置事件监听器,而是事件监听器设置再其父节点上,然后利用冒泡原理影响设置每一个子节点。
​

常用的鼠标事件

event对象代表事件的状态,跟事件相关的一系列信息的集合。现阶段我们主要是用鼠标事件对象MovseEvent和键盘事件对象KeyboardEvent。

e.clientX   返回鼠标相对于浏览窗口可视区的X坐标
e.clientY  返回鼠标相对于浏览窗口可视化的Y坐标
e.pageX    返回鼠标相对于文档页面的X坐标
e.pageY    返回鼠标相对于文档页面的Y坐标
e.screenX  返回鼠标相对电脑屏幕的X坐标
e.screenY  返回鼠标相对电脑屏幕的Y坐标

JS BOM

BOM即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是window。

BOM比DOM大

window

window.onload是窗口(页面)加载事件,当文档内容完全加载完成会触发该事件(包括图像、脚本文件、CSS、文件等),就是调用的处理的函数。
window.onresize是调整窗口大小加载事件,当触发时就调用的处理函数。
window.innerwidth

定时器

window.setTimeout(调用的函数,延迟秒数);  调用一次  
window.clearTimeout(定时器名称);  暂停定时器
window.setInterval(调用的函数,延迟秒数); 调用很多次
window.clearInterval(调用定时器名称);  暂停定时器

this指向问题

this指向问题一般指向的是调用它的对象。
1、全局作用域或者普通函数中this指向全局对对象window(注意定时器里面的this也是指向window)
2、方法调用中谁调用this指向谁
3、构造函数中this指向构造函数的实例

js同步和异步

javaScript语言是一个单线程,同一时间只能做一件事。
主线程栈    异步处理器  任务队列   事件循环

js同步

主线程栈

js异步

任务队列

location对象

URL 统一资源定位符,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎样处理它。
组成
protocol://host[:port]/path/[?query]#frament

protocol 通信协议 常用的http、ftp、maito等

host 主机(域名) www.wdaw.com

port 端口号 可选,省略是使用方案的默认端口

path 路径 由零个或者多个'/'符号隔开的字符串,一般用来表示主机上的一个目录或文件地址

query 参数 以键值对的形式,通过&符号分隔开来

fragment 片段 #后面内容 常用链接 描点

location.href       获得或者设置整个URL
location.host       返回主机(域名)
location.port       返回端口号
loaction.pathname   返回路径
loaction.search     返回参数
loaction.hash       返回变短

loction对象方法

location.assign()   跟href一样,可以跳转页面
location.replace()   替换当前页面,因为不记录历史,所以不能后退页面
location.reload()   重新加载页面,相当于刷新按钮或者f5如果参数为true强制刷新ctrl+f5

navigator对象

navigator 对象包含有关浏览器的信息,它有很多属性,我们常用的是userAgent,该属性可以返回由客户机发送服务器的user-agent头部的值。

history对象

window对象给我们提供了一个history对象,与对象浏览器历史记录进行交互。该对象包含用户
window.history.back()   可以后退功能
window.history.forward()    前进功能
window.history.go()   前进后退功能 参数如果是1 前进1个页面 如果是-1 后退1个页面

PC端网页特效

offset系列属性的作用

offset翻译过来就是偏移量,我们使用offset系列相关属性可以动态的得到该元素的位置(偏移)、大小等。
获得元素距离带有定位父元素的位置
获得元素自身的大小(宽度高度)
注意:返回的数值都不带单位
element.offsetParent 返回该元素带有定位的父级元素。
element.offsetTop 返回元素相对带有定位父元素上方的偏移量
element.offsetLeft 返回元素带有定位父元素左边框的偏移量
element.offsetWidth 返回自身包括padding、边框、内容区的宽度 不带数值单位
element.offsetHight 返回自身包括padding、边框、内容区的宽度 不带数值单位

offset 和style的区别

offset可以得到任意样式表中的样式值。
offset系列获得的数值是没有单位的。
offsetWidth包含padding+border+width。
offsetWidth等属性是只读属性,只能获取不能赋值。
所以,我们想要获得元素大小位置,用offset更合适。
​
style只能得到行内样式表中的样式值。
style.width获得的是带有单位的字符串。
style.width获得不包含padding和border的值。
style.width是可读写属性,可以获得也可以赋值。
所以,我们想要给元素更改值,则需要用style改变。

client系列属性的作用

client翻译过来就是客户端,我们使用cilent系列的相关属性来获取元素可视化得到相关信息。
通过clinet系列的相关属性可以动态的得到该元素的边框大小、元素大小
element.clientTop 返回元素上边框的大小。
element.clientLeft 返回元素左边框的大小。
element.clientWidth 返回自身包括padding、内容区的宽度,不包含边框,返回数值不带单位。
element.clientHeight 返回自身包括padding、内容区的宽度,不包含边框,放回数值不带单位。

淘宝flexible.js源码分析

(function flexible(window,document){
    var docEl=document.documentElemt
})
立即执行函数(function(){})()
立即执行函数,不需要调用,立马能够自己执行的函数,第二个函数相当于调用函数
主要作用:创建一个独立的作用域
​

scroll系列属性的作用

scroll翻滚过来就是滚动的,我们使用scroll系列的相关属性可以动态的得到该元素的大小、和滚动距离等。

element.scrollTop 返回被卷上去的上侧距离,返回数值不带单位
element.scrollLeft 返回被卷去的左侧距离,返回数组不带单位
element.scrollWidth 返回自身实际的宽度,不包含边框,返回数值不带单位。
element.scrollHeight 返回自身实际的高度,不含边框,返回数值不带单位。
window.pageYoffset  页面的滚动距离

三大系列总结

element.offsetWidth 返回自身包括padding、边框、内容区的宽度,返回数值不带单位
element.clientWidth 返回自身包括padding、内容区的宽度,不包含边框,返回数值不带单位
element.scrollWidth 返回自身实际的宽度,不含边框,返回数值不带单位。

mouseenter和mouseover的区别

mouseenter鼠标事件
    当鼠标移动到元素上时就会触发mouseenter事件
    类似mouseover,它们两者之间的差别是
    mouseover鼠标经过自身盒子会触发,经过子盒子还会触发。mouseenter只会经过自身盒子触发。

简单动画函数

核心原理:通过定时器setInterval()不断移动盒子位置。
实现步骤:
    1、获得盒子当前位置
    2、让何止在当前位置加上一个移动单位
    3、利用定时器不断重复这个操作
    4、加一个结束定时器的条件
    5、注意此元素需要添加定位,才能使用element.style.left

缓动动画

核心算法:(目标值-现在的位置)/10 作为每次移动的距离步长。

网页轮播图案例

移动端网页布局

JSAPI

String常用函数:

1:indexof()
2:charAt()
3:substring()
4:scilce()
5:split()

indexof()

(method) String.indexOf(searchString: string, position?: number | undefined): number
返回子字符串第一次出现的位置。
​
@param searchString— 要在字符串中搜索的子字符串
​
@param position— 开始搜索字符串对象的索引。如果省略,搜索将从字符串的开头开始。

charAt()

(method) String.charAt(pos: number): string
返回指定索引处的字符。
​
@param pos— 所需字符的从零开始的索引。

substring()

(method) String.substring(start: number, end?: number | undefined): string
返回 String 对象中指定位置的子字符串。
​
@param start— 从零开始的索引号,指示子字符串的开头。
​
@param end 从零开始的索引号,指示子字符串的结尾。子字符串包括字符,但不包括 end 指示的字符。 如果省略 end,则返回从原始字符串的开始到结尾的字符。

scilce()

(method) String.slice(start?: number | undefined, end?: number | undefined): string
返回字符串的一部分。
​
@param start— 指向 stringObj 指定部分开头的索引。
​
@param end 指向 stringObj 的指定部分末尾的索引。子字符串包括字符,但不包括 end 指示的字符。 如果未指定此值,则子字符串将继续到 stringObj 的末尾。

split()

(method) String.split(separator: string | RegExp, limit?: number | undefined): string[] (+1 overload)
使用指定的分隔符将字符串拆分为子字符串,并将它们作为数组返回。
​
@param separator— 标识用于分隔字符串的一个或多个字符的字符串。如果省略,则返回包含整个字符串的单元素数组。
​
@param limit— 用于限制数组中返回的元素数的值。

Ararry常用函数

join()
push()
pop()
find()
forEach()
splice()
sort()
reverse()

join()

(method) Array<string>.join(separator?: string | undefined): string
将数组的所有元素添加到字符串中,由指定的分隔符字符串分隔。
​
@param separator— 用于将数组的一个元素与结果字符串中的下一个元素分开的字符串。如果省略,数组元素用逗号分隔。

push()

(method) Array<string>.push(...items: string[]): number
将新元素追加到数组的末尾,并返回数组的新长度。
​
@param items— 要添加到数组中的新元素。

pop()

(method) Array<string>.pop(): string | undefined
从数组中删除最后一个元素并返回它。 如果数组为空,则返回未定义且不修改数组。

find()

(method) Array<string>.find<string>(predicate: (value: string, index: number, obj: string[]) => value is string, thisArg?: any): string | undefined (+1 overload)
返回数组中谓词为 true 且未定义的第一个元素的值 否则。
​
@param predicate 查找数组中每个元素的谓词一次的调用,升序 顺序,直到找到谓词返回 true 的谓词。如果找到这样的元素,请找到 立即返回该元素值。否则,查找未定义的返回。
​
@param thisArg 如果提供,它将用作每次调用 谓语。如果未提供,则改用未定义。

sort()

(method) Array<string>.sort(compareFn?: ((a: string, b: string) => number) | undefined): string[]
就地对数组进行排序。 此方法改变数组并返回对同一数组的引用。
​
@param compareFn 用于确定元素顺序的函数。预计会回来 如果第一个参数小于第二个参数,则为负值,如果参数相等,则为零,如果参数相等,则为正值 否则值。如果省略,元素将按升序、ASCII 字符顺序排序。
​
[11,2,22,1].sort((a, b) => a - b)

BootStrap

布局容器

1、container 类用于固定宽度并支持响应式布局的容器。
<div class="container">
2、container-fluid 类用于100%宽度,占据全部视口(viewport)的容器。

栅格网格系统

栅格网格系统
        1.列组合
            列总和书不能超过12,大于12,自动换行到下一行
        2.列偏移
            如果我们不希望相邻两个列紧靠在一起,但又不想使用margin或者其他技术手段来。这个时候就可以使用列偏移(offset)功能来实现。使用列偏移也非常简单,只需要在列元素上添加类名"col-md-offset-*"
        3.列排序
            列排序其实就是改变列的方向,就是改变左右浮动,并且设置浮动的距离。
            在Bootstrap框架的网格系统中是通过添加类名 col-md-push-* 和 col-md-pull-*。
        4.列嵌套
            Bootstrap框架的网络系统还支持的嵌套。你可以在一个列中添加一个或者多个行(row)容器,然后在这个行容器中插入列。         

文本

常用样式
         1.标题
             bootstrap对h1到h6的效果进行覆盖
             提供了对用的类名,为非标题元素设置样式 .h1到.h6
                副标题 small标签 或 .small类名 
         2.段落
             通过.lead来突出强调内容(其作用就是增大文本字号,加粗文本,而且对行高和margin也做相应的处理。)
                <small> 小号字
         3.强调
             .text-muted: 提示,使用浅灰色(#999)
             .text-primary:主要,使用蓝色(#428bc)
             .text-success: 成功,使用绿色(#3c763d)
             .text-info: 通知信息,使用浅蓝色(#31708f)
             .text-warning: 警告,使用黄色(#8a6d3b)
             .text-danger: 危险,使用褐色(#a94442)
          4.对齐效果
              .text-left 左对齐
              .text-right 右对齐
              .text-center 居中对齐
              .text-justify  两端对齐      

列表

3.定义列表 
   <dl>
       <dt>HTML</dt>
         <dd>超文本标记语言</dd>
       <dt>css</dt>
         <dd>层叠样式表是一种样式表语言</dd>
   </dl>
   <dl class="dl-horizontal">
       <dt>HTML 超文本标记语言</dt>
          <dd>HTML 称为超文本标记语言,是一种标识性语言</dd>
       <dt>测试标题不能超过160px的宽度,否则2个点</dt>
          dd>我在写一个水平定义列表的效果,我在写一个水平定义列表的效果</dd>
   </dl>

代码

一般在个人博客上使用的较为频率,用于显示代码的风格。在Bootstrap主要提供了三种代码风格:
            (1) 使用<code></code>来显示当行内联代码
            (2) 使用<pre></pre>来显示多行代码代码
                  样式: pre-scrollable(height,max-height高度固定,为340px,超过纯在滚动条)
            (3) 使用<kbd></kbd>来显示用户输入代码,如快捷键

表格

Bootstrap 为了表格提供了1种基础样式和4种附和样式以及1个支持响应式的表格。在使用Bootstrap的表格过程中,只需要添加对用的类名就可以得到不同的表格风格:
    基本样式:
        (1).table:基本表格
    附加表格:
        (1).table-striped: 斑马线表格
        (2).table-bordered: 带边框的表格
        (3).table-hover: 鼠标悬停高亮的表格
        (4).table-condensed: 紧凑型表格,单元格没内距或者内距较其他表格的内距小。
tr、th、td样式:
    .active  将悬停的颜色应用在行或者单元格上
    .success 表示成功的操作
    .info  表示信息变化的操作
    .warning 表示一个警告的操作
    .danger 表示一个危险的操作、

表单

表单主要功能是用来与用户做交流的一个网页控件,良好的表单设计能够让网页与用户更好的沟通。表单中常用的元素主要包括:文本输入框、下拉选择框、单选按钮、复选按钮、文本域和按钮等。
表单控件
    .form-control .input-lg(较大) .input-sm(较小)
输入框text
    .form-control
下拉选择框 select
    多行选择设置: multiple-"multiple"

mysql 进阶

Mysql 性能分析

MySQL 性能分析 变量频率

 show global status like 'com_______'; #变量查询次数
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_binlog    | 0     |
| Com_commit    | 0     |
| Com_delete    | 0     |
| Com_import    | 0     |
| Com_insert    | 0     |
| Com_repair    | 0     |
| Com_revoke    | 0     |
| Com_select    | 3     |
| Com_signal    | 0     |
| Com_update    | 0     |
| Com_xa_end    | 0     |
+---------------+-------+

Mysql 性能分析 慢日志

 show variables like 'slow_query_log'; #慢查询开关
+----------------+-------+
| Variable_name  | Value |
+----------------+-------+
| slow_query_log | OFF   |
+----------------+-------+
# vi /etc/my.cnf  //vi 编辑器去Linux笔记里看
G     //文件末尾
i    //插入
#慢查询日志
slow_query_log=1    // 查询开关
long_query_time=2   // 查询时间超过2s
esc
:wq    

Mysql 性能分析 查找用时

select @@have_profiling;  #Mysql是否支持
+------------------+
| @@have_profiling |
+------------------+
| YES              |
+------------------+
select @@profiling;  #Mysql profiling开关
+-------------+
| @@profiling |
+-------------+
|           0 |
+-------------+
 show profiles;    #查询最近mysql语句用时
+----------+------------+--------------------+
| Query_ID | Duration   | Query              |
+----------+------------+--------------------+
|        1 | 0.00018925 | select @@profiling |
|        2 | 0.00015925 | select * from user |
|        3 | 0.02461950 | show databases     |
|        4 | 0.00009175 | using mysql        |
|        5 | 0.00060650 | SELECT DATABASE()  |
|        6 | 0.00058275 | show databases     |
|        7 | 0.00757575 | show tables        |
|        8 | 0.00006750 | shwo tables        |
|        9 | 0.00769575 | show tables        |
|       10 | 0.00037350 | select * from user |
|       11 | 0.00006375 | show profiling     |
+----------+------------+--------------------+
 show profile for query query_id; #Mysql具体语句的用时
+--------------------------------+----------+
| Status                         | Duration |
+--------------------------------+----------+
| starting                       | 0.000637 |
| Executing hook on transaction  | 0.000017 |
| starting                       | 0.000014 |
| checking permissions           | 0.000018 |
| Opening tables                 | 0.020660 |
| init                           | 0.000015 |
| System lock                    | 0.000010 |
| optimizing                     | 0.000328 |
| statistics                     | 0.000089 |
| preparing                      | 0.000070 |
| Creating tmp table             | 0.000155 |
| executing                      | 0.001520 |
| end                            | 0.000015 |
| query end                      | 0.000005 |
| waiting for handler commit     | 0.000398 |
| closing tables                 | 0.000028 |
| freeing items                  | 0.000039 |
| cleaning up                    | 0.000604 |
+--------------------------------+----------+

Mysql 性能分析 执行计划

explain select 字段列表 from 表名 where 条件; #mysql语句的表的连接和连接顺序。
explain select * from student;
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------+
|  1 | SIMPLE      | student | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    1 |   100.00 | NULL  |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------+
id: select查询的序列号,表示查询中执行select子句或者是操作表的顺序(id相同执行从上到下;id不同,值越大,越先执行)。
select_type
表示SELECT的类型,常见的取值有SIMPLE(简单表,即使用表连接或者子查询)、primary(主查询,即外层的查询)、UNION(UNION中得到第二个或者后面的查询语句)、subquery(select/where之后包含了子查询)等
type
表示连接类型,性能由好到差的连接类型为NULL、system、const、eq_ref、ref、range、index、all。
key
实际使用的索引,如果为NULL,则没有使用索引。
key_len
表示索引中使用的字节数,该值为索引字段最大可能长度,并非实际使用长度,在不损失精确性的前提下,长度越短越好。
rows
Mysql认为必须要执行查询的行数,在innodb引擎的表中,是一个估计值,可能并不是准确的。
filtered
表示返回结果的行数占需读取行数的百分比,filtered的值越大越好。

Mysql 索引

Mysql 索引使用规则

1、最左前缀法则:如果索引了多列(联合索引),要遵守最左前缀法则。最左前缀法则指的是查询从索引的最左列开始,并且不跳过索引中的列。如果跳跃某一列,索引将部分失效(后面的字段索引失效)。
2、范围查询:联合索引中,出现范围查询(>,<),范围查询右侧的列索引失效。

Mysql 索引失效

1、索引列运算:不要在索引列上进行运算操作,索引将失效。聚合函数substring 。
2、字符串不加引号:字符串类型字段使用时,不加引号,索引将失效。
3、模糊查询: 如果仅仅是尾部模糊匹配,索引不会失效,如果是头部模糊匹配,索引失效。
4、用or分割开的条件,如果or前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到。
5、如果Mysql评估使用索引比全表更慢,则不使用索引。

Mysql 前缀索引

create index index_xxxx on table_name(column(n));
可以根据索引的选择性来决定,而选择性是指不重复的索引值(基数)和数据表的记录总数的比值,索引选择性越高则查询效率越高,唯一索引的选择性是1,这是最好的索引选择性,性能也是最好的。
select count(distinct 字段_name)/count(*) from tb_user;

Mysql 单列索引和多列索引

create index index_xxxx on table_name(n) #单列索引
create index index_xxxx on table_name(n,m,k) #多列索引

Mysql 优化

Mysql 插入数据

1、批量插入

insert into tb_name values(n,m,k),(n,m,k);

2、手动提交事务

start transaction;
insert into tb_name values(n,m,k);
insert into tb_name values(n,m,k);
commit;

3、主键顺序插入

4、大批量插入数据

如果一次性需要插入大批量数据,使用insert语句插入性能较低,此时可以使用MYSQL数据提供的load指令插入。操作如下:
mysql --local-infile -u root -p
#客服端连接服务器时,加上参数 --local-infile
set global local_infile=1;
#设置全局参数local_infile为1,开启从本地加载文件导入数据的开关
load data local infile '/root/sql.log' into table 'to_user' fields terminated by ',' lines terminated by'\n';

Mysql 主键索引

1、数据组织方式

在innodb储存引擎中,表结构都是根据主键顺序组织储存的,这种储存方式的表称为索引组织表(index organized table IOT)。
Tablespace:表空间
	Segment
	Segment
Segment:段
	Extent
	Extent
Extent:区(1M)
	page*64
Page:页 16k
	Row
Row: 行

2、页分裂

页可以为空,也可以填充一半,页可以填充100%,每个页包含了2-N行数据(如果一行数据多大,会行溢出),根据主键排列。
主键顺序插入
主键乱序插入

3、页合平

当删除一行记录时,实际上记录并没有被物理删除,只是记录被标记(flaged)为删除并且它的空间变得允许被其他记录声明使用。当页中删除的记录达到MERGE_THRESHOLD(默认为页的50%),innodb会开始寻找最靠近的页(前或后)看看是否可以将两个页合拼以优化空间使用。

Mysql order by优化

最左前缀法则
Using filesort:通过表的索引或全表扫描,读取满足条件的数据行,然后在排序缓存区sort buffer中完成排序操作,所有不是通过索引直接返回排序结果的排序都叫FileSort排序。
Using index:通过有序索引顺序扫描直接返回有序数据,这种情况即为using index,不需要额外排序,操作效率高。

Mysql group by优化

using temporary:用到临时表,性能不高。
最左前缀法则

Mysql limit 优化

select * from table_name limit 100000,10;#常规
一般分页查询时,通过创建 覆盖索引 能够比较好地提高性能,可以通过覆盖索引加子查询形式进行优化。
select s1.*  from table_name s1,(select name from table_name order  by id limit 20000,10) s2 where s1.name=s2.name;

Mysql count 优化

select count(*) from table_name #常规
MyISAM 引擎把一个表的总行数存在了磁盘上,因此执行了count(*)的时候直接返回这个数,效率很高;
InnoDB 引擎就麻烦了,它执行count(*)的时候,需要数据一行一行地从引擎里面读出来,然后累计计数。
优化思路:(自己计数)

Mysql update 优化

innodb 是行锁
当update没有根据索引查找时,用的是表锁。
当update根据索引查找时,用的是行锁。

Msyql 视图

视图也叫虚拟表不存放数据,存放表结构。数据来源于基表

视图的创建:

create view view_name as select查询语句;

视图的修改:

alter view view_name as select查询语句;

视图的删除:

drop view view_name;

视图的检查选项

当使用with check option 子句创建视图时,Msyql会通过视图检查正在更改的每一个行,例如插入,更新,删除,以使其符合视图的定义。mysql允许基于另一个视图的创建视图,它还会检查依赖视图中的规则以保持一致性,为了确定检查的范围,mysql提供了两个选项cascade和loacal,默认值为cascaded。

create or replace view view_name where语句 with 视图检查选项 option。

cascaded:

依赖的视图都加上检查

local:

当地的视图加上检查

在进行视图数据操作时,如果遇到如下情况,操作可能会失败。

1、视图定义在多个表上。
2、没有满足视图的基本表对字段的约束条件。
3、在定义视图的select语句后的字段列表中使用了数学表达式或聚合函数。
4、在定义视图的select语句中使用了distinct、union、top、group by或having子句。

Mysql 储存过程

Mysql 存储过程的介绍

存储过程时事先经过编译并储存在数据库中的一段sql语句的集合,带调用存储过程可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,对于提高数据处理的效率时有好处的。

Msyql 存储过程的创建:

create procedure 储存过程名称([参数列表])
begin
	--sql语句
end;

Mysql存储过程的调用:

call 名称([参数]);

Mysql储存过程查看:

select * from information_schema.routines where routnes_schema='xxx';-- 查找指定数据库的存储过程及状态信息
show create procedure 存储过程名称;

Mysql删除过程:

drop procedure 储存过程名称;

Mysql 存储过程的参数

in : 输入参数
out: 输出参数
inout: 输入输出参数

Mysql变量

Mysql 系统变量

系统变量是MYSQL服务器提供,不是用户定义的,属于服务器层面。分为全局变量(Global)、会话变量(SESSION)。

查看系统变量:

show [session|global] variables;
show [session|global] variables like'___';
select @@[session|global] 系统变量名;

设置系统变量

set [session|global] 系统变量名=值;
set @@[session|global] 系统变量名=值;

Mysql 用户定义的变量

用户定于变量是用户根据需要自己定义的变量,用户变量不用提前声明,在用的时候直接用"@变量名"使用就可以。其作用域为当前连接。

赋值:

set @var_name =expr[,@var_name=expr]……;
set @var_name :=expr[,@var_name:=expr]……;
select 字段名 into @var_name from 表名;

使用:

select @var_name;

Mysql 局部变量

定义:

declare 变量名 变量类型 [default ……];

Mysql 跳转语句

Mysql 跳转语句if

if 条件1 then
	……
else 条件2 then   -- 可选
    ……
else             -- 可选
	……
end if;

Mysql 跳转语句case

case case_value
	when when_value1 then statement_list1
	[when when_value2 then statement_list2]……
	[ElSE statement_list]
end case;
case
	when search_condition then statement_list1
	[when search_cindition then statement_list2]……
	[ELSE statement_lsit]
end case;

Mysql 循环语句

Mysql 循环语句while

while 条件 Do
	sql逻辑……
end while;

Mysql 循环语句repeat

repeat
    sql 逻辑……
    until 条件
end repeat;

Mysq循环语句loop

sign: loop
    sql逻辑……
end loop [sign];
leave sign; --退出指定标记的循环体
iterate sign; --直接进入下一个循环

Mysql游标cursor

声明游标

declare 游标名称 cursor for 查询语句;

打开游标:

open 游标名称;

获得游标记录:

fetch 游标名称 into 变量[,变量]

关闭游标:

close 游标名称;

Mysql 条件处理程序

declare handler_action handler for condition_value[,condition_value]……
handler_action
	continue:继续执行当前程序。
	exit:终止执行当前程序。
condition_value
	SQLSTATE sqlstate_value:状态码,如02000。
	SQLWARNING:所有以01开头的SQLSTATE代码的简写。
	NOT FOUND:所有以02开头的SQLSTATE代码的简写。
	SQLEXCEPTION:所有没有被SQLWARNING或NOT FOUND捕获的SQLSTATE代码的简写。

Mysql 触发器

触发器的创建:

create trigger trigger_name after|begin insert|update|delete 
on table_name for each row
begin
	trigger_语句;
end;

触发器的参数:

begin 在之前
after 在之后
insert 插入   new
updata 修改   new|old
delete 删除   old

Mysql 锁

Mysql全局锁

备份数据,解决备份不一致问题

设置全局锁

flush tables with read lock;

备份

mysqldump -u root -p 密码 数据库 > 地址

取消全局锁

unlock tables;

简化

mysqldummp --single-transaction -u root-p 密码  数据库> 地址

Mysql表级锁

表锁:

表共享读锁(read lock):多客户端的情况下,都可以使用DQL。不能DML;
表独占写锁(write lock):在多客户端的情况下,其他客户端都不可以使用DML和DQL。但是当前客户端可以使用DML和DQL;
lock tables 表名…… read/write.
unlock tables /客户端断开连接

元数据锁(meta data lock,MDL):

事务执行,解决DDL和DML冲突,自动添加锁:
	DDL: alter  exclusive
	DML: insert…… shared_write
	DQL: select …… shared_read
	表锁: lock tables xxx read/write shared_read_only/shared_No_read_write
select * from performance_schema.metadata_locks;

DML和DQL于DDL互斥:

当当前客户端有执行DDL语句时,其他客户端都不可以执行DML和DQL
直到事务提交,但当前客户端能执行DQL和DML。
当当前客户端已经执行表共享读锁,有执行DDL语句时,其他客户端都不可以执行DML和DQL,没有执行的DDL语句时,因为DML和DQL兼容又因为有表共享读锁只能执行DQL.
同理……
直到事务提交。

意向锁:

为了避免DML在执行时,加的行锁和表锁冲突,在innodb引入了意向锁,在加表锁的时候会检查。所以我们引入意向锁可以解决检查锁冲突的时间问题。和锁是否冲突(有锁等待问题)做出判断。
意向共享锁(is):由语句select……lock in share mode添加。
意向排他锁(ix):有insert、update、delete、select……for update 添加。 
意向共享锁(is):如果加的表锁为表共享读锁(read lock),可以直接加上。
意向排他锁(ix):表锁都不行,但是意向锁兼容。
select * from performance_schema.data_locks;

行级锁

特点:锁定粒度最小,发生锁冲突的概率最低,并发度最高。应用在innodb储存引擎中。
innodbd的索引是基于索引组织的,行锁是通过对索引上的索引项加锁实现的,而不是记录加的锁。对于行级锁,主要分为以下三类:
行锁查看:show statue like 'innodb_row_lock%';

行锁:

共享锁:允许一个事务去读一行,阻止其他事务获得相同数据集的排它锁。
排他锁:允许获得排他锁的事务更新数据,阻止其他事务获得相同数据集的共享锁和排他锁。

间隙锁和临建锁:

为了防止出现幻读的现象。innodb使用next-key锁进行搜索和扫描。
临建锁是由记录锁和间隙锁构成。
1、索引上的等值查询(唯一索引),不纯在的记录加锁时,优化为间隙锁,存在的时候为记录锁。
2、索引的等值查找(普通索引),向右遍历时最后一个值不满足查询需求时,next-key退化为间隙锁。
3、索引上的范围查找(唯一索引)--会访问到不满足条件的第一个值为止。
唯一索引等值查询
当我们用唯一索引进行等值查询的时候,查询的记录不存在,加锁的规则也会不同:
	当查询的记录是存在的,在使用[唯一索引进行等值查询]时,next-key lock 会退化成[记录锁]。
	当查询的记录是不存在的,在用[唯一索引进行等值查询]时,next-key lock 会退化成[间隙锁]。

唯一索引范围查询
范围查询和等值查询的加锁规则是不同的。
例如
	select * from t_test where id>=8 and id<9 for update;
	select * from t_test where id=8 for update;
先对范围内有记录的加上记录锁,然后加上间隙锁。

非唯一索引等值查询
当我们用非唯一索引进行等值查询的时候,查询的记录存不存在,加锁的规则页会不同:
当查询的记录存在时,除了会加next-key lock外,还额外加间隙锁,也就是会加两把锁。
当查询的记录不存在时,指挥加next-key lock,然后会退化为间隙锁,也就是只会加一把锁。
非唯一索引范围查询
非唯一索引和主键索引的范围查询的加锁也有所不同,不同之处在于普通索引范围查找,next-key lock 不会退化为间隙锁和记录锁。
总结
唯一索引等值查询:
	当查询的记录是存在的,next-key lock会退化成[记录锁]
	当查询的记录不存在时,只会加next-key lock,然后会退化为间隙锁,也就是只会加一把锁。
	
非唯一索引等值查询:
	当查询的记录存在时,除了会加记录锁还会加上两个间隙锁,也就时加两把锁。
	当查询的记录不存在时,只会加next-key,然后退化成一把间隙锁。
	
唯一索引范围查询:
	为查询存在的记录加上记录锁,记录之间加上间隙锁。
	当查询不存在的记录时加上间隙锁。
非唯一索引范围查询:
	为查询的记录加上next-key lock,不会退化成间隙锁和记录锁。

死锁问题

客户端1:

set global transaction isolation level repeatable read ;
begin;
    select * from student where student_id=1213902017 for update ;-- 序号1
    select * from student where student_id=1213902018 for update ;-- 序号2
commit

客户端2:

set global transaction isolation level repeatable read ;
begin;
    select * from student where student_id=1213902018 for update ;-- 序号2
    select * from student where student_id=1213902017 for update ;-- 序号1
commit

当客户端1事务执行序号1对序号1加锁(在这里加的是行锁,因为储存引擎为innodb,select用到了索引)以后,客户端2事务执行了序号2(同理),客户端1事务要执行序号2因为加了行锁,而客户端2事务要执行序号1因为加了行锁,都在等待解除行锁,就造成了死锁。

Mysql Innodb引擎

逻辑储存结构

表空间(idb文件),一个mysql实例可以对应多个表空间,用于储存记录、索引等数据。
段:分为数据段、索引段、回滚段,innodeb是索引组织表,数据段就是b+树的叶子节点,索引段即为b+树的非叶子节点。段用来管理多个Extent(区)。
区:表空间的单元结构,每个区的大小为1M。默认情况下,innodb储存引擎页大小为16k,即一个区一共64个连续的页。
页:Innodb储存引擎磁盘管理的最小单元,每一个页的大小默认为16kb。为了保证页的连续性,innodb储存引擎每次从磁盘申请4-5个区。
行:innodb储存引擎数据是按行进行存放的。

架构

内存架构

buffer pool,change buffer ,adaptive hash index,log buffer。

buffer pool
BUffer Pool:缓冲池是主内存中的一个区域,里面可以缓存磁盘上经常操作的真实数据,在执行增删改查操作时,先操作缓冲池中的数据(若缓冲池没有数据,则从磁盘加载并缓存),然后以一定频率刷新到磁盘,从而减少磁盘io,加快处理速度。
缓存池以page页为单位,底层采用链表数据结构管理page。根据状况,将page分为三种类型:
	free page:空闲page,数据没有使用。
	clean page:被使用的page,数据没有被修改过。
	dirty page:脏页,被使用page,数据被修改过,数据于磁盘中的数据产生不一致。
buffer pool涉及链表:
	free链表。
	flush链表。
	LRU链表。
buffer pool涉及算法或问题:
	Buffer Pool污染问题。
	mysql LRU优化算法。

buffer pool缓存:

	innodb会把储存的数据划分为若干个[页],以页作为磁盘和内存交互的基本单位,一个页的默认大小为16kB,因此,buffer pool同样需要按照[页]来划分。
	在mysql启动的时候,innodb会为Buffer Pool申请一片连续的内存空间,然后按照默认的16kb的大小划分出一个一个的页就叫做缓存页。此时这些页都是空闲的,之后随着程序的运行,才会有磁盘上的页被缓存到buffer pool中。
buffer pool页管理:
	为了更好的管理这些在Buffer Pool中的缓存页,innodb为每一个缓存页都创建一个控制块,控制块信息包括[缓存页的表空间、页号、缓存页地址、链表节点等等]。
	控制块也是要占用空间的,它放在Buffer Pool的最前面,接着才是缓存页,如下图:

buffer Pool链表:

	free链表:把空闲页的控制块取控制块的首地址构成free链表,当需要磁盘中的页刷新到buffer Pool中的空页时,直接访问free链表,找到你一个节点,用指针节点找到对应的控制块,然后进行操作刷新,如果修改数据,在flush链表中链尾增加一个此操作的节点,然后free链表删除第一个节点。(快速找到空白页)
	flush链表:把脏页的控制块取控制块的首地址构成free链表,当需要buffer Pool中的脏页刷新到磁盘中的页时,直接访问free链表,找到你一个节点,用指针节点找到对应的控制块,然后进行操作刷新,然后在free链表中链尾增加一个此操作的节点,然后flush链表删除第一个节点。
	LRU链表:old区域和young区域。

简单的LRU算法:

--当访问的页在Buffer Pool里,就直接把该页对应的LRU链表节点移动到链表的头部。
--当访问的页不在Buffer Pool里,除了要把页放入到LRU链表的头部,还要淘汰LRU链表末尾的节点。

预读失效问题:

mysql的预读机制。程序是有空间局部性的,靠近当前被访问数据的数据,在未来很大概率会被访问到。所以,mysql在提前加载这些数据页时,但是这些数据页并没有被访问,相当于这个预读是白做了,这个就是预读失效。
		如果使用简单的预读页放到LRU链表头部,而当Buffer Pool空间不够的时候,还需要把末尾的页淘汰掉。
		如果这些预读页如果一直不会被访问到,就会出现一个问题,不会被访问的预读页占用了LRU链表的前排的位置,而末尾淘汰的页,可能是频繁范文的页,这样就大大降低了缓存命中率。

mysql LRU优化算法:

要避免预读失效带来影响,最好就是让预读的页停留在Buffer Pool里的时间要尽可能的短,让真正被访问的页才移动到LRU链表的头部,从而保证真正被读取的热数据留在Buffer Pool里的时间尽可能长。
		将LRU分为两个区域:old区域和young区域。
			old区域占整个LRU链表长度的比例可以通过innodb_old_blocks_pc参数来设置,默认值是37,代表整个LRU链表中young区域与old区域比例是63:37。
		划分这两个区域后,预读的页只需要加入到old区域的头部,当真正访问的时候,才将页插入young区域的头部。如果预读的页一直没有被访问,就会从old区域移除,这样就不会影响young区域中的热点数据。
	
解决预读问题。
在进入mysql数据库的yong区域增加一个条件:停留子old区域的时间判断。
具体是这样做的,在对某个处在old区域的缓存页进行第一次访问,就在它对应的控制块中记录下来这个访问时间:
		如果后续的访问时间与第一次访问的时间在某一个时间间隔内,那么该缓存页就不会被从old区域移动到young区域的头部;
		如果后续的访问时间与第一次访问的时间不在某个时间间隔内,那么该缓存页就会被从old区域移动到young区域的头部。
解决Buffer Pool问题。	

Buffer Pool污染问题:

当某一个SQL语句扫描了大量的数据时,在Buffer Pool空间空间有限的情况下,可能会将Buffer Pool里的所有页都替换出去,导致热数据被淘汰了,等这些热数据又被再次访问的时候,由于缓存未命中,就会产生大量的磁盘IO,MySQL性能就会急剧下降,这个过程被称为Buffer Pool污染。

change buffer: 更改缓存区(针对于非唯一二级索引页),在执行DML语句时,如果这些数据Page没有在BUffer Pool中,不会直接操作磁盘,而将数据变更存在更改缓存区 Change Buffer中,在未来数据被读取时,再将数据合并到buffer pool中,再将合并后的数据刷新到磁盘中。
change Buffer的意义是什么?
	与聚集索引不同,二级索引通常是非唯一的,并且以相对随机的顺序插入二级索引。同样,删除和更改可能会刷新可能会影响索引树中不相邻的二级索引页,如果每一次都操作磁盘,会造成大量的磁盘IO。有了ChangeBuffer之后,我们可以在缓存池中进行合并处理,减少磁盘IO。
Adaptive Hash index:自适应hash索引,用于优化对buufer pool数据的查询。innodb储存引擎会监控对表上各个索引页可以提高速度,则建立hash索引,称之为自适应hash索引。
自适应哈希索引,无需人工干预,是系统根据情况自动完成。
参数: adaptive_hash_index
Log Buffer: 日志缓存区,用来保存要写入到磁盘中的日志数据(redo log、undo log),默认大为16MB,日志缓存区的日志会定期刷新到磁盘中。如果需要更新、插入或删除许多行的事务,增加日志缓冲区的大小可以节省磁盘I/O。
参数:
innodb_log_buffer_size:缓冲区大小。
innodb_flush_log_at_trx_commit:日志刷新到磁盘时机。
  1:日志在每次事务提交写入并刷新到磁盘。
  0:每秒将日志写入并刷新磁盘一次。
  2:日志在每次事务提交后写入,并每秒刷新到磁盘一次。 
磁盘架构
System Tablespace:系统表空间是更改缓冲区的储存区域。如果表是在系统表空间而不是每个表文件或通用表空间中创建的,它也可能包含表和索引数据。(在Mysql5.x版本中还包含innodb数据字典、undolog等)
参数:innodb_data_file_path
File-Table Tablespaces:每个表空间包含单个Innodb表的数据和索引,并储存在文件系统上的单个数据文件中。
参数:innodb_file_per_table
General Tablespace: 通用表空间,需要通过create tablespace 语法创建通用表空间,在创建表时,可以指定该表空间。
-- 创建表空间
create tablespace xxx add datafile 'file_name' engine=engin_name;
-- 把表存放在表空间
create table xxx tablespace ts_name;
Undo tablespaces: 撤销表空间,mysql实例在初始化时会自动创建两个默认的Undo表空间(初始大小16M),用于储存undo log日志。
Temporary Tablespaces:innodb使用会话临时表空间和全局临时表空间。储存用户创建的临时表等数据。
Doublewrite Buffer Files:双写缓冲区,innodb引擎将数据页从Buffer Pool刷新到磁盘前,先将数据页写入双写缓冲区文件中,便于系统异常时恢复数据。
#ib_16384_0.dblwr
#ib_16384_1.dblwr
Redo Log:重做日志。是用来实现事务的持久性。该日志文件由两部分组成;重做日志缓冲区(redo log buufer)以及重做日志文件(redo log),前者是在内存中,后者在磁盘中。当事务提交之后会把所有修改信息都会存在该日志中,用于在刷新脏页到磁盘时,发生错误时,进行数据恢复使用。
#ib_logfile0
#ib_logfile1
后台架构
1.Master Thread
核心后台线程,负责调度其他线程,还负责将缓冲池中的数据异步刷新到磁盘中,保持数据的一致性,还包括脏页的刷新、合并插入缓存、undo页的回收。
2.IO Thread
在innodb储存引擎中大量使用了AIO来处理IO请求,这样可以极大提高数据库的性能,而IO Thread主要负责这些IO请求的回调

线程安全默认个数职责
Read thread4负责读操作
Write thread4负责写操作
log thread1负责将日志缓冲区刷新到磁盘
insert buffer thread1负责将写缓存区内容刷新到磁盘

show engine innodb status;
3.Purge Thread
主要用于回收事务已经提交了的undo log,在事务提交之后,undo log可能不用了,就用它来回收。
4.Page Cleaner Thread
协助Master Thread 刷新脏页到磁盘的线程,它可以减轻Master Thread的工作压力,减少阻塞。

事务原理

事务的概念:
事务的四大特性(ACID):
	A.原子性
	C.一致性
	I.隔离性
	D.持久性
redo log 和undo log 为事务一致性,原子性,持久性提供保障
锁和MVCC来实行隔离性
mysql InnoDB引擎默认的修改数据语句:
		update,delete,insert都会自动给涉及到的数据加上排他锁,
		select语句默认不会加任何锁类型。
redo log: 持久性
重写日志,记录的是事务提交时数据页得到物理修改,是用来实现事务的持久性。
用于处理事务提交后,内存刷新到磁盘中时,发生错误时,进行数据恢复。
该日志文件有两部分组成:redo log buffer 在内存中是顺序磁盘io,是直接刷新到磁盘中的。redo log file 在磁盘中是顺序磁盘io。
undo log: 原子性
回滚日志,用于记录数据被修改前的信息,作用包含两个:提供回滚和MVCC(多版本并发控制)。
undo log和redo log记录物理日志不一样,他是逻辑日志。可以认为当delete一条记录时,undo log会记录一条对应的insert记录,反之亦然,当update一条记录时,它会记录一条对应相反的update记录。当执行rollback时,就可以从undo log中的逻辑记录读到相应的内容并进行回滚。
undo log 销毁:undo log在事务执行时产生,事务提交时,并不会立即删除undo log,因为这些日志可能还用于MVCC。
undo log 储存:undo log采用段的方式进行管理和记录,存放在前面介绍的roolback segment 回滚段中,内部包含1024个undo log segment。

MVCC

当前读:
	读取的是当前记录的最新版本,读取时还要保证其他事务不能修改当前记录,会对读取的记录进行加锁。select …… lock in share mode(共享锁),select …… for update、update、insert、delete(排他锁)都是一种当前读。
快照读:
	简单的select(不加锁)就是快照读,快照读,读取的时记录的是记录数据的可见版本,有可能是历史记录,不加锁,是非阻塞读。
	read committed:每次select,都生成一个快照读。
	repeatable read:开启事务后第一个select语句才是快照读的地方。
	serializable:快照读会退化为当前读。
Mvcc:
	多版本并发控制。指维护一个数据的多个版本,使得读写操作没有冲突,快照读为Mysql实现MVCC提供一个非堵塞读功能。Mvcc的具体实现,还需要依赖数据库记录的三个隐式字段、unlog log日志、readView。
三个隐式字段:
DB_TRX_ID:最近修改事务ID,记录插入这条记录或最后一条修改记录的事务ID。
DB_ROLL_PTR: 回滚指针,指向这条记录的上一个版本,用于配合undo log,指向上一个版本。
DB_ROW_ID:隐藏表结构没有指定主键,将会生产该隐藏字段。
undo log:
回滚事务,在insert、updata、delete的时候产生的便于数据回滚的日志。
当insert的时候,产生的undo log日志不仅在回滚时需要,在快照时页需要,不会立即被删除。
生成一个版本链:
	如果有两个事务,事务2和事务3会遵循锁机制。
	例如
 时间	  事务2          事务3
  1     begin	       begin
  2     up              up
  3     commit          |
  4				        up
这样会因为锁机制 事务3时间为2的up会向后推辞到时间为4的up。(锁的排它锁原理)
注意这里我写的锁没有利用索引而产生表锁所以会出现锁的阻塞。


如果在innodb中产生了利用了索引产生的是行锁。
	例如
 时间	  事务2          事务3
  1     begin	       begin
  2     up              up
  3                    commit 
  4     commit    
 就可以出现这样的情况了。
readview
	readview(读视图)是快照读SQL执行时MVCC提取数据的依据,记录并维护系统当前活跃的事务(未提交的)id
	readview包含了四个核心字段:
	m_ids 当前活跃的事务id集合
	min_ids 最小活跃事务id
	max_trx_id 预分配事务id,当前最大事务id+1(因为事务id是自增的)
	creator_trx_id readview创建者的事务id
版本链数据访问规则:
	1、trx_id==creator_trx_id?  回溯到本事务此查询语句的上一个update语句。
	2、trx_id<min_trx_id?	回溯大概到本事务上一个事务结束的时候。
	3、trx_id>max_trx_id? 	回溯大概到本事务的结束的地方和不访问在表中事务不是本事务的版本节点。
	4、min_trx_id<=trx_id<=max_trx_id? 如果trx_id不在m_ids是可以访问该版本的。 回溯到最近事务提交的地方。
注意:回溯不仅有一次。最后找到满足1、2、4的地方。
在RR中:redview在快照读的时候会复制本事务中上一个快照读的地方。
在Rc中:redview在快照读的是该时刻的快照读。

自己的猜想(待验证):

这里undo版本链和readview是分开运行的,有利于提高效率,因为undo不会随readview的快照读而停止加链。
这里我说明一下我猜想为什么会有快照读为事务2,而开始事务已经到了事务3。
因为readview在快照读的时候后才向buffer pool缓存池存储命令,而log buffer已经储存并刷新了,undo版本链先加载了事务3的update加了链。然后在查询的时候就从事务3的开始。(简而言之就是Buffer Pool和Log Buffer刷新的时间不同)
这样可以防止计算机没有按照时间顺序引起的错乱,又提高了效率。

如果开始的时候是事务3,而快照读的是事务2。

关于MVCC是否解决了幻读问题
    MVCC部分解决掉了幻读问题:
    	原因:
    	
    	当使用的是MVCC快照读的时候:
    		insert 不会给版本链添加节点。
    		select 会根据版本链来搜索。
    		所以不会搜到insert插入的。
    	幻读解决。
    	
    	但是当是快照读的时候:
    		insert 不会给版本链添加链。
    		update 对insert的数据进行修改的时候就会给版本链增加节点。
    		select 会根据版本链来搜索到这个节点。
    	幻读没有解决。
    	简而言之,就是看版本链增加了update修改insert的数据项有没有。有,幻读没有解决,没有,幻读有解决。
解决幻读

innodb引擎默认加入间隙锁。

在mvcc和部分锁解决RR的基础上增加next-key lock解决很大程度(注意这个很大程度,在RR情况下是可以小部分解决)幻读问题。
1、第一种方法:通过对update(undo log版本链)的控制
	insert 默认加上意向锁的排他锁和和元数据的写锁。
	在select * from …… where …… for update; 加上的是意向锁的排它锁和元数据锁的写锁和行锁next-key lock。
	如果update 就会出现排他锁互斥。
2、第二种方法:通过对insert的控制
	select * from ……for update;加上的是意向锁的排它锁和元数据锁的写锁和行锁next-key lock。
	insert 就会阻塞。
这样就可以很大程度上解决幻读问题。

数据库常用小工具

系统数据库

Mysql数据库安装完成后,自带一下是个数据库,具体作用如下:

mysql
	储存mysql服务器正常运行所需要的各种信息(时区、主从、用户、权限等)
information_schema
	提供了访问数据库元数据的各种表和视图,包含数据库、表、字段类型及访问权限等。
performance_schema
	为MySQL服务器运行时状态提供了一个底层监控功能,主要用于收集数据库服务器性能参数
sys
	包含了一系列方便DBA和开发人员利用performance_schema性能数据库进行性能调优和诊断的视图

常用工具:

该mysql不是指mysql服务,而是指mysql的客服端工具。

语法:
	mysql [options][database]
选项:
	-u --user=name   #指定用户
	-p --password[=name]   #指定密码
	-h --host=name  #指定服务器ip或域名
	-p --port=port  #指定连接端口
	-e --execute    #执行SQL语句并退出
mysqladmin
	Mysql管理工具
	mysqladmin --help
msyqlbinlog
	二进制日志查看工具
	mysqlbinlog --help
mysqlshow
	查看数据库、表、字段的统计信息
	mysqlshow --help
mysqldump
	数据备份工具
	mysqldump --help
mysql
	mysql客户端工具,-e执行SQL并退出
	mysql --help
mysqlimport/source
	数据导入工具
	mysqlimport/source --help

Ajax入门

JQuery的Ajax

jQuery中发起Ajax请求最常用的三个方法如下:

$.get() 获得数据
    jQuery中$.get()函数的功能单一,专门用来发起get请求,从而将服务器上的资源请求到客户端来进行使用。
    $.get(url,[data],[callback])
        url String 是 要请求的资源地址
        data object 否 请求资源期间要携带的参数
        callback 否 请求成功时的回调函数
        
        
$.post() 提交数据
    jQuery中$.post()函数的功能单一,专门用来发起post请求,从而向服务器提交数据。
    $.post(url,[data],[callback])
        url String 是 要请求的资源地址
        data object 否 请求资源期间要提交的参数
        callback 否 请求成功时的回调函数
    
    
$.ajax()
    相比于$.get和$.post()函数,jQuery中提交的$.ajax()函数,是一个功能比较综合的函数,它允许我们对Ajax请求进行更加详细的配置。
    $.ajax()函数的基本语法如下:
    $.ajax({
        type: '',//请求的方式,例如GET或POST
        url:'',//请求的url地址
        data:{ },//这次请求要携带的数据
        success: function(res){}  // 请求成功时的回调函数
    })

接口的概念

使用Ajax请求数据时,被请求的URL地址,就叫做数据接口(简称接口),同时,每个接口必须有请求方式。

接口测试工具Postman

案例

form表单的基本使用

表单在网页中主要负责数据采集功能。HTML中的<form>标签,就是用于采集用户输入的信息,并通过<from>标签的提交操作把采集到的信息提交到服务器端进行处理。

action属性

action属性用来规定当提交表单时,向何处发送表单数据。
action属性的值应该是后端提供的一个URL地址,这个URL地址专门负责接受表单提交过来的数据。
当<form>表单在未指定action属性值的情况下,action的默认值当前页面的URL地址。
注意:当提交表单后,页面会立即跳转到action属性指定的URL地址

target属性

_blank
_self
_parent
_top
framename

method属性

method属性用来规定以何种方式把表单数据提交到action URL。
它的可选值有两个,分别是get和post。
默认情况下,method的值为get,表示通过URL地址的形式,把表单数据提交到action URL。
注意:
    get方式适合用来提交少量的、简单的数据。
    post方式适合提交大量的、复杂的、或包含文件上传的数据。

enctype属性

enctype属性用来规定在发送表单数据之间如何对数据进行编码。
它的可选值有三个,默认情况下,enctype的值为application/x-www-form-urlencoded,表示在发送前编码所有的字符。
什么是表单的同步提交
    <form> 表单同步提交后,整个页面会发生跳转,跳转到action URL所指向的地址,用户体验很差。
    <form>表单同步提交后,页面之前的状况和数据会丢失。
解决方式: 表单只负责从采集数据,Ajax负责将数据提交到服务器。
​

通过Ajax提交表单数据

serialize()
    为了简化表单中数据的获取操作,jQuery提供了serialize()函数,其结构如下:
    $(selector).serialize()
    好处:
        可以一次性获得列表单中的所有数据。
示例:
    $(".form1").serialize()
    //调用的结果:
    //username=用户名的值&password=密码的值
    注意:在使用serialize()数据快速获得表单数据时,必须为每个表单元素添加name属性!。

案例

模板引擎的基本概念

var rows[]
$.each(res.data,function(i,item){
    rows.push(……)
})
$("#cmt-list").emty().append(row.join('')) //渲染列表的UI结构.

上述代码通过字符串拼接的形式,来渲染UI结构的。

如果UI结构比较复杂,则拼接字符串的时候需要格外注意引号之前的嵌套。且一旦需求发生变化,修改起来也非常麻烦。

什么是模板引擎
    模板引擎,顾名思义,它可以根据程序员指定的模板结构和数据,自动生成一个完整的HTML页面。
    数据+数据结构->模板引擎->HTML页面
模板引擎的好处:
    1、减少了字符串的拼接操作
    2、使代码结构更清晰
    3、使代码更易于阅读与维护

art-templete模板引擎(初学者友好型)

art-template简介
art-template是一个简约、超快的模板引擎。中文官网首页为http://aui.github.io/art-template/zh-cn/index.html
文档查看 http://aui.github.io/art-template/zh-cn/docs/
导入 art-template
在window全局,多一个函数,叫做template('模板的id',需要渲染的数据对象)
在定义需要渲染的对象
<script type="text/html" id="template1" >
        <h1>{{name}}</h1>
    </script>
    <script>
        var data={name: "李四"};
        var HtmlStr=template("template1",data);
        console.log(HtmlStr);
    </script>
art-template提供了{{}}这种语法格式,在{{}}内可以进行变量输出,或循环数组等操作,这种{{}}语法在art-template中被称为标准语法。

原文输出

{{@value}}
如果要输出的value值中,包含了HTML标签结构,则需要使用原文输出语法,才能保证HTML标签被正常渲染。

条件输出

{{if value}} 按需输出的内容 {{/if}}
{{if vl}}按需输出的内容{{else if v2}} 按需输出的内容{{/if}}
如果要实现条件输出,则可以在{{}}中使用if……else if……/if的方式,进行按需输出。

循环输出

{{each arr}}
    {{$index}} {{$value}}
{{/each}}

过滤器

自来水 -> 净水器 -> 纯净水
需要处理的值 -参数-> 过滤器的函数-返回值->输出新值
过滤器的本质,就是一个function处理的函数。
{{value|filterName}} 
过滤器语法类似管道操作符,它的上一个输出作为下一个输入。
定义过滤器的基本语法如下:
template.defaults.imports.filterName=function(value){
/* return处理的结果 */
}

模板引擎的实现原理

正则表达式:
exec()函数用于检索字符串中的正则表达式的匹配。
如果字符串中有匹配的值,则返回该匹配值,否者返回null。
RegExpObject.exec(string)

示例代码如下:

var str='hello';
var patten=/o/;
console.log(pattern.exec(str));

分组正则表达式

var str='<div> 我是{{name}}<div>';
var pattern=/{{\s*([a-zA-Z]+)\s*}}/
var patternResult=patten.exec(str)
console.log(patternResult)
//得到name相关的分组信息
//["{{name}}","name",index:7,input="<div> 我是{{name}}<div>",groups:undefined]

字符串的replace函数

replace()函数用于字符串中用于一些字符串替换另一个字符,语法如下:
var result="123456".replace("123","abc") //得到的result的值为字符串'abc446'

代码示例如下:

var str='<div> 我是{{name}}<div>';
var data={name: "div"}
var pattern=/{{\s*([a-zA-Z]+)\s*}}/
var patternResult=null;
while(patternResult=patten.exec(str)){
    str=str.replace(patternResult[0],data[patternResult[1]]);
}
console.log(str);

实现简易的模板引擎

实现步骤

1、定义模板结构。
2、预调用模板引擎。
3、封装template函数。
4、导入并使用自定义的模板引擎。

定义模板结构

<script type="text/html" id="template1">
        <div>姓名{{name}}</div>
        <div>年龄{{age}}</div>
        <div>性别{{sex}}</div>
</script>

预调用模板引擎

<script>
        var data={name: "李四",age:23,sex:"男"};
        var ResultString=template("template1",data);
        console.log(ResultString);
        //$("#user-box").html(ResultString); jquery写法
        document.getElementById("user-box").innerHTML=ResultString;
 </script>

导入并使用自定义的模板引擎

<script>
        // 封装template函数。 核心
        function template(event,data){
            var resPattern=null;
            var htmlstr=document.getElementById(event).innerHTML;
            var pattern=/{{\s*([a-zA-z]+)\s*}}/;
            while(resPattern=pattern.exec(htmlstr)){
                htmlstr=htmlstr.replace(resPattern[0],data[resPattern[1]]);
            }
            return htmlstr;
        }
        var data={name: "李四",age:23,sex:"男"};
        var ResultString=template("template1",data);
        console.log(ResultString);
        //$("#user-box").html(ResultString); jquery写法
        document.getElementById("user-box").innerHTML=ResultString;
</script>

Ajax加强

XMLHttpRequest的基本使用

XMLHttpRequest XMLHttpsResquest(简称xhr)是浏览器提供的javascript对象,通过它,可以请求服务器上的数据资源。之前我们学习的jQuery中的Ajax函数,就是基于xhr对象封装出来的。

使用xhr发起GET请求

1、创建XHR对象
var xhr=new XMLHttpRequest();
2、调用open函数,指定请求方式与URL地址
xhr.open("GET","http://……/……/……");
3、调用send函数,发起Ajax请求
xhr.send()
4、监听onreadystatechange事件
xhr.onreadystatechange=function(){
    if(xhr.readystate==4&&xhr.status==200){
        console.log(xhr.responseText);
    }
}

xhr对象readstate的相关属性

0  UNSENT    XMLHttpRequest对象已经被创建,但是未被调用open方法。
1  OPENED     open()方法已经被调用。 
2  HEADERS_RECEIVED     send()方法已经被调用,相应头也已经被接受。
3  LOADING      数据接受中,此时response属性中已经包含部分数据。
4  DONE       Ajax请求完成,这意味着数据传输已经彻底完成或失败。

get请求携带参数的本质

无论使用$.ajax(),还是用$.get(),又或者直接使用xhr对象发起GET请求,当需要携带参数的时候,本质上,都是直接将参数以查询字符串的形式,追加到URL地址里面,发送到服务器的。
$.get('url',{name:'zs',age:20},function(){})
等价于
$.get('url?name=zs&&age=20',function(){})
$.ajax({
    method:'GEt',
    url:'url',
    data:{name:'zs',age:20},
    success:function(){}
    
})
等价于
$.ajax({
    method:'GEt',
    url:'url?name=zs&&age=20',
    success:function(){}
})

URL编码与解码

URL地址中,只允许出现英文相关的字母、标点符号、数字,因此,在URL地址中不允许出现中文字符。
如果URL中需要包含中文这样的字符,则必须对中文符进行编码(转义)。
URL编码的原则: 使用安全的字符(没有特殊用途或者特殊意义的可打印字符)去表示那些不安全的字符。
URL编码原则的通俗理解:使用英文字符去表示非英文字符。

如何对URL进行编码与解码

浏览器提供了URL编码与解码的API,分别是:
encodeURL()  编码的函数
decodeURL()  解码的函数
注意:由于浏览器会自动对URL地址进行编码操作,因此,大多数情况下,程序员不需要关心URL地址的编码与解码操作。

使用xhr发起Post请求

步骤:
1、创建xhr对象。
var xhr=new XMLHttpsRequset();
2、调用xhr.open()函数。
xhr.open("post",'http://……/……/……');
3、设置Content-Type属性(固定写法)
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencode");
4、调用xhr.send()函数,同时指定要发送的数据
xhr.send('bookname=水浒传&……')
5、监听xhr.onreadystatechange事件
xhr.onreadystatechange=function(){
    if(xhr.readyState==4 && xhr..status==200){
        console.log(xhr.responseText);
    }
}

数据交换格式

XML
XML的英文全称是EXtensilble Markup Language,即可扩展标记语言。因此,XML和HTML类似,也是一种标记语言。
​
XML和HTML的区别:
XML和HTML虽然都是标记语言,但是,它们两者之间没有任何关系。
HTML被设计用来描述网页上的内容,是网页内容的载体。
XML被设计用来传输和储存数据,是数据的载体。
​
XML的缺点:
1、XML格式太复杂,和数据无关的代码太多,体积大,传输效率低。
2、在Javascript中解析XML比较麻烦
JSON
JSON的全英文全称是JavaScriptObjectNotation,即"javaScript对象表示法"。简单来讲,JSON就是Javascript对象和数组的字符串表示法,它使用文本表示一个JS对象或数组的信息,因此,JSON的本质是字符串。
作用: JSON是一种轻量级的文本数据交换格式,在作用上类似于XML,专门用于储存和传输数据,但是JSON比XML更小、更快、更易解析。
对象结构中:对象结构在JSON中表示为{}括起来的内容。数据结构为{key:value,key:value,……}的键值对结构。其中,key必须是使用英文的双引号包裹的字符串,value的数据类型可以是数字、字符串、布尔值、null、数组、对象6种类型。
注意事项:
1、属性名必须使用双括号包裹。
2、字符串类型的值必须使用双括号包裹。
3、JSON中不允许使用单括号表示字符串。
4、JSON中不能写注释。
5、JSON的最外层必须是对象或数组格式。
6、不能使用undefined或函数作为JSON的值。
JSON和JS对象的区别
JSON是JS对象的字符串表示法,它使用文本表示一个JS对象的信息,本质是一个字符串。
//这是一个对象
var obj={a:'hello',b:'word'};
//这是一个JSON字符串,本质是一个字符串
var json='{"a":"hello","b":"word"}';
JSON和JS对象的转换
JSON->JS
var obj=JSON.parse('{"a":"hello","b":"World"}')
//结果是{a:'hello',b='word'}
JS->JSON
var json=JSON.stringify({a:'hellp',b:'word'})
//结果是'{"a":"hello","b":"World"}'

序列化与反序列化

序列化:
    把数据对象转换成字符串的过程,叫做序列化,例如:调用JSON.stringify()的函数的操作,叫做JSON序列化。
反序列化:
    把字符串转换为数据对象的过程,叫做反序列化,例如:调用JSON.parse()函数的操作,叫做JSON反序列化。

封装Ajax

<script>
        function resloveData(data){
            var dataString=[];
            for(key in data){
                var str=key+"="+data[key];
                dataString.push(str);
            }
            return dataString.join('&');
        }
        function Ajax(param) { 
            var Xhr=new XMLHttpRequest();
            var qs=resloveData(param.data);
            if(param.method.toUpperCase()=="GET"){
                Xhr.open(param.method,param.url+"?"+qs);
                Xhr.send();
            }else if(param.method.toUpperCase()=="POST"){
                Xhr.open(param.method,param.url);
                Xhr.setRequestHeader("Content-Type","application/x-www-form-urlencode");
                Xhr.send(qs);
            }
            Xhr.onreadystatechange=function(){
                if(Xhr.readyState===4 & Xhr.status===200){
                    var resStr=JSON.parse(Xhr.responseText);
                    param.success(resStr);
                    
                }
            }
         }
        Ajax({
            method : 'GET',
            url :'#',
            data : {name:1,age:20} ,
            success : function (res){}
        });
</script>

XMLHttpRequest level2

旧版本XMLHttpRequest Level2的新功能

1、可以设置HTTP请求的时限。
2、可以使用FormData对象管理表单数据。
3、可以上传文件。
4、可以获得数据传送的进度信息

设置HTTP请求时限

有时,Ajax操作很耗时间,而且无法预知要花费多少时间。如果网速很慢,用户可能要等很久。新版本的XMLHttpRequest对象,增加了timeout属性,可以设置HTTP请求的时限:
    xhr.timeout=3000
上面的语句,将最长等待时间设为3000毫秒。过了这个时限,就自动停止HTTP请求。与之配套的还有一个timeout事件,用来指定回调函数:
xhr.ontimeout=function(event){
    alter("请求超时");
}

使用FormData对象管理表单数据

Ajax操作往往用来提交表单数据。为了方便表单处理,HTML5新增加一个FormData对象,可以模拟表单操作:
var fd=new FormData(); //可以放form元素
fd.append("uname",'zs');
fd.append('upwd','123455');
var xhr=new XMLHttpResquest();
xhr.open('POST',"http://www.liulongbin.top:3306/api/formdata");
xhr.send(fd);
xhr.onreadystatechange=function(){
​
}

上传文件

新版XHMLHTttpRequest对象,不仅可以发送文本本身信息,还可以上传文件。
实现步骤:
1、定义UI结构。
2、验证是否选择了文件。
3、向FormData中追加文件。
4、使用xhr发起文件上传的请求。
5、监听onreadystatechange事件。
var btnUpload=document.querySelector("#btnUpload")
btnUpload.onclick(function(){
    var files=document.querySelector("#files").files
    if(files.length<=0){
        return alter(请选择要上传的文件!);
    }
    var fd=new FormData();
    fd.append('avatar',files[0]);
    var xhr=new XMLHttpRequest()
    xhr.open("post",'http//……');
    xhr.send(fd);
    xhr.onreadystatechange=function(){
        if(xhr.readyState===4 && xhr.status===200){
            var data=JSON.prase(xhr.responseText)
            if(data.status===200){
                document.querySelector("#img").src='http//……'+data.url
            }else{
                console.log(data.message);
            }
        }
    }
})

显示文件上传进度

新版本的XMLHttpRequest对象中,可以通过监听xhr.upload.onprogress事件,来获取文件的上传进度。语法格式如下:
var xhr=new XMLHttpRequest()
xhr.upload.οnprοgress=function(e){
    if(e.lengthComputable){
        //e.loaded 以传输的字节
        //e.total 需传输的总字节
        var percentComplate=Math.ceil((e.loaded/e.total)*100)
        $('#percent').attr('style','width:'+percentComplete+'%').html(percentComplete+'%')
    }
}

监听上传完成的事件

xhr.upload.οnlοad=function(){
    $('#percent').removeClass().addClass('Progress-bar progress-bar-success')
}

axios

Axios是专注于网络数据请求的库。
相比于原生的XMLHttpRequest对象,axios简单易用。
相比于jQuery,axios更加轻量化,只专注于网络请求。
axios发起get请求的语法:
axios.get('url',{params:{/*参数*/}}.then(callback))
axios发起post请求的语法:
axios.post('url',{params:{/*参数*/}}.then(callback))
axios发起ajax请求的语法:
axios.ajax({
    method:'请求类型',
    url:'请求的URL地址',
    data:{/*POST数据*/},
    params:{/*GET参数*/}
    }).then(callback)

同源和跨域

同源

如果两个页面的协议,域名和端口都相同,则两个页面具有相同的源。
什么是同源策略
同源策略是浏览器提供的一个安全功能。
MDN官方给定的概念:同源策略限制了从同一个源加载的文档或脚本如何与来自于另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的安全机制。
通俗的理解:浏览器规定,A网络的JavaScript,不允许和非同源的网站C之间,进行资源的交互,例如:
1、无法读取非同源网页的Coockie、LocalStorage、IndexedDB
2、无法接触非同源网页的DOM。
3、无法向非同源地址发送Ajax请求。

跨域

同源指的是两个URL的协议、域名、端口一致,反之,则是跨域。
出现跨域的根本原因:浏览器的同源策略不允许非同源的URL之间进行资源的交互。
网页: https://www.test.com/index.html
接口: http://www.api.com/userlist
注意:浏览器允许发起跨域请求,但是,跨越请求回来的数据,会被浏览器拦截,无法被页面获取到!
现如今,实现跨域数据请求,最主要的两种解决方案,分别是JSONP和CORS。
JSONP: 出现的早,兼容性号。是前端程序员为了解决跨越问题,被迫想出来的一种临时解决方案。缺点是只支持GET请求,不支持POST请求。
CROS:出现的较晚,它是W3C标准,属于跨域Ajax请求的根本解决方案。支持GET和POST请求。缺点是不兼容某些低版本的浏览器。

JSONP

JSONP的实现原理:
    由于浏览器同源策略的限制,网页中无法Ajax请求非同源的接口数据。但是<script>标签不受浏览器同源策略的影响,可以通过src属性,请求非同源的js脚本。
    因此,JSONP的实现原理,就是通过<script>标签的属性,请求跨越的数据接口,并通过函数调用的形式,接受跨域接口响应回来的数据。
定义一个success回调函数:
<script>
    function success(data){
        console.log('获取到了data数据');
        console.log(data);
    }
</script>
通过<script>标签,请求接口数据:
<script src="https://ajax.frontend.itheima.net:3306/api/jsonp?callback=success&name=zs&age=20"></script>

JQuery中的JSONP

jQuery提供的$.ajax()函数,除了可以发起真正的Ajax数据请求之外,还能够发起JSONP数据请求,例如
$.ajax({
    url:'http://……',
    dataType:'jsonp',
    jsonp:'callback',
    jsonpCallback:'abc',
    success:function(res){
        console.log(res);
    }
})
默认情况下,使用jQuery发起JSON请求,会自动携带一个callback=jQureyxxx的参数,jQueryxxx是随机生成的一个会回调函数名称。
​

综合案例

为了获得到用户每次按下键盘输入的内容,需要监听输入框的keyup事件,示例代码如下:

$.('#ipt').on('keyup',function(){
    var keywords=$(this).val.trim();
    if(keywords.lenth<=0){
        return $('suggest-list').empty().hide();
    }
})

封装getSuggestList函数

将获得搜索建议的代码,封装到getSuggestList函数中,示例代码如下:

function getSuggestList(kw){
    $.ajax({
        url:'https://suggest.taoba.com/sug?q='+kw,
        dataType:'jsonp',
        success:function(res){
            console.log(res)
        }
    })
}

定义模板结构

<script type='text/html' id='tpl-suggestList'>
{{each result}}
    <div class='suggest-item'>{{$value[0]}}<div>
{{/each}}
</script>

定义渲染模板结构的函数

function renderSuggestList(res){
    if(res.result.length<=0){
        return $('suggest-list').empty().hide()
    }
    var htmlstr=template('tpl-suggestList',res);
    $.('#suggest-list').html(htmlStr).show();
}

防抖

防抖策略是当事件被触发后,延迟n秒后再执行回调,如果在这n秒内事件又被触发,则重新记录时间。
在输入框中连续输入一串字符时,可以通过防抖策略,只在输入完后,才执行查询的请求,这样可以有效减少请求次数,节约请求资源;
实现输入框的防抖
var time=null;
function debounceSearch(keywords){
    timer=setTimeout(function(){
        getSuggestList(keywords)
    }),500);
}
$('#ipt').on('keyup',function(){
    ClearTimeout(time);
    debounceSearch(keywords)
})

缓存

实现全局缓存

//定义缓存对象
var cacheObj={}
//将搜索结果保存到缓存对象中
var k=$(this).val.trim();
//2.需要将数据作为值,进行缓存。
cacheObj[k]=res;
//3.优先从缓存中获得搜索建议
if(chacheObj[keywords]){
    return renderSuggestList(cacheObj[k]);
}

节流

节流策略(throttle),顾名思义,可以减少一段时间内事件的触发频率。

节流的应用场景

1、鼠标连续不断地触发某事件(如点击),只在单位时间内只触发一次;
2、懒加载时要监听计算滚动条的位置,但不必每次滑动

节流阀的概念

高铁卫生间是否被占用,由红绿灯控制,红灯表示被占用,绿灯表示可使用。
假设每一个人上卫生间都需要花费5分钟,则五分钟之内,被占用的卫生间无法被其他人使用。
上一个人使用完毕后,需要将红灯重置为绿灯,表示下一个人可以使用卫生间。
下一个人在上卫生间之前,需要先判断控制灯是否为绿色,未知晓能否上卫生间。

案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="day\jquery-min.js"></script>
    <script src="day\dist\js\templat-web.js"></script>
    <style>
        html,body{
            padding: 0;
            margin: 0;
            overflow: hidden;
        }
        #img{
            position: absolute;
            width: 50px;
            height: 50px;
            background-color: thistle;
        }
    </style>
</head>
<body>
    <div id="img"></div>
    <script>
        $(function(){
            var time=null;
            $(document).mousemove(function(e){
                if(time) return ;
                time=setTimeout(function(){
                    $("#img").css('top',e.pageY+'px').css('left',e.pageX+'px');
                    time=null;
                }, 40);
            })
        })
    </script>
</body>

防抖和节流的区别

防抖:如果事件被频繁触发,防抖能保证只有一次触发生效!前面N多次的触发都会被忽略!
节流:如果事件被频繁触发,节流能够减少事件的触发频率,因此节流是由选择性地执行一部分事件!

HTTP协议

通信概念

通信,就是信息的传递和交换。
通信三要素:
1、通信的主体
2、通信的内容
3、通信的方式

通信协议

通信协议是指通信的双方完成通信所必须遵循的规定和约定。
通俗的理解:通信双方采用约定号的格式来发送和接受消息,这种事先约定好的通信格式,就叫做通信协议。

现实生活中的通信协议

张三与李四采用写信的方式进行通信,在填写信封时,写信的双方需要遵循固定得到规则,信封的填写规则就是一种通信协议。

互联网的通信协议

客户端与服务器之间要实现网页的传输,则通信得到双方必须遵守网页内容的传输协议。
网页内容又叫做超文本,因此网页内容的传输协议又叫做超文本传输协议简称HTTP协议。

什么是HTTP协议

HTTP协议即超文本传送协议,它规定了客户端与服务器之间进行网页内容传输时,所必须遵循的传输格式。
例如:
客户端要以HTTP协议要求的格式把数据提交到服务器
服务器要以HTTP协议要求的格式把内容响应给客户端

HTTP写协议的交互模型

HTTP协议采用了请求/响应的交互模型

HTTP请求消息

由于HTTP协议属于客户端浏览器和服务器之间的通信协议,因此,客户端发起的请求叫做HTTP请求,客户端发送到服务器的消息,叫做HTTP请求消息。
注意:HTTP请求消息又叫做HTTP请求报文。

HTTP请求消息

HTTP请求消息请求行、请求头部、空行和请求体4部分组成。
请求方式 空格  URL 空格 协议版本 回车符 换行符
头部字段名称:       值         回车符 换行符
……
请求体

请求行

请求行由请求方式、URL和HTTP协议版本3个部分组成,它们之间用空格隔开。
请求方式 空格 URL 空格 协议版本 回车符 换行符
POST /api/post HTTP/1.1
Host: ajax.fronted.dawd.net:3306
Proxy-Connection:keep-alive
Content-Length:14
​
Accept:*/*

Node

Node.js 作为一个JavaScript的运行环境,仅仅提供了基础功能和API。然而,基于Node.js提供的这些的工具和框架如雨后春笋,层出不穷,所以学会了Node.js,可以让前端程序员胜任更多的工作和岗位:

1、基于Express框架(Express - 基于 Node.js 平台的 web 应用开发框架 - Express 中文文档 | Express 中文网),可以快速构建Web应用

2、基于Electorn框架(Build cross-platform desktop apps with JavaScript, HTML, and CSS | Electron),可以构建跨平台的桌面应用

3、基于restify框架(http://restify.com),可以快速构建API接口项目

4、读写和操作数据库、创建使用的命令行工具辅助前端开发、etc……

总之: Node.js是大前端时代的"大宝剑",有了Node.js这个超级Buff的加持,前段程序员的行业竞争力会越来越强。

查看已安装的Node.js版本号

node -v
C:\Users\Administrator>node -v
v18.16.1

在node.js环境中执行JavaScript代码

node 1.js

fs文件系统模块

fs模板是Node.js官方提供的、用来操作文件的模块。它提供了一系列的方法和属性,用来满足用户对文件的操作需求。
fs.readFile()方法,用来读取指定文件中的内容。
fs.writeFile()方法,用来向指定的文件中写入内容。

导入fs

const fs=require('fs')

fs.readFile()函数

作用:读取文件

var fs = require('fs');
fs.readFile('1.txt', function (err, data) {
  if (err) return console.error(err);
  console.log(data.toString());
});
快捷键 node-file-read-async
function readFile(path: fs.PathOrFileDescriptor, callback: (err: NodeJS.ErrnoException | null, data: Buffer) => void): void (+3 overloads)
namespace readFile
​
异步读取文件的全部内容。
​
@param path 文件的路径。如果提供了 URL,则必须使用file:协议。 如果提供了文件描述符,则基础文件将not自动关闭。

fs.writeFile()函数

作用:写入文件

var fs = require('fs');
var datastr="dawd";
fs.writeFile('1.txt',datastr, function (err) {
  if (err) return console.error(err);
  console.log(datastr.toString());
});
function writeFile(path: fs.PathOrFileDescriptor, data: string | NodeJS.ArrayBufferView, callback: fs.NoParamCallback): void (+1 overload)
namespace writeFile
将数据异步写入文件,如果文件已存在,则替换该文件。

@param path 文件的路径。如果提供了 URL,则必须使用file:协议。 如果提供了文件描述符,则基础文件将not自动关闭。

@param data— 要写入的数据。如果提供了缓冲区或 Uint8Array 以外的内容,则该值将强制转换为字符串

path路径模块

导入path

const path=require('path');

join()函数

作用: 连接路径

const path = require('path');
const pathstr=path.join("/a",'/b/c','../../','/d','e');
console.log(pathstr);
(method) path.PlatformPath.join(...paths: string[]): string
将所有参数联接在一起并规范化生成的路径。

@param paths— 加入路径。

@throws— {类型错误} 如果任何路径段不是字符串。

basebname()函数

作用:删除扩展名

const path = require('path');
(method) path.PlatformPath.basename(path: string, suffix?: string | undefined): string
返回路径的最后一部分。类似于 Unix basename 命令。 通常用于从完全限定的路径中提取文件名。

@param path— 要评估的路径。

@param suffix— (可选)要从结果中删除的扩展名。

@throws— {类型错误} 如果path不是字符串,或者如果ext是给定的,不是字符串。

extname()函数

作用:获得扩展名

var str=path.extname("/da/da/1.txt");
console.log(str);
(method) path.PlatformPath.extname(path: string): string
返回路径的扩展名,从路径最后一部分中字符串的最后一个“.”到字符串的末尾。 如果路径的最后一部分没有“.”,或者路径的第一个字符是“.”,则返回一个空字符串。

@param path— 要评估的路径。

@throws— {类型错误} 如果path不是字符串。

时钟案例

自定义resolveCSS方法:

//导入模板
const fs = require('fs');
const path = require('path');
//设置正则表达式
const regstyle=/<style>[\s\S]*<\/style>/;
//读取html文件
fs.readFile(path.join(__dirname,'day1.html'), function (err, data) {
    if (err) return console.error(err);
    //使用函数resloveCSS
    resolveCSS(data.toString());
  });
/** 提取html中的CSS 
* 
* @param {String} htmlStr  "html字符串"
*/
function resolveCSS(htmlStr) { 
    //使用正则表达式提取文件中的<style></styl>标签
    const r1=regstyle.exec(htmlStr);
    //将提取出来的样式和字符串,做进一步处理。
    const newCSS=r1[0].replace("<style>","").replace("</style>","");
    //将提取出来的css样式,写入到index.css为文件中。
    fs.writeFile(path.join(__dirname,"day1.css"),newCSS, function (err) {
        if (err) return console.error("样式导入失败"+err.message);
        console.log(newCSS.toString());
    });
}

http模块

创建web服务器的基本步骤

1、导入http模块。
2、创建web服务器实例。
3、为服务器实例绑定request事件,监听客户端的请求。
var http = require('http');
http.createServer(function (request, response) {
  response.writeHead(200, {'Content-Type': 'text/plain'});
  response.end('Hello World');
}).listen(8081);

console.log('Server running at http://127.0.0.1:8081/');
(method) ServerResponse<IncomingMessage>.writeHead(statusCode: number, headers?: http.OutgoingHttpHeaders | http.OutgoingHttpHeader[] | undefined): http.ServerResponse<http.IncomingMessage> & {
    ...;
} (+1 overload)
向请求发送响应标头。状态代码为 3 位 HTTP 状态代码,如404.最后一个论点,headers,是响应标头。 可选地可以提供人类可读的statusMessage作为第二个 论点。

headers可能是一个Array其中键和值位于同一列表中。 是的not元组列表。因此,偶数偏移量是键值, 奇数偏移量是关联的值。数组位于同一位置 格式为request.rawHeaders.

返回对ServerResponse,以便可以链接调用。
启动侦听连接的服务器。一个net.Server可以是 TCP 或 一IPC服务器取决于它侦听的内容。

可能的签名:

server.listen(handle[, backlog][, callback])
server.listen(options[, callback])
server.listen(path[, backlog][, callback]) for IPC servers
server.listen([port[, host[, backlog]]][, callback])对于 TCP 服务器
此函数是异步的。当服务器开始侦听时,'listening'将发出事件。最后一个参数callback将被添加为侦听器'listening' event.

All listen()方法可以采取backlog参数以指定最大值 挂起的连接队列的长度。实际长度将确定 通过操作系统通过 sysctl 设置,例如tcp_max_syn_backlog and somaxconn在 Linux 上。此参数的默认值为 511(不是 512)。

All Socket设置为SO_REUSEADDR (see socket(7) for details).

The server.listen()当且仅当存在 第一次出现错误server.listen()致电或server.close()已经 叫。否则,一个ERR_SERVER_ALREADY_LISTEN将抛出错误。

聆听时最常见的错误之一是EADDRINUSE. 当另一台服务器已经在侦听请求的port/path/handle.处理此问题的一种方法是重试 一段时间后:
request对象
只要服务器接受到了客服端的请求,就会调用通过server.on()为服务器绑定的request事件处理函数。
如果想在事件处理函数中,访问与客户端相关的数据和属性,可以使用如下的方式;
request.url
request.method

模块化

模块的分类

内置模块:fs、path、http
自定义模块: 用户之定义创建的模块
第三方模块。

加载模块

const fs=require('fs');
const custom=require('./custom.js');
const moment=require('moment');

模块作用域

自定义模块里的变量、方法。只能在模块内被访问。
好处
防止了全局变量污染的问题。

module对象

在每一个.js自定义模块中都有一个moudle对象,它里面储存了和当前模块有关的信息。
console.log(module);

module.exports对象

在自定义模块中,可以使用module.exports对象,将模块内的成员分享出去,供外界使用。
外界用require()方法导入自定义模块时,得到的就是module.exports所指向的对象。

exports对象

由于module.exports单词写起来比较复杂,为了简化向外共享成员的代码,Node提供了exports对象。默认情况下,exports module.exports指向同一个对象。最终共享的结果,还是以module。exports指向的对象为准。

模块化规范

遵循了CommonJS模块化规范,CommonJS规定了模块的特性和各模块之间如何互相依赖。

每一个模块内部,module变量代替当前模块。
module变量是一个对象,它的exports属性是对外接口。
加载某个模块,其实是加载模块的module.exports属性。

npm与包

格式化时间传统做法

function dateForm(){
    const date=new Date();
    const y=padZero(date.getFullYear());
    const m=padZero(date.getMonth()+1);
    const d=padZero(date.getDate());
    const hh=padZero(date.getHours());
    const mm=padZero(date.getMinutes());
    const ss=padZero(date.getSeconds());
    return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
}
console.log(dateForm());
function padZero(n){
    return n/10>=1? n:'0'+n;
}

npm格式化时间做法

使用npm包管理工具,在项目中安装格式化时间的包moment
使用require导入格式化时间的包
参考moment的官方API文档对时间进行格式化
const moment=require('moment')
var dt=moment().format('YYYY-MM-DD hh:mm:ss')
console.log(dt);

包管理配置文件

多人协作的问题
整个项目的体积是30.4M
第三方包的体积是28.8M
项目源代码的体积1.6M
遇到问题:第三方的包体积过大,不方便团队成员之间共享项目源代码。

如何记录项目中安装了哪些包

package.json包中记录安装了哪些包。

包的分类

项目包
那些被安装到项目的node_moudules目录中的包,都是项目包。
项目包分为两大类:
	开发包

express模块

官方给出的概念:Express是基于Node.js平台,快速、开放、极简的Web开发框架。
通俗的理解:Express的作用和Node.js内置的Http模块类似,是专门用来创建Web服务器的。
Express的本质:就是一个npm上的第三方包,提供了快速创建Web服务器的便捷方法。
Express的中文官网:http://www.expressjs.com.cn

创建基本的Web服务器

1、导入express
const express = require('express')
2、创建Web服务器
const app = express()
3、指定接口
const port = 8081
4、监听get请求
app.get('/', (req, res) => res.send('Hello World!'))
5、调用app.listen(端口号,启动后成功后调用函数),启动服务器。
app.listen(port, () => console.log(`Example app listening on http://127.0.0.1:${port}!`))

监听GET和POST请求

app.get('/', (req, res) => res.send('Hello World!'))

参数一:客户端请求的URL地址。
参数二:请求对应的处理函数
	req:请求对象(包含了与请求相关的属性与方法)
	res:响应对象(包含了与响应相关的属性和方法)
app.post('/', (req, res) => res.send('Hello World!'))

获得URL中携带的查询参数

通过req.query对象,可以访问到客户端通过查询字符串的形式,发送到服务器的参数:
app.get('/', (req, res) => res.send('Hello World!'))
// req.query 默认是一个空对象
// 客服端使用 ?name=zs&age=20 这种查询字符串形式,发送到服务器的参数。
//可以通过req.query对象访问到,例如:
//req.query.name req.query.age

获得URL中的动态参数

通过req.params对象,可以访问到URL中,通过:匹配到的参数:

托管静态资源

express提供了一个非常好用的函数,叫做express.static(),通过它,
我们可以非常方便地创建一个静态资源服务器,例如,通过如下代码就可以将public目录下的图片、css文件、javascript文件对外开放访问了:
app.use(express.static('public'))

nodemon

nodemon动态服务器
nodemon xx.js

模块化路由

为了方便对路由进行模块化的管理,Express 不建议将路由器直接挂载到app上,而是推荐将路由器抽离为单独的模块。
将路由器抽离为单独模块的步骤如下:
1、创建路由器由模块对应的.js文件。
2、调用express.Router()函数创建路由对象。
3、向路由对象上挂载具体的路由。
4、使用moduel.exports向外共享路由器对象。
5、使用app.use()函数注册路由器模块。
const express = require('express')
const app=express.Router();
app.get('/', (req, res) => res.send('Hello World!'))
module.exports=app;
const express = require('express')
const app = express()
const port = 3000
const routes=require('./014.js');
app.use(routes);
console.log(app);
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
app.use("/xx",routes)
/xx是前缀

express中间件

在处理污水的时候,一般都要经过三个处理环节,从而保证处理后的废水,达到排放标准。
处理污水的这三个中间处理环节,就可以叫做中间件。

Express中间件的调用流程

客户端--请求-->中间件1-->中间件2-->中间件N--响应-->客户端
Express的中间件,本质上就是一个function处理函数,EXpress中间件的格式如下:
function(req,res,next){
	next();
}
next函数的作用:
next函数是实现多个中间件连续调用的关键,它表示把流转关系转交给下一个中间件或路由。

中间件函数

中间件的作用
多个中间件之间,共享同一份req和res.基于这样的特性,我们可以在上游的中间件中,统一为req或res对象添加自定义的属性或方法,供下游的中间件或路由进行使用。
定义中间件函数
	function(req,res,next){
	next();
}
全局生效的中间件
function nw(req, res, next) { 
    console.log('这是中间件1');
    next();
}
app.use(nw);
局部中间件
不使用app.use()定义的中间件,叫做局部生效的中间件。
function nw(req, res, next) { 
    console.log('这是中间件1');
    next();
}
app.get('/',nw ,(req, res) => res.send('Hello World!'))
module.exports=app;
中间件的注意事项
1、中间件要放在路由前面。
2、客户端发送过来的请求,可以连续调用多个中间件进行处理。
3、执行完中间件的业务代码之后,不要忘记调用next()函数。
4、为了防止代码逻辑混乱,调用next()函数后不要再写额外的代码。
5、连续调用多个中间件时,多个中间件之间,共享req和res对象。
中间件的分类
应用级别的中间件
路由级别的中间件
错误级别的中间件
Express 内置中间件
第三方的中间件
应用级别的中间件
通过app.use()或app.get()或app.post(),绑定到app实例上的中间件,叫做应用级别的中间件。
路由级别的中间件
通过Router.use()绑定的中间件叫做路由中间件。
错误级别的中间件
函数里面有err参数。放在所有路由之后。
Express内置的中间件
express.static() 快速托管静态资源的内置中间件,例如:HTML文件、图片、CSS样式等。
express.json() 解析JSON格式的请求体数据。
express.urlencoded() 解析URL-encoded格式的请求体数据。

创建web服务器

const express=require("express");
const app=express();
const port = 3000
const router=require("./017.js");
app.use(router);
app.listen(port, () => console.log(`Example app listening on port ${port}!`))

// 路由模块
const express = require('express')
const router = express.Router();
router.get('/', (req, res) => res.send('Hello World!'))
module.exports=router;

编写GET接口

// 路由模块
const express = require('express')
const router = express.Router();
router.get('/', (req, res) =>{
    //获得客服端通过查询字符串,发送到服务器的数据。
    const query=req.query;
    res.send({
        status:0,   //0表示成功、1表示失败。
        msg: 'GET请求成功!' ,//状态描述。
        data: query  //响应给客户端的具体数据。
    }
    )
}
 )
module.exports=router;

编写POST接口

 router.post('/post', (req, res) =>{
    //获得客服端通过查询字符串,发送到服务器的数据。
    const body=req.body;
    res.send({
        status:0,   //0表示成功、1表示失败。
        msg: 'GET请求成功!' ,//状态描述。
        data: body //响应给客户端的具体数据。
    }
    )
}
 )

CORS跨域问题(主流)

使用cors是解决Express的一个第三方中间件。
使用分为如下3步:
1、运行npm install cors 安装中间件
2、使用const cors=require('cors') 导入中间件
3、在路由之前调用app.use(cors())配置中间件

CORS跨域资源共享

什么是CROS
CORS由一系列HTTP响应头组成,这些HTTP响应头决定浏览器是否组织前端js代码跨域获得资源。
配置了CORS相关的HTTP响应头,就可以解决浏览器端的跨域访问权限。
CORS响应头部-Access-Control-Allow-Orign
响应头部中可以携带一个Access-Control-Allow-Origin字段,其语法如下:
Access-Control-Allow-Origin:<origin>
例如,下面的字段可以允许来自:http://itcast.cn的请求:
res.setHeader('Access-Control-Allow-Origin','http://xxxx.cn');
CORS响应头部-Access-Control-Allow-Methods
CORS仅支持客户端发起的GET、POST、HEAD请求。
如果客户端希望通过PUT、DELETE等方式请求服务器的资源,
res.setHeader('Access-Control-Allow-Methods','PUT,GET');
Access-Control-Allow-Headers
如果客户端向服务器发送了额外的请求头信息,则需要在服务器端,通过Access-Control-Allow-Headers的请求头进行声明,否则这次请求会失败!

CORS分类

简单请求
请求方式:GET、POST、HEAD三者之一。
HTTP头部信息不超过以下几种字段:无定义头部字段、Accept、Accent-Language、……。
预检请求
只要符合以下任何一个条件的请求,都需要进行预检请求:
1、请求方式为GET、POST、HEAD之外的请求Method类型。
2、请求头中包含之定义头部字段。
3、向服务器发送了application/json格式的数据。
简单请求和预检请求的区别
简单请求的特点:客户端与服务器之间只会发生一次请求。
预检请求的特点:客户端与服务器之间会发送两次请求,OPTION预检请求成功之后,才会发起真正的请求。
创建JSONP接口的注意事项
如果项目中配置了CROS跨域资源共享,为了防止冲突,必须在配置CORS中间件之前声明JSONP的接口。否则JSONP接口会被处理成开启了CROS的接口。
实现JSONP接口
在使用cors()函数之前定义jsonp模版。
在项目中操作mysql数据库
1、安装操作mysql数据库的第三方模块(mysql)
2、通过mysql模块连接到MYSQL数据库
3、通过mysql模块执行SQL语句
安装操作mysql数据库的第三方模块(mysql)
mysql模块是npm上的第三方命令。
npm i mysql
配置连接模块
var mysql = require('mysql');
var con = mysql.createConnection({
        host: "localhost",
        user: "test",
        password: "123456789",
        database: "student_control_system",
        port:3306,
});
con.connect(function(err) {
         if (err) console.log(err.message);
        console.log("连接成功");
});
查询语句(DDL中的show,DML的select)
con.query("select ……",[],(err,result)=>{
    if(err) console.log(err.message);;
    console.log(result);
});
第一个参数相当于java中的statement、preparstatement。
第二个参数相当于java中的setInt、setString函数
第三个参数相当于java中的executeQuery()
插入语句
con.query("insert ……",[],(err,result)=>{
    if(err) console.log(err.message);;
    if(result.affectedRows===1){
    	console.log("插入成功");
    }
});
第一个参数相当于java中的statement、preparstatement。
第二个参数相当于java中的setInt、setString函数
第三个参数相当于java中的executeUpdate()
更新语句
con.query("update ……",[],(err,result)=>{
    if(err) console.log(err.message);;
    if(result.affectedRows===1){
    	console.log("更新成功");
    }
});
删除语句
con.query("delete ……",[],(err,result)=>{
    if(err) console.log(err.message);;
    if(result.affectedRows===1){
    	console.log("删除成功");
    }
});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值