[淘宝网](http://www.taobao.com/)
![图片标题](file:///Users/wangjing/Desktop/511542077195.jpg)
# 一级标题
## 二级标题
### 三级标题
#### 四级标题
##### 五级标题
###### 六级标题
tips:几个 # 就是几级标题,最小到六级
*这是斜体*
*[这是斜体链接](http://www.taobao.com)*
*斜体,[这是斜体链接](http://www.taobao.com)*
tips:斜体和链接可以混用
这是字体
这是字体
这是字体
这是字体
**加粗**字体
Email:
* list1
* list2
* list3
1. list1
2. list2
3. list3
***
---
- - - -
tips: 三种都一样
在上一行内容缩进的基础上再缩进四个空格
需要换行
这是换行后的下一行
~~中划线~~
这是脚注[^1]
[^1]: 这是脚注说明,会在文章的末尾显示.
默认表格:
First Header | Second Header | Third Header
------------ | ------------- | ------------
Content Cell | Content Cell | Content Cell
Content Cell | Content Cell | Content Cell
左右浮动表格:
First Header | Second Header | Third Header
:----------- | :-----------: | -----------:
Left | Center | Right
Left | Center | Right
tips:默认向左对齐
> 这里的内容在内容块中
命令 | 执行 | 注释 |
---|---|---|
clear | 清空屏幕的内容 | |
pwd | 查看我们所在的目录(位置),刚打开终端的时候,默认在用户目录下。 | percent work directary |
ls | 显示当前目录下的文件内容,ls后面如果什么都不加,默认显示当前目录下的内容。ls 可以和路径配合使用,用于显示路径下的内容 | list show |
ls / | 显示跟目录下的内容 | |
ls ./ | 查看当前目录下得内容 | |
ls …/ | 查看父目录下得内容 | |
ls ~ | 查看用户目录的内容(打开终端默认在用户目录下) | |
ls -l | 会以一个列表的形式,把所有的内容全部输出出来 | |
ls -a | 看隐藏的文件 | |
ls -la | -l和-a的组合 | |
cd xxx | 进入xxx的文件夹(Tab键会自动补齐) | come directory |
cd - | 回到上一个目录 | |
cd ~ | 回到用户目录(刚打开终端时的目录) | |
/ | 根目录 | |
./ | 当前目录 | |
…/ | 上一级目录 | |
mkdir xxx | 在当前目录下,创建一个xxx名字的文件夹 | make directory |
mkdir a b c d | 新建多个文件夹 | |
mkdir -p res/style/scss | 新建多个层级的目录 | |
touch aaa | 在当前目录下创建一个aaa名字的文件 | |
rm 1.txt | 删除名字为1.txt的文件 | remove |
rm -rf 456/ | 删除当前目录下456名字的文件夹,删除文件夹的同时,里面的文件统统删除。 | |
mv 1.txt 123.txt | 移动+改名,将当前目录的1.txt 移动到当前目录,并改名为123.txt | move |
cp 1.txt 2.txt | 将当前目录下的1.txt拷贝一份,并放到当前目录下,并命名为2.txt | |
open . | 打开当前所在的文件夹 | |
open xxx/xxx | 打开指定路径文件 | |
mdfind name.html | 查询指定文件的路径 |
vi 1.c (如果文件存在,则打开这个文件,如果不存在,先创建,再打开)
dd 删除一行(光标所在的那一行) (剪切)
5dd 删除光标下的5行
p 粘贴
yy 复制
5yy 复制5行
u 撤销上一次操作 (undo)
ctrl+r 恢复操作 (redo)
gg 将光标定位在第一行
shift+g 将光标定位到最后一行
num shift+g 将光标定位在第num行
Hyper text makup language (超文本标记语言)
<html>
<head>
<meta charset="UFT-8">
<meta name="keywords" content="关键字,关键字">
<meat name="description" content="网页描述"
href="图标路径" rel="icon">设置网页图标单标签
<title>标题title>
<style>
/*注释标签*/
style>
head>
<body>
<hr>横线单标签
<br>换行单标签
<img src="设置图片路径" width="" height="" alt="当图片无法显示时的描述行文字" title="设置鼠标悬停在图片上时的文字提示">图片单标签
<h1>-<h6>标题标签
<p>段落标签
<font size="16" color="red">font>改变文字大小颜色
<u><ins>下划线标签
<del><s>删除线标签
<b><strong>加粗标签
<em><i>文字倾斜标签
body>
html>
(所有文件在同一个根目录里面)
- 如果图片和文件在同一个文件夹中,直接写图片名称< img src="1.jpg">
- 如果图片在文件的上一级目录中,写../图片名称 < img src="../1.jpg">
- 如果图片在文件的下一级目录中,写文件夹名称/图片名称< img src="images/1.jpg">
<a href="跳转目标页面的路径" target="_self(在当前标签打开目标页面) / _blank(在新标签中打开目标页面)">
<a href="#id值">
  空格
< <
> >
© ©️
<ul>
<li>li>
ul>
<ol>
<li>li>
ol>
<dl>
<dt>标题dt>
<dd>标题项dd>
<dd>标题项dd>
dl>
<table border="1" witdh="表格宽" height="表格高" cellpadding="内容和表格的间距" cellspacing="单元格间距" border-collapse:collapse;
align="表格对齐方式">
<caption>表格名称caption>
<tr align="行内容对其方式">
<th colspan="横向单元格合并" rowspan="纵向单元格合并">th>
<th>th>
<th>th>
tr>
<tr>
<td>td>
<td>td>
<td>td>
tr>
table>
<form action="提交的目标,例如1.php" method="提交的方式,有get/post两种">
<lable for="id名">输入框lable(行内元素,配合for实现对应鼠标焦点)>
输入框<input type="text" name="设置输入框名字" value="设置默认值" maxlength="设置最大输入长度" readonly="readonly(设置只读)" id="id名" placeholder="占位符,为控件设置提示">
box-sizing:border-box; 设置这个属性后,设置元素宽高就是元素实际大小
密码框<input type="password">
复选框<input type="checkbox" checked="checked(默认选中)">
单选框<input type="radio" name="只有相同name值才能实现单选" checked="checked(默认选中)">
下拉列表<select>
<optgroup label="中国区域">
<option>北京option>
<option selected="selected(默认选中)">上海option>
optgroup>
select>
选择文件上传控件<input type="file">
文本域<textarea >textarea>
数据提交按钮<input type="submit">
图片样式提交按钮<input type="image" src="按钮.jpg">
重置按钮<input type="reset">
按钮<input type="button" value="按钮">
form>
/<header>header> 头部区域
/<nav>nav>导航区域
/<article>article>文章区域
/<aside>aside>侧边区域
/<section>section>块区域
/<footer>footer>底部区域
/<video src="路径" autoplay(自动播放,谷歌不支持) controls(显示控件) loop(循环播放)>video>视频播放
<video controls> 兼容写法
<source src="test.mp4">
<source src="test.avi">
video>
<audio>audio>音频播放
<input type="email" name="">请输入邮箱地址
<input type="url" name="">请输入网址
<input type="number" name="" step="设置减少和增加的步数"> 只能输入数字
<input type="text" autofocus(自动获取焦点) required(控件内容不能空)>
<input type="date" name="" >日
<input type="month" name="">月
<input type="week" name="">周
<input type="range" name="">滑块
<input type="color" name="">拾色器
下拉列表
<input type="text" name="" list="abc">
<datalist id="abc">
<option>北京option>
<option>上海option>
<option>广州option>
datalist>
独占一行,可以设置宽高,不设置宽的时候和父级元素宽相同 display:block;
div p h1-h6 ul ol li dl dt dd tr
在一行显示,不能设置宽高 display:inline;
span a font strong em i
在一行显示,可以设置宽高 display:inline-block;
img input
元素就是html标签,通过css模拟一个html标签叫伪元素(伪元素是行内素)
一个标签中最多设置两个伪元素
.box::before { before是标签在父级容器.box里元素的最前面
content:"内容区域";
}
.box::after { after是标签在父级容器元素的最后面
content:"";
}
段落标签不能包含标题标签
段落标签不能包含div
不推介使用行内元素包含块级元素
层叠样式表(cascading style sheets)
层叠性:同一选择器的相同样式属性,后面覆盖前面
继承性:子元素未设置的属性(color / font所有属性 / )可以从父元素继承 【width / height 没有继承性】
优先级:!important (10000) > 行内样式(10000) > id选择器(1000) > 类选择器(100) > 标签选择器(10) > 继承(0)
text-align:center; 元素水平居中
text-indent:2em;首行缩进
text-decoration:none/underline; 设置下划线
text-shadow:0px 0px 10px red,5px 5px 10px blue【左右偏移 上下偏移 模糊度 颜色】; 设置文字影阴
vertical-align:; 设置在垂直方向的对齐方式;
A.解决行内块元素底部3像素空白(vertical-align:baseline;行内块元素默认属性)
一种将行内块转换成块
第二种vertical-align:top(顶线对齐) / bottom(底线) / middle(中线); 【baseline:基线对齐】
B.解决图片垂直居中
先设置行高等于盒子高度再让图片中线对齐;
font-size:14px;
font-weight:700(bold) 400(normal);
font-style:italic normal;
font-family:“宋体”;
line-height:24px;行高(只对文字有作用,行高等于容器高度文字局中)
list-style:none; 去掉列表默认样式
font:700 italic 14px/24px "宋体";
*合写必须设置font-size和font-family,font-size必须在font-family之前,font没有color属性*
backgroun-color:red #222 rgb(100,100,255) rgba(0,0,0,0.1) *a:alpha 通道透明度0-1*;
background-image:url(“2.png”);
background-repeat:repeat / no-repeat / repeat-x / repeat-y; 设置背景图平铺方式(默认平铺)
background-size:200px 100px;(宽 高 背景图尺寸)
Background-size :cover(等比例将父元素铺满)/content(完整显示到父元素中);
background-position:left top / 20px 80px; (左正右负 下正上负)
设置背景图片位置 (left right top bottom center)
【设置两个值:宽 高;设置一个值,后面一个值默认center】
background:transparent(透明色) url("2.png") no-repeat 20px 80px; 背景合写没有个数和顺序限制
box-shadow:inset 5px 5px 5px blue;(盒子影阴,inset设置内影阴)
background:url(img.png) no-repeat left top, url(img.png) no-repeat left bottom;
background-attchment:fixed;(背景图附着)
Background-origin:border-box/padding-box/content-box;(背景图从什么位置开始显示)
background-clip:border-box/padding-box/content-box/text;(背景图从什么位置开始裁切)
线性
div{
background-image:linear-gradient(
to left,to right,to top,to bottom, /*方向到哪*/
0deg,45deg,90deg,135deg,180deg.../*0从y轴下开始,顺时针*/
red 20%, /*色块位置*/
blue 50%
);
background-sizing:200px 80px; /*设置这个后百分比相对于这个宽*/
}
径向渐变
opacity:0.5;(这种透明方式会让标签本身和内容都改变)
overflow:hideen; 超出父元素隐藏
overflow:scroll; 设置滚动条;
overflow:auto; 自动判断是否需要添加滚动条;
overflow:visible; 元素超出父级,没有滚动条,超出部分也正常显示。
display:none; 元素隐藏,隐藏后不占位置;
display:block; 显示元素。
visibility:hidden; 元素隐藏,隐藏后占位置(清除浮动会用);
text-overflow:clip(修剪文本)/ellipsis(省略号代替修剪的文本)/string(用指定字符串代替修剪的文本);(和overflow:hidden; 还有white-space:nowrap;)
* console——escape(“宋体”)查看字体编码
* em:一个相对单位(一个字符大小)
cursor:move/pointer;
<html lang="en">
<head>
<meta charset="UTF-8">
<title>表单加表格title>
<link rel="stylesheet" type="text/css" href="css文件路径"> 外链式
<style type="text/css"> 嵌入式
style>
head>
<body>
<p style="属性:值;属性:值;">p> 行内式
body>
html>
属性选择器: div[class]{} 有class属性的所有div
[class^="o"]{} 类名以字母o开始
[class$="o"]{} 类名以字母o结束
[type*="checkbox"]{} 属性里面有checkbox的type标签
[class][id="one']{}有id名是one并有class类名
标签选择器:p {}
类选择器:. 类名 {}
*注意:不能以数字开头,不能以特殊符号开头,不要用汉字命名*
id选择器:#id名 {}
*一个标签只能调用一个id选择器,一个id选择器只能对应一个标签*
通配符选择器:* {} 选中页面中所有标签
后代选择器 :ul li {} 选中ul标签中所有的后代li标签
子代选择器:ul>li {} 选中ui标签下第一代li标签
指定选择器:ul.one {} ul#two{}
并列选择器:ul,p, div {} 同时改变这些标签的属性
伪类选择器: :link {} 设置链接的样式(不推荐使用,有兼容性)
:visited {} 设置被访问过的标签样式(不推荐使用,只能设置颜色,有缓冲问题)
:hover {} 设置鼠标悬停在标签时的样式
:active {} 设置标签被激活的样式
:focus {} 设置获取鼠标焦点的样式 input:focus{color:red;}
结构伪类选择器:nth-child(n){} 选中父元素中第n个子元素
:nth-last-child(n){} 选中父元素中倒数第n个子元素
:first-child {} 选中父元素中的第一个子元素
:last-child {} 选中父元素中的第最后一个子元素
ul li:nth-child(5n) {} 选中父元素中是5的倍数的li
p:nth-of-type(n) 只读p的第n个
:nth-child(even偶数/odd奇数)
p:empty 读取空的p
盒子模型组成:内容区域,边框(border),内边距(padding),外边距(margin)
注意: 这里的宽高是指盒子内容区域的宽高
盒子实际大小=内容宽高+内边距+边框+外边距
box-sizing:border-box(自动计算)/content-box(默认计算方式);
border-style: none / solid / dashed / dotted;
border-width: 边框粗细;
border-color:边框颜色;
border-collapse:collapse; (表格边框合并)
border:5px solid red;(边框合写)【border-top / border-left / border-bottom / border-right】
border-radius:50%;
Border-radius:20px 20px 20px 20px(4个角水平半径) / 20px 20px 20px 20px(垂直半径);
如果垂直半径和水平半径一样可以省略不写垂直半径,如果四个角半径一样,可以只写一个。
去掉表单控件轮廓线:outline-style: none; 【这里轮廓线是️鼠标点击后的蓝色轮廓】
Border-image-source:url('img.png');
Border-image-slice:20 20 20 20; //切割图片,上右下左
Border-image-repeat:round; //设置切割后图片平铺方式
Border-image-width:20px; //设置边框图片宽度;
让两个盒子浮动,边框通过margin-left:-1px;合并,然后鼠标经过给相对定位提高层级。
加内边距后,盒子会变大,要保持盒子大小,需相应减少盒子内容区域的宽高。
padding:10px 20px 30px 40px; (上 右 下 左)
padding:10px 20px 30px; (上 左右 下)
padding:10px 20px; (上下 左右)
写法同padding
Margin:0 auto; 只会让标准流下的盒子居中,auto只有块级元素才可以生效。
外边距塌陷:
1.上下两个盒子,上面设盒子置下外边距,下面盒子设置上外边距,这两个外边距会以较大的那个外边距合并;
解决方式:只设置一个盒子的外边距。
2.两个嵌套盒子,设置margin-top,这两个margin-top会以较大那个外边距塌陷(这个猜测本质原因是基线重合)
解决方式:
1.给大盒子加1像素外边距或者1像素padding;
2.给父级元素加overflow:hidden;
3.浮动
Body,h1,h2,h3,h4,h5,h6,ul,ol,li,dl,dd,dt,a {
margin:0;
padding:0;
list-style:none;
text-decoration:none;
}
标准流就是网页标准
float:left /right
元素设置浮动后不占位置了
浮动有隐藏的行内转换属性
清除浮动
1.额外标签 clear:both; 在浮动元素同级加一个空元素,给clear属性2.overflow:hidden; 给浮动元素父级添加overflow属性 (使用该属性时,必须保证父元素中没有超出父元素的元素)
3.伪元素清除浮动【.clearfix{ *zoom:1; (加*号意思只有ie7以下浏览器解析)}】
4.双伪元素清除浮动
什么时候需要清除浮动
1.网页布局中,父元素没有设置高
2.父元素中,所有子元素都设置了浮动
注意:一个盒子里有两个子盒子,第一个盒子占位后,第二个盒子不管是浮动还是定位只是它本身不占位置,不会飘在第一个盒子上面。
( position:static;)
静态定位的元素就是标准流的默认位置
静态定位不能改变元素位置
position:absoulte;
绝对定位可以改变元素位置;
绝对定位的元素会以有定位的父元素为参照物,如果父级没有,会参body;
绝对定位的元素是脱标元素,不占位置,行内元素设置绝对定位后可以设置高;
<div class="box1"> /.box1{position:relative;}
<div class="box2">div>
/.box2{position:absoulte; left:50%(父元素); margin-left:box2宽度一半;}
div>
position:relative;
相对定位可以改变元素位置
相对定位以自己的位置为参照物
相对定位元素不会脱标,占位置。(子绝父相)
position:fixed;
固定定位可以改变元素位置;
固定定位元素始终以浏览器html为参照物
固定定位的元素也是脱标元素,不占位置;
只有相对定位/绝对定位/固定定位的元素才有层级
z-index:;值越大层级越高,值相同,后面压前面
如果父元素有层级,那么比较父元素层级,不用比较子元素层级
减少服务器请求次数,提高加载效率。插入背景图定位。
iconfont.cn icomoon.io
1.这种盒子高度改变,图片就不居中了
text-align=center; ling-height=盒子高; vertical-align=middle;
2.插入一个空标签,html结构臃肿
<div>
<img src="">
<span>span>
div>
div{
设置宽高
text-align:center;
}
span {
display:inline-block;
vertical-align:middle;
height:100%;
}
img {
vertical-align:middle;
}
3.用伪元素来让图片垂直居中
div::before {
content:"";
height:100%;
width:0;
display:inline-block;
}
img {
vertical-align:middle;
}
transition 【需要用户动作才能执行】
语法:
transition-property:all; 默认值是all(代表开始状态和结束状态有状态差的所有属性都有动画效果。)[必须有]
transition-duration:1s; (完成动画需要的时间) 【必须有】
transition-delay:2s; (延时执行动画)
transition-timing-function:ease,linear, ease-in,ease-out,ease-in-out; 默认值是ease (速度类型)
transition:all 1s linear;
transition: width 1s ease,height 1s ease 2s;
animation【不需要用户动作就能执行】
语法:
调用并执行动画集
animation:
animation-name函数名
animation-duration动画完成一个周期花费的时间
animation-iteration-count:1;设置执行次数 /*默认1次,infinite无限循环*/
animation-timing-function:linear;动画速度类型;
animation-direction:alternate;设置动画是否在下一周期逆播,默认是normal(恢复开始状态也有动画,当动画执行次数为偶数有逆播效果)
animation-delay:2s;设置动画延时
animation-play-state:paused;设置动画运行或暂停(默认是running)
animation-fill-mode:forwards(动画结束后停在结束状态);设置动画执行完成后的状态,回道开始状态backwards
steps(多少步完成1周动画);步
定义动画集
@keyframes 函数名 {
from{ /*用from to或者百分比来表示动画的开始结束状态*/
开始状态
}
to { /*百分比相对于动画执行时间*/
结束状态
}
}
transform
语法:
旋转
transform-origin:left top; (旋转起始点,可以是像素)[3d里面改变旋转轴]
transform:rotate(60deg); (旋转的度数,正数为顺时针,负数为逆时针)
3D合写要用rotate3d();
【先旋转后位移的时候一定要注意旋转后的轴变了】
缩放
transform:scale(0.5,2); ( x轴,y轴。大于1放大,小于1缩小,取值为0的时候,元素宽高为0;)[放大会让元素里的元素内容都放大]
倾斜
transform:skew(30deg,50deg);
位移
Transform:translate(Xpx,Ypx);
transtorm:translate(100%,50%); 百分比相对于元素自身宽高
合写
transform:translateX(10px) translateY(20px) scale(1) rotateX(10deg) rotateY(20deg)
Transform-style:preserve-3d; (申明这是一个3D的盒子)
perspective:推介600-1000px; 浏览器近大远小透视效果;
浏览器厂商通常都是在属性名称前添加厂商的私有前缀,来测试这些尚未成为标准的特性, 因此,可以借助私有前缀,来解决浏览器对CSS3的兼容性问题。
内核 | 前缀 | 主要浏览器 |
---|---|---|
Trident | -ms- | Internet Explorer |
Gecko | -moz- | Firefox |
Webkit | -webkit- | Chrome、Opera、Safari、Android |
Presto | -o- | 早期Opera |
.box{
-webkit-transition:all 1s;
-moz-transition:all 1s;
-ms-transition:all 1s;
-o-transition:all 1s;
transition:all 1s;
}
/推荐使用 先前缀后标准 顺序/
移动端适配基础知识
获取设备独立像素(物理像素比)
alert(window.devicePixelRatio)
> 该属性规定自动换行的处理方法。
>
> normal (按照浏览器默认的换行方式) | break-all | break-all
> ```
- 设置文字超出以省略号隐藏显示
```css
//注意:要设置宽,不能有高,有高第三行会露出一点
overflow:hidden;
word-break:keep-all; 段落文字有空格就换行;
word-break:break-all; 段落文字在容器末尾换行
text-overflow:ellipsis;文字超出容器显示省略号
-webkit-line-camp:2;文字要显示多少行
/* autoprefixer: off */
-webkit-box-orient: vertical;
/* autoprefixer: on */
display:-webkit-box;将盒子转换为弹性盒子
在服务器环境下,可以直接引用less文件
1. HTML页面直接通过link标签引用 less文件
用less引入样式在index.css
@import 'base.css';
@import "shipei.css";
/*声明变量*/
@bgc:red;
@size:14px;
p{
background:@bgc;
font-size:@size*2;//支持计算
.punlic(100px,200px, red);//调用公共样式
}
/*定义函数公共样式*/
.public(@a,@b,@c){
width:@a;
height:@b;
background:red;
color:@c;
}
/*有默认值的函数公共样式*/
.public(@a:100px,@b:200px,@c:red){
width:@a;
height:@b;
background:red;
color:@c;
}
/*嵌套写法*/
div{
width:200px;
a {
font-size:100px;
}
}
对应生成的css是
div a {
font-size:100px;
}
//快捷键 meat vp
在伸缩盒子中有两条轴
主轴默认水平显示,侧轴垂直
flex-direction:row;(主轴默认值水平)
flex-direction:column;(主轴垂直显示)
flex-direction:row-reverse;(主轴水平反向)
flex-direction:column-reverse;(主轴垂直反向)
justify-content:flex-statr;(默认)
justify-content:flex-end;(右侧对齐)
justify-content:center;
justify-content:space-between;(两端对齐)
justify-content:space-around;(四周留白分布对齐)
align-items:flex-statr;
align-items:flex-end;
align-items:center;
align-itmes:baseline;(基线对齐)
align-itmes:stretch;(拉伸-默认)
flex-wrap:warp;(默认nowarp)
align-content:stretch(默认);
align-content:flex-statr;
align-content:flex-end;
align-content:center;
align-content:space-between;
align-content:space-around;
algin-self:flex-end;
algin-self:flex-start;
algin-self:center;
浏览器默认文字大小16px;
em:长度单位,相对当前标签文字大小
rem:长度单位,相对于当前根目录标签HTML的文字大小
rem适配的思路就是:
用不同设备宽除以相同数得到不同设备html文字大小,然后用设计图尺寸除以文字大小得到rem倍数,因为不同设备根目录文字大小不同,所以不同文字大小乘以相同倍数得到不同设备的尺寸来适配
什么是媒体查询?
1, 媒体指的就是各种设备(移动设备,PC设备) 2, 查询指的就是要检测属于哪种设备 总结: 媒体查询:通过查询当前属于哪种设备,让网页能够在不同的设备下正常的预览
学习媒体查询的核心是什么?
实现页面在不同设备下正常预览.[判断当前设备]
媒体类型
将不同的设备划分为不同的类型,称为媒体类型
- all (所有的设备)
- print (打印设备)
- screen(电脑屏幕,平板电脑),智能手机
媒体特性
用来描述设备的特点,比如宽度,高度...
- width 网页显示区域完全等于设置的宽度
- height 网页显示区域完全等于设置的高度
- max-width / max-height 网页显示区域小于等于设置的宽度
- min-width / min-width 网页显示区域大于等于设置的宽度
- orientation: portrait (竖屏模式) | landscape (横屏模式)
语法关键字
目的将媒体类型和媒体特性链接到一块,进行设备检测
- and 可以将多个媒体特性链接到一块,相当于且
- not 排除某个媒体特性 相当于非,可以省略
- only 指定某个特定的媒体类型, 可以省略
语法
外联式语法
<link rel="stylesheet" type="text/css" href="01.css" media="only screen and (max-width: 420px)">
内嵌式语法
@media only screen and (max-width: 420px) { body { background-color: red; } } 备注: 多个条件联写 @media only screen and (width: 320px) and (height: 568px) {}
//平板设备
@media only screen and(max-width:980px){
.header {
}
}
//手机设备
@media only screen and(min-width:320px)and (max-width:768px) {
.header {
}
Amaze UI:[amazeui.org]
Framework7:[framework.taobao.org]
Bootstrap:[bootcss.com.]
EasyUI[jeasyui.net]
EXTjs[extjs.org.cn]
织梦cms/动易cms
将网页人为的划分为均等的长度,然后排版布局,通常以百分比为单位
介绍
用来开发响应式布局的 HTML + CSS +JS 的框架
下载
点击链接下载
生产环境版本: 代码已经被压缩过,可以直接放到服务器上部署. 源代码版本: 代码没有经过压缩,用户可以修改源代码
通过link标签可以引用
"stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">
通过npm安装
npm install bootstrap
开始使用
1. 准备工作 "viewport" content="width=device-width, initial-scale=1, user-scalable=no"> "X-UA-Compatible" content="IE=edge"> 让部分国产浏览器默认采用高速模式渲染页面 "renderer" content="webkit"> 2. 在HTML页面中引入Bootstrap对应的CSS文件 "stylesheet" type="text/css" href="css/bootstrap.css"> 3. 例如:
"table table-hover">
123132 123132 123132 123132 排版
标题
☞ 可以直接使用 <h1>h1> 到 <h6>h6> 标签 ☞ 可以给标签设置 .h1 到 .h6 的类名表示标题
其他行内元素
☞ Bootstrap 支持所有HTML标签行内元素 ☞ 例如: <mark>让文本高亮显示mark> | <del> 删除线 del> | <s>s> <strong>strong> | <em> em> ... ☞ 新标签: <small>小号文本标签small> 或者 .small类名可以实现相同效果
对齐方式
.text-left : 文本左对齐 .text-center: 文本居中对齐 .text-right: 文本右对齐
改变字母大小写
.text-lowercase: 将字母全部转换为小写 .text-uppercase: 将字目全部转换为大写 .text-capitalize: 将首字母转换为大写
列表
☞ 去掉列表的默认样式: .list-unstyled <ul class="list-unstyled"> <li>li> ul> ☞ 列表项在一行上显示: .list-inline <ul class="list-inline"> <li>li> <li>li> ul> ☞ 实现水平的自定义列表: .dl-horizontal <dl class="dl-horizontal"> <dt>dt> <dd>dd> dl>
样式设置
☞ 给table标签添加 table类 <table class="table"> table> ☞ 各行变色表格效果添加 table-striped类 <table class="table table-striped"> table> ☞ 设置表格边框添加 table-bordered类 <table class="table table-bordered"> table> ☞ 设置鼠标悬停时候样式添加 table-hover类 <table class="table table-hover"> table> ☞ 设置表格设状态: <tr class="active">...tr> <tr class="success">...tr> <tr class="warning">...tr> <tr class="danger">...tr> <tr class="info">...tr>
响应表格
<div class="table-responsive"> <table class="table"> ... table> div> 备注: 必须将表格放到类名是table-responsive的标签中
<div class="form-group">
<label for="exampleInputEmail1">Emailabel>
<input type="email" class="form-control" id="exampleInputEmail1" placeholder="Email">
div>
<div class="form-group">
<label for="exampleInputPassword1">密码label>
<input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
div>
总结:
1. 给表单控件设置 类名 form-control 可以实现默认样式的设置
提示信息和表单控件一行上显示
☞ 为form标签添加 form-inline类名即可 <form class="form-inline"> <div class="form-group"> <label for="exampleInputName2">Namelabel> <input type="text" class="form-control" id="exampleInputName2" placeholder="Jane Doe"> div> form> 总结: 1. 让表单中表单控件在一行上显示,给父元素设置form-inline类名 ✔ 必须保证表单控件的类名是form-control 或者 放到一个 form-group的标签中
多选框
<div class="checkbox"> <label> <input type="checkbox" value=""> Option one is this and that—be sure to include why it's great label> div>
单选框
<div class="radio"> <label> <input type="radio" name="optionsRadios" id="optionsRadios1" value="option1" checked> Option one is this and that—be sure to include why it's great label> div>
一行上显示的多选框
<label class="checkbox-inline"> <input type="checkbox" id="inlineCheckbox1" value="option1"> 1 label> <label class="checkbox-inline"> <input type="checkbox" id="inlineCheckbox2" value="option2"> 2 label>
一行上显示的单选框
<label class="radio-inline"> <input type="radio" name="inlineRadioOptions" id="inlineRadio1" value="option1"> 1 label> <label class="radio-inline"> <input type="radio" name="inlineRadioOptions" id="inlineRadio2" value="option2"> 2 label>
下拉列表
<select class="form-control"> <option>1option> <option>2option> <option>3option> <option>4option> <option>5option> select>
按钮
<button type="button" class="btn btn-default">(默认样式)Defaultbutton> <button type="button" class="btn btn-primary">(首选项)Primarybutton> <button type="button" class="btn btn-success">(成功)Successbutton> <button type="button" class="btn btn-danger">(危险)Dangerbutton>
栅格系统用于通过一系列的行(row)与列(column)的组合来创建页面布局
使用步骤
1. 必须放到类名是 .container 的容器中 <div class="container"> <div class="row"> <div class="col-md-10">.col-md-10div> <div class="col-md-2">.col-md-2div> div> div> 2. 设置列数:一共12列 col-xs-number --- 超小屏幕 手机 (<768px) col-sm-number --- 小屏幕 平板 (≥768px) col-md-number --- 中等屏幕 桌面显示器 (≥992px) col-lg-number --- 大屏幕 大桌面显示器 (≥1200px) 例如: <div class="col-xs-3 col-sm-5">div> 在小屏幕占3列 在平板设备下占5列 3. 设置列偏移 col-md-offset-number | col-sm-offset-number 从左向右偏移 4. 从堆叠到水平排列 ☞ 默认元素独占一行显示 --- 堆叠 ☞ 设置元素占列数,可以在一行上显示 --- 水平排列 5. 流式布局 : 让元素的固定宽度为100%布局 <div class="container-fluid">div> 6. 列排序 <div class="row"> <div class="col-md-9 col-md-push-3">.col-md-9 .col-md-push-3div> <div class="col-md-3 col-md-pull-9">.col-md-3 .col-md-pull-9div> div>
掘金 思否 简书
<input type="button" value="按钮" onclick="alert('Hello World')" />
<head>
<script type="text/javascript">
alert('Hello World!');
</script>
</head>
<script src="main.js"></script>
什么是变量
为什么要使用变量
如何使用变量
var age;
1.var age;
age=18;
2.var age=18;
var age,zheTihs,sex;
age=10;
zheTihs='zs';
用来描述变量的具体特征(在内存中的存储特征)
转义符
var str="今天学习\'js\'"
字符串长度
console.log(str.length);
//这是一个变量
var age=10;
/*
var age=18;
console.log(age);
*/
谷歌浏览器:字符串黑色/数值类型蓝色/布尔类型蓝色/undefined、null灰色
var num = 5;
console.log(num.toString());
var str = '500';
console.log(+str); // 取正
console.log(-str); // 取负
console.log(str - 0);
var num1 = 5;
var num2;
num2=++num1 + ++num1;
这里对应结果是:13=6+7;
- 后置++ - 先赋值给新的变量再自身加
javascript
var num1 = 5;
var num2;
num2=num1++ + num1++;
这里对应结果是:11=5+6;
原理:
var a=3;
b=a++;//b=3,a=4
c=++a;//a=4,c=5;
``````
//条件?(如果条件成立执行问号后面的代码):(如果条件不成立执行冒号后面的代码);
var a=prompt("");
var b=prompt("");
n1>n2 ? alert("最大值是n1") : alert("最大值是n2")
//这里从左往右走,如过第一个条件假,走第二个条件,如果是值依然返回值。
var a=1>9||30;
alert(a);//这里a弹出30;
// 只要有一个条件为true时,结果就为true;
// 当两个条件都为false时,结果才为false;
// 当一个条件为true时,后面的条件不再判断
// 注意:当数值参与逻辑或运算时,结果为true,会返回第一个为真的值;如果结果为false,会返回第二个为假的值;
//这里从左往右走,如过第一个条件假,返回false,如果第一个条件真,走第二个条件,如果是值可以返回值。
var a=12>9&&30;
alert(a);//这里a弹出30;
// 两边条件都为true时,结果才为true;
// 如果有一个为false,结果就为false;
// 当第一个条件为false时,就不再判断后面的条件
// 注意:当数值参与逻辑与运算时,结果为true,那么会返回的会是第二个为真的值;如果结果为false,返回的会是第一个为假的值。
当条件为false时,结果为true;反之亦然。
if(条件){
逻辑代码(条件true执行)
}
else{
逻辑代码(条件false执行)
}
//多条件判断
if(条件){
}else if (条件) {
}else if (条件) {
}else{
}
如果能够明确变量的具体值,可以考虑用switch语句
语法:
switch (变量) {
case 变量值1://这里注意变量值和变量的类型要一样,不然会执行default
逻辑代码;
break;//加break就是条件满足停止继续执行
case 变量值2:
break;
default:
逻辑代码;
break;
}
//1到100求和
var i=1;
var sum=0;
while (i<=100){
sum+=i;
i++;
}
alert(sum);
do{
循环体代码(变量自增自减)
}while(条件)
在程序中如果执行到continue语句时,程序会跳过本次循环进入到下一次循环中
//输出1-10,遇到5跳过
for(var i=1;i<=10;i++){
if(i==5){
contonue;//遇到i等于5不往下走了,直接返回循环i++;
}
console.log(i);
}
当程序执行到break语句的时候,会结束循环程序
for(var i=1;i<=10;i++){
if(i==5){
break;//遇到i==5,不循环了,直接结束整个循环程序;
}
console.log(i);
}
数组和变量都是在程序中保存数据的容器,数组一次可以存放多条数据。
var arry=new arry(5);//这里面5是数组的长度 ,里面每一个值是undefined。
var arry=new arry(10,20,30,40);//这里面是数组中存的数据,数组的长度是4.
//直接给数组赋值
var ary=[1,2,"asd",ture];
//获取数组中的值
console.log(ary[1]); //打印出2
//通过循环获取数组中的买一个值(遍历)
for(var i=0;i<4;i++){
console.log(ary[i]);
}
//获取数组的长度
ary.length;
//通过索引的方式给数组赋值
//在数组中索引是从0开始的
var ary=[];
ary[0]=1;//把数字1放到索引是0的数组中
//删除数组的方法:
arry.splice(要删除的位置,要删除的长度);
//判断数组中是否存在某一项
arry.indexof(要判断项);
和数组一样都有索引和长度,伪数组不能调用真正数组中内置的方法
将页面中的一段功能代码封装到一个容器中方便重复使用
1.声明函数
//关键字声明
function f1(){
}
//表达式申明
var f1=function(){
}
2.调用函数
3.函数中的参数
函数的参数可以是任何的数据类型
形参:定义变量或者数组
实参:具体值
//有参函数
function fn (a,b){
}
//调用函数时候,传递参数(实参)
fn(100,1000);
function (arry){
var max=arry[0];
for(var i=0;i<arry.length;i++){
if(max<arry[i]){
max=arry[i];
}
}
return max;//把max的值返回到函数外部
//如果不用返回值,就需要在函数内部弹出结果
alert(max);
}
var abc=[1000,2,3,100];
var n1=get_max(abc);//定义一个变量接受返回的值
alert(n1);
function fn(){
}
function(){
}
(function fn(a){
alert(a);
})()//这个小括号里面的实参可以传给a
全局作用域
局部作用域
在函数内部形成的一块区域
块级作用域
var a=25
abc();
function abc(){
alert();
var a=10;
}
//预解析>>变量提升+函数声明提升
var a;
function abc(){
var a;
alert (n1);
a=10;
}
a=25;
abc();
JavaScript 中的所有事物都是对象:字符串、数字、数组、日期,等等。
//对象中的值都是以键值对形式出现的
//key:值;
//例如创建一个汽车对象
var car={
name:‘法拉利’,
color:red,
qidong:function(){
alert("汽车启动");
},
shace:function(){
alert("汽车停止");
}
}
//通过js中内置的构造函数创建对象
var zs=new object();//内置
zs.name="zs";
zs.age=18;
关键字new:实现调用构造函数,创建对象
//工厂方式
function createPeole(uname,uage,uheight){
var obj=new Object();//内置
obj.name=uname;
obj.age=uage;
obj.height=uheight;
return obj;
}
var zs=createPeole("zs",18,180);
var ls=createPeole("ls",18,180);
alert(typeof zs);>>object
//自定义构造函数创建对象
function People(uname,uage,uheight){
this.name=uname;//this指向自定义构造函数创建的对象
this.age=uage;
this.height=uheight;
return this;
}
var zs=new People("zs",18,180);//自定义构造函数创建的对象
var ls=new People("ls",18,200);
//可以直接通过 对象.属性名()获取
alert(car.name);
//可以通过 对象["属性名"];
alert(car["name"]);
car.name="布卡龙";
delete car.name;
car.name="霸道";
for(key in car){
console.log(car[key]);
//不能用下面这两个,因为key是一个存储了对象中所有属性名的变量
//console.log(car.key);
//console.log(car['key']);
}
**begin** (可选)
从该索引处开始提取原数组中的元素(从0开始)。
如果该参数为负数,则表示从原数组中的倒数第几个元素开始提取,slice(-2)表示提取原数组中的倒数第二个元素到最后一个元素(包含最后一个元素)。
如果省略 begin,则 slice 从索引 0 开始。
**end**(可选)
在该索引处结束提取原数组元素(从0开始)。slice会提取原数组中索引从 begin 到 end 的所有元素(包含begin,但不包含end)。
slice(1,4) 提取原数组中的第二个元素开始直到第四个元素的所有元素 (索引为 1, 2, 3的元素)。
如果该参数为负数, 则它表示在原数组中的倒数第几个元素结束抽取。 slice(-2,-1)表示抽取了原数组中的倒数第二个元素到最后一个元素(不包含最后一个元素,也就是只有倒数第二个元素)。
如果 end 被省略,则slice 会一直提取到原数组末尾。
如果 end 大于数组长度,slice 也会一直提取到原数组末尾。
//截取数组,第一个表示从哪开始,第二个表示从哪结束,end值取不到
var ary1=[‘a’,‘b’,‘c’,‘d’,‘e’,‘f’,‘g’];
ary1.slice(2,5);
提供了一系列的与数学相关的属性或方法
Math.sin(x);
Math.cos(x);
Math.tan(x);
直接通过对象.属性(方法);
var get={
test:function(){
}
}
get.test();
通过构造函数创建对象,然后通过对象.属性(方法);
function Get(){
this.test=function(){
}
}
var n1=new Get();
Get.test();
//获取当前系统时间
var d=new Date();//=new Date('1992-8-8')获取指定日期的时间//=new Date(year,month,date);
console.log(d);
//获取当前系统时间对应的毫秒表示法
console.log(d.valueOf());
console.log(d.getTime());
//H5中的方法
Date.now();
浏览器平台对外公开的操作浏览器和网页的接口
文档树:浏览器在加载html文件时,会把文档、文档中的标签、属性、文本、注释转换成对象,然后按照标签的关系以树状结构存储到内存中
节点对象:文档树中的对象也称为节点对象,包括(文档、元素、文本、属性、注释)
onclick 鼠标点击事件
onmouseenter 鼠标进入元素事件
onmouseleave 鼠标离开元素事件
//语法:事件源.事件类型=事件处理程序
btn.onclick=function(){
console.log(this);
};
//事件处理程序的本质
onclick本质上就是事件源这个对象中的一个键值,默认值是null
给事件源注册事件,本质上就是会给onclick赋值一个函数,所以onclick是事件源的一个方法
当用户点击时,浏览器自动调用了btn.onclick()
事件处理程序中的this关键字指向事件源本身
//取消a标签的默认跳转行为
方式1
事件处理程序最后:return false;
方式2
给a标签的href设置javascript:,表示将来点击a,会阻止默认跳转行为,并仅仅会执行js代码
方式3
e.prevenDefault(); 有兼容性问题
//通过a可以打开拨号应用
<a href="tel:">拨号</a>
//通过a可以打开默认邮件应用
<a href="mailto:">邮件</a>
语法:
获取属性值 元素.属性名
设置属性值 元素.属性名="";
//获取类名,不能用元素.clss,要用元素.className
innerText/textContent,获取文本
//textContent有兼容性问题
innerHTML,获取内容,包含子标签和文本
var div=getElementById('dear');
div.style.backgroundColor="red";
var div=getElementById('dear');
div.className='a';
//这里面a是div的class类名,样式写在css里面了
//value操作表单元素的内容
元素.value;返回字符串
//checked操作表单元素是否选中
元素.checked;返回布尔值
//disabled操作表单元素是否禁用
元素.disabled;返回布尔值
//selected操作表单下拉框
元素.selected;返回布尔值
option.selected=false;
//下拉框的多选效果用multiple
<select id="sel" multiple></select>
//在原生js中没有:selected选择器
:checked选择器针对所有表单元素
//获取自定义属性
元素.getAttribute('属性名');
//修改自定义属性
元素.setAttribute('属性名,要修改的')
//移除自定义属性
元素.removeAttribute('属性名')
//注意:这三个方法还可以操作系统自带的属性
//通过子节点获取父节点:
子节点.parentNode
//通过父节点找子节点:
父节点.childNodes(这里获取的子节点,包含text和元素)
父节点.children;(这里获取的是子元素)
父节点.firstElementChild;(获取第一个子元素)
父节点.lastElementChild;(获取最后一个子元素)
//获取兄弟节点
节点.nextElementsibling;(获取下一个兄弟)
节点.previousElementsibling;(获取上一个兄弟)
nodeType//1-——元素/3———text
nodeName//大写的标签名——元素/#text——text
nodeValue//null————元素/文本内容——文本
//通过innerHtml动态创建
var str=ul.innerHTML;
ul.innerHTML=str+'我是新来的 '
//通过createElement()创建(性能高)
var newLi=document.createElement('li');
ul.appendChild(newLi);
newLi.innerText="我是新来的"
//通过appendChild()追加元素
appendChild()
//通过removeChild()删除元素
removeChild()
//通过inserBefore()删除元素
父级元素.inserBefore(新节点,旧节点)
//通过replaceChild()删除元素
父级元素.replaceChild(新节点,旧节点)
//通过cloneNode()删除元素
元素.cloneNode(布尔值);false——只克隆元素本身/true——克隆元素和内部所有元素
因为以前注册事件的方法不能给同一个按钮注册多次相同事件
btn.addEventListener("click",function(){
console.log(1);
})
事件对象详解
document.onclick=function(e){
//处理程序中第一个行参就是事件对象
console.log(e);
}
e.touches[0].clientY
手指对象的clientX/Y 【参照可视区域的水平/垂直像素距离】@普通事件注册方式:非官宣,兼容好,但是同一个事件源多次注册相同事件会覆盖
@普通事件解绑方式:btn.οnclick=null;
@用事件监听注册事件(标准方式),有兼容性
事件源.addEventListener(‘事件’,事件处理程序,是否捕获);
@解绑事件(前提:注册事件处理程序时,处理程序要有名字)
事件源.romoveEventListener(‘事件’,事件名);
输入框事件
oninput 【输入框输入事件】
textarea.οninput=function(){};
鼠标事件
onclick 【鼠标点击事件】
onmouseenter 【鼠标进入事件】//不支持冒泡
onmouseleave 【鼠标离开事件】//不支持冒泡
onmouseover 【鼠标进入事件】
onmouseout 【鼠标离开事件】
onmousedown 【鼠标按下事件】
onmouseup 【鼠标弹起事件】
onmousemove 【鼠标移动事件】
键盘事件(一般都给document绑定)
onkeydown 【键盘按下事件】
onkeyup 【键盘弹起事件】
滚动事件
onscroll 【滚动条事件】
手指触摸事件(用事件监听注册)
document.addEventListener('touchend',function(){
console.log("松开");
})
touchstart 【手指按下事件】
touchmove 【手指移动事件】
touchend 【手指松开事件】
transitionend事件 【css过渡结束后检测的行为】(事件监听注册)
过渡谁,谁就是事件源
浏览器对象模型
window.pageYOffset //设置或返回当前页面相对于窗口显示区左上角的 Y 位置。
window.pageXOffset //设置或返回当前页面相对于窗口显示区左上角的 X 位置。
这两个相当于document.documentElemnt.scrollTop/ScrollLeft;卷进去的距离
window.innerWidth //返回窗口的文档显示区的宽度。
window.innerHeight //返回窗口的文档显示区的高度。
- window对象被 称为顶级对象 或全局对象 。
- 因为全局变量和全局函数本质上都是window对象的属性或方法。
- window对象可以省略。
面相对象不是替代面向过程,而是面向过程的更高一级的封装
Object Oriented Programming,简称OOP,是一个编程开发思想。
它将真实世界的各种复杂关系抽象成一个个对象,然后由对象之间的分工与合作,完成对真实世界的模拟
创建对象:new 构造函数名();
构造函数:
内置构造函数:Object、Date、Array、Math
自定义的:Dog、Cat、Shab
创建对象:new 类名();
对象查找属性的一个流程
1. 会先从对象本身找
2. 没有,通过_proto_提供的原型地址,找到原型
3. 在原型中找对应的属性和方法
4. 没有,通过原型的_proto_提供的原型地址,找到原型
继承时类(子类)与类(父类)之间的关系
属性不能改,方法可以改
//人类
function Person() {
name:"人类",
age:10
}
Person.prototype.eat=function() {
}
var p1=new Person();
//学生类
function Student() {}
var stu1=new Student();
//更改子类原型的指向
Student.prototype=new Person();
//给新的原型加一个能找到student函数的contructor属性
Student.prototype.contructor=Student;
属性能继承,方法不能
function Person(name,age) {
this.name=name;
this.age=age;
}
var obj={};
Person.call(obj,'张三',18);
consloe.log(obj); //name:"张三",age:18
// 【人类→父类】 function Person(name,age,gender) { this.name = name; this.age = age; this.gender = gender; }; Person.prototype.eat = function() { console.log('我会吃....'); }; Person.prototype.run = function() { console.log('我会跑....'); }; Person.prototype.sayHi = function() { console.log('你好.'); }; // 【学生类→子类】 function Student(name,age,gender) { // this在此的指向是当前创建的学对象 stu1、stu2 var obj = this; // 借用继承 Person.call(obj,name,age,gender); } // 原型继承 Student.prototype = new Person(); Student.prototype.constructor = Student; // 创建一个学生对象 var stu1 = new Student('张三',11,'男'); var stu2 = new Student('李四',12,'女'); stu1.sayHi(); stu2.eat(); // 总结:组合继承 // 借用:借用属性 // 原型:继承的方法
语法:函数名.call(调用者,实参,实参);
作用:函数借用时会立即执行,this指向调用者
语法:函数名.apply(调用者,实参,实参);所有实参要放到数组
fn.apply(obj,[‘zs’,10])
作用:函数借用时会立即执行,this指向调用者
语法:函数名.bind(调用者,实参,实参);
作用:函数借用时,不会立即执行,返回一个新的函数,将来手动调用新的函数,this指向调用者
var obj={
0:11,
1:22,
2:33,
3:44,
length:4
};
Array.prototype.push.call(obj,55);
Array.prototype.push.apply(obj,[55]);
Array.prototype.push.bind(obj,55)();
函数名.arguments
获取用户传入的实参
函数名.length
获取函数形参个数
函数名.name
获取函数名字
闭包是能够读取其他函数内部变量的函数
好处:维护私有变量的安全
内存中,谁清理内存中没用的数据——CG(保洁Garbage Collection)
变量的生命周期:当程序关闭时,会被从内存中释放,变成垃圾数据
变量的生命周期:函数执行完就被释放了,变成垃圾数据
内层作用域可以访问外层作用域中的变量,但是外层作用域无法访问内层中的变量
function bieshu(){
var a='三儿';
var guanjia=function(v){
console.log(a);
a=v;
console.log(a);
}
return guanjia;
}
var cyqz=bieshu();
cyqz();
程序调用自身的编程技巧称为递归
递归前进段
边界条件
递归返回段
减少代码量
//一组年龄10,12,14,16,18,20...求第n个人的年龄
function age(n){
if(n==1){
return 10;
}else {
return age(n-1)+2; //age(5) <=age(4) <=age(3) <=age(2) <=age(1)=10
}
}
var r=age(5);
console.log(r);//=>18
两种方法
1)for in 循环
2)Object.assign()
是对字符串操作的一种逻辑公式,根据字符串规则实现对字符串的提取、修改、替换
普通字符
特殊字符(元字符、限定符、中括号、或模式、分组模式、修饰符、正则转译符)
| 字符 | 描述 |
| ---- | :------------: |
|||
|||
|||
|||
元字符
\d //匹配数字
\D //匹配非数字
\w //匹配字母数字或下划线
限定符
\d\d //表示查找双数,单数不匹配
\d{11} //查找连续的11个数字
\d{3,} //查找至少3个数相连的数字
\d{4,5} //查找至少3个最多5个数相连的数字,如果是10个数,会分成两组来找
中括号
[] //表示一个范围
或模式
baidu|guge //这两个都可以选中
分组模式
(你好) //表示分组
修饰符
g //表示全局
i //忽略大小写
转译符
\
var str="1";
//创建正则对象
var reg=new RedExp('\\d');
//简写方式
var reg=/\d/;
//检查字符串是否匹配
var isOk=reg.test(str);
console.log(isOk);
<script src=jquery.js></script>
console.log($===jquery); //ture
//$ 是一个函数
//$("选择器") 函数需要调用
//调用完毕后,返回要给JQuery类型的对象
//创建一个对应的jquery对象
<button id="nbtn"></button>
var $btn=$("#btn");
$.fn=$.prototype; // 它两指向同一个地址,$也可以用jquery代替
##JQuery对象和DOM对象
//获取对应jquery对象
var $btn=$("#btn");
var #lis=$("li")
//不管是获取一个还是获取一组元素,将来都返回一个伪数组,这个伪数组是jquery对象
各有各的属性和方法
var btn=document.qureySelector("button");
var $btn=$(btn);
var $btn=$("button");
var btn=$btn[0];
//也可以这样
var btn=$btn.get[0];
$(“选择器”).事件名(事件处理程序);
var $btn=$("button");
$btn.click(function(){
alert("1");
})
//在给一组div注册事件时,jquery库内部自动循环给每一个div注册事件
$("div").click(function(){
//this不是指jquery对象,是指向原生jsDOM对象
//this.text("hello");这个不对
$(this).text("hello");
var num=$(this).index();
$(this).text("hello"+num);
})
$("div").css("width",300);
$("div").css("background","red");
$("div").css({
width:300,
height:300,
background:"blue"
});
var w=$("div").css("width");
//:eq(index) ,第几个,索引从0开始的
//:even 选择索引号为偶数的元素,从零开始
//:odd 选择索引号为奇数的元素
$("tody tr:even").css("background","skyblue");
//选择器 eq
$("li:eq(1)").css("background","red");
//筛选方法 eq
$("li").eq(1).css("background","red");
// 遍历祖先
对象.parent();// 方法返回被选元素的直接父元素,只会向上一级对 DOM 树进行遍历。
对象.parents(); //方法返回被选元素的所有祖先元素,它一路向上直到文档的根元素 ()
对象.parents("ul"); //使用可选参数来过滤对祖先元素的搜索(只搜索祖先元素是ul的元素)
对象.parentsUntil(); //方法返回介于两个给定元素之间的所有祖先元素
// 遍历后代
children() //方法返回被选元素的所有直接子元素,该方法只会向下一级对 DOM 树进行遍历。
find("*") //方法返回被选元素的后代元素,一路向下直到最后一个后代。[必须传参,*或者指定元素]
// 遍历同胞
siblings() //方法返回被选元素的所有同胞元素。
next() //方法返回被选元素的下一个同胞元素,该方法只返回一个元素。
nextAll() //方法返回被选元素的所有跟随的同胞元素。
nextUntil() //方法返回介于两个给定参数之间的所有跟随的同胞元素
prev(), prevAll() 以及 prevUntil() //方法的工作方式与上面的方法类似,只不过方向相反而已:它们返回的是前面的同胞元素(在 DOM 树中沿着同胞之前元素遍历,而不是之后元素遍历)
// 过滤元素
first() //方法返回被选元素的首个元素
last() //方法返回被选元素的最后一个元素。
eq() //方法返回被选元素中带有指定索引号的元素。索引号从 0 开始
filter() //方法允许您规定一个标准。不匹配这个标准的元素会被从集合中删除,匹配的元素会被返回。
not() //方法返回不匹配标准的所有元素。
对象.show();显示哪个元素
对象.hide();隐藏哪个元素
对象.hasClass();检查是否有类名
对象.addClass();添加类名
对象.removeClass();移除类名,如果不传参,会移除所有类名
对象.toggleClass();如果有这个类名移除,没有就添加
原生的window.onload事件是页面中所有资源加载完执行
入口函数仅仅是等DOM树加载完就执行
$(document).ready(function(){
})
//简写
$(function(){
})
$("div").attr("id","box");
$("div").attr("pic","10086");
$("div").attr("pic");
$("div").removeAttr("id");
prop 针对selected 、checked、disabled
$("input").prop("disabled");
//也可以这样
$('input').[0].disabled;
$("input").prop("checked",true);
$("div").text("哈哈哈
");
$("div").text();
$("div").html("哈哈哈
");//这个会渲染
$("div").html();//这个会渲染
$("input").val("发送");
$("input").val();
//语法
对象.show([运动时间(毫秒)],[运动线型],[fn])
对象.hide([运动时间(毫秒)],[运动线型],[fn])
对象.toogle([运动时间(毫秒)],[运动线型],[fn]) 切换
//语法
对象.slideDown([运动时间(毫秒)],[运动线型],[fn])
对象.slideUp([运动时间(毫秒)],[运动线型],[fn])
对象.slideToogle([运动时间(毫秒)],[运动线型],[fn]) 切换
//语法
对象.fadeIn([运动时间(毫秒)],[运动线型],[fn])
对象.fadeOut([运动时间(毫秒)],[运动线型],[fn])
对象.fadeToogle([运动时间(毫秒)],[运动线型],[fn]) 切换
animate(params,[speed],[easing],[fn])
//param:需要传入一个对象。(动画属性集合)
$("div").animate({
width:300,
height:300,
opatiy:1;
},3000)
对象.stop(clearQueue,jumpToend);
clearQueue--true:清空所有动画
clearQueue--false:清空当前运行的一个动画(默认)
jumpToend--true:停止当前动画,并立刻运动到目标
jumpToend--false:停止动画,保持当前停止状态,不会运动到目标(默认)
$("< li>")
向父元素最后面追加
新创建的Jquery对象.appendTo($(“父元素选择器或者父元素的jquery对象”));
父元素jQuery对象.apeend(新创建的jQuery对象);
var $newLi=$('');
$newLi.appendTo($("ul"));
//也可以这样
$("ul").append($newLi);
向父元素最前面追加
新创建jQuery对象.prependTo(‘父元素选择器’);
父元素jQuery对象.prepend(新创建的jQuery对象);
var $newLi=$('');
$newLi.prependTo($("ul"));
//也可以这样
$("ul").prepend($newLi);
.remove()
//删除页面中的h2
$("h2).remove()
.empty(); //推介使用,清空内部所有的元素及元素相关的事件
.html(""); //仅仅清空内部元素,不清内部中的元素事件
.clone(布尔值); 返回克隆好的元素 /false//表示仅仅克隆内容 true//克隆内容和事件/
对象.offset();–返回的是一个对象(有top/left属性)/且参照文档
对象.offset().top;
对象.position();–返回一个对象/参照上级元素
对象.click(function(){
//如果不设置动画,直接给window注册
$(window).scrollTop(0);
//如果设置动画,给html/body设置
$('html,body').animate({
scrollTop:0;
})
})
$(btn).click(function(){
alert(1);
});
//底层
$(btn).on('click',function(){
alert(1);
});
//底层
//事件源.addEventListener('事件',事件处理程序,是否捕获);
jquery对象.on(事件名,选择器,事件处理程序)
$('div').on('click','p',function fn1(){
//this--所点的子孙元素(DOM)
alert($(this).text());
})
$('div').off('click',fn2);
$('div').off('click','p',fn2);
bind和unbind注册事件
delegate实现事件委托
对象.trigger(‘click’);
<audio src="ss.mp3"></audio>
<button id="play">播放</button>
<button id="pause">暂停</button>
$("#play").click(function(){
$('audio').[0].load();
$('audio').[0].paly();//jq中没有操作音频视频的方法
})
pause(); //暂停
play(); //播放
load(); //重新加载
调用一些方法来做设置操作时,方法结束后返回调用的对象,以便继续使用其他方法
var obj={
name:'zs',
age:1,
sing:function(){
console.log('嗯哼个');
},
da:function(){
console.log('chulai');
}
}
obj.sing();
obj.da();
//这么写不行,因为方法调用返回值为undefind
obj.sing().da();
//给方法加return this;就可以了
obj.sing().da();
var obj={
name:'zs',
age:1,
sing:function(){
console.log('嗯哼个');
return this;
},
da:function(){
console.log('chulai');
}
}
end方法回到链式上的上一个jq对象
$('li')//li对象
.eq(1).css('color','red')//第二个li对象
.parent().css('color','yellow')//父级对象
.end(); //回到eq(1)对象
如果 被 其 他 库 中 的 被其他库中的 被其他库中的覆盖了,解决办法
设计目的是提供JQuery的类似API,有一个5-10k的通用库,分模块引入
强大的触摸滑动插件
是继ES4和ES5之后的js语言规范,提供更加方便的新语法弥补js语言本身的缺陷
有兼容问题
let
let 定义变量,变量不可以重名,必须先定义再使用
具有块级作用域
没有变量提升
代码演示
let age = 18;
{
// 外部无法score,因为有块级作用域
let score = 100;
}
for (let i = 0; i < 10; i++) {
// i 只能在此范围内使用,因为有块级作用域
}
const
常量一旦初始化,不可以重新赋值
const 定义常量,常量不可以重名,必须先定义再使用
具有块级作用域
没有变量提升
代码演示
// 常量名一般大写
const PI = 3.1415926;
// 报错,常量定义必须进行初始化
const MAX;
小结
关键字 | 变量提升 | 块级作用域 | 其它 |
---|---|---|---|
let | × | √ | 先定义再使用,不可以重名 |
const | × | √ | 先定义再使用,不可以重名 |
var | √ | × | 直接使用,可以重名 |
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
方便获取数组中的某些项
let arr = [5, 9, 10];
let [a, b, c] = arr;
console.log(a, b, c); // 输出 5 9 10
// 默认情况获取到的变量需要和对象的属性同名
let obj = {foo: 'aaa', bar: 'bbb'};
let { foo, bar } = obj;
// 更改变量的名称
let obj = {foo: 'aaa', bar: 'bbb'};
let { foo: a, bar: b } = obj;
let obj = {
name: 'zs',
age: 18,
dog: {
name: 'BYD',
age: 1
}
}
// 通过模式匹配,获取 dog 的 name 和 age
// dog 是匹配源数据中的模式
let { dog: { name, age } } = obj;
// 假设从服务器上获取的数据如下
let response = {
data: ['a', 'b', 'c'],
meta: {
code: 200,
msg: '获取数据成功'
}
}
// 如何获取到 code 和 msg
let { meta: { code, msg } } = response;
ES6 中允许使用箭头定义函数 (=>),目的是简化函数的定义并且里面的this也比较特殊。
箭头函数的定义
let fn = x => x * 2;
// 等同于
let fn = function (x) {
return x;
}
如果箭头函数的只有一个参数可以省略小括号,否则参数的小括号不可以省略
let fn = (x, y) => x + y;
// 等同于
let fn = function (x, y) {
return x + y;
}
如果箭头函数的代码块中不止一条语句的话,不能省略大括号,如果需要返回值,必须添加 return
let fn = (x, y) => {
console.log(arguments);
x = 2 * x;
y = 2 * y;
return x + y;
}
箭头函数不可以作为构造函数使用
箭头函数内部没有 arguments
ES6 之前函数不能设置参数的默认值
// ES5 中给参数设置默认值的变通做法
function fn(x, y) {
y = y || 'world';
console.log(x, y);
}
// ES6 中给函数设置默认值
function fn(x, y = 'world') {
}
rest 参数:剩余参数,以 … 修饰最后一个参数,把多余的参数都放到一个数组中。可以替代 arguments 的使用
// 求一组数的最大值
function getMax(...values) {
let max = values[0];
for (let i = 0; i < values.length; i++) {
if (max < values[i]) {
max = values[i];
}
}
return max;
}
// 调用
console.log(getMax(6, 1, 100, 9, 10));
注意:rest 参数只能是最后一个参数
扩展运算符
扩展运算符,可以看成 rest 参数的逆运算,也是 … 可以把数组中的每一项展开
// 合并两个数组
let arr1 = [1, 2];
let arr2 = [3, 4];
let arr3 = [...arr1, ...arr2];
// 把数组展开作为参数,可以替代 apply
// 求数组的最大值
let arr = [6, 99, 10, 1];
let max = Math.max(...arr);
Array.from()
把伪数组转换成数组
let fakeArr = {
0: 1,
1: 2,
2: 3,
length: 3
};
let arr = Array.from(fakeArr);
console.log(arr);
数组实例的 find() 和 findIndex()
find 找到数组中第一个满足条件的成员并返回该成员,如果找不到返回undefined。
findIndex 找到数组中第一个满足条件的成员并返回该成员的索引,如果找不到返回 -1。
// 找到数组中的第一个小于 0 的数字
let arr = [1, 3, -5, 6, -2];
let result = arr.find((x) => x < 0);
// 等同于
let result = arr.find(function (x) {
return x < 0;
});
// find 回调函数有 3 个参数
arr.find(function (item, index, ar) {
// item 当前的值
// index 当前的值对应的索引
// ar 原数组
});
findIndex 的使用和 find 类似
数组实例的 includes()
判断数组是否包含某个值,返回 true / false
模板字符串
模板字符串解决了字符串拼接不便的问题(内容太长需要换行,拼接多个变量)
模板字符串使用反引号 ` 括起来内容
let name = 'zs';
let age = 18;
// 拼接多个变量,在模板字符串中使用占位的方式,更易懂
let str = `我是${name},今年${age}`;
// 内容过多可以直接换行
let html = `
- itheima
`;
includes(), startsWith(), endsWith()
includes()
返回布尔值,表示是否找到了参数字符串startsWidth()
返回布尔值,表示参数字符串是否在原字符串的头部endsWith()
返回布尔值,表示参数字符串是否在原字符串的尾部。repeat()
repeat
方法返回一个新字符串,表示将原字符串重复n
次。
let html = '- itheima
';
html = html.repeat(10);
ES6 将全局方法parseInt()
和parseFloat()
,移植到Number
对象上面,行为完全保持不变。
Set 是 ES6 中新增的内置对象,类似于数组,但是成员的值都是唯一的,没有重复的值(可以实现数组去重)。
// Set 可以通过一个数组初始化
let set = new Set([1, 2, 1, 5, 1, 6]);
// 数组去重
let arr = [...set];
size
:属性,获取 set
中成员的个数,相当于数组中的 length
add(value)
:添加某个值,返回 Set 结构本身。delete(value)
:删除某个值,返回一个布尔值,表示删除是否成功。has(value)
:返回一个布尔值,表示该值是否为Set
的成员。clear()
:清除所有成员,没有返回值。export 导出:变量、函数、类
import 导入: 自定义导入名称;解构赋值
// 导出变量
export let abc=123;
export let info=456;
// 导出函数
export function foo(){
console.log('foo)
}
// 导出类
export class Cat{
constructor(name){
this.name=name
}
}
class Dog{
constructor(name){
this.name=name
}
}
let fn = function(){
console.log('fn')
}
export { Dog,fn }
//在模块中默认的导出只能有1个,默认导出在导入时可以自定义名称。例如kitty
export default calss {
constructor(msg){
this.msg=msg
}
}
// 导入
import Kitty,{abc, info, foo, Cat, Dog, fn} from 导出文件路径
foo()
let cat = new Cat('tom')
console.log(cat)
let dog = new Dog('gou')
console.log(dog)
let k = new Kitty();
因为 ES6 有浏览器兼容性问题,可以使用一些工具进行降级处理,例如:babel
降级处理 babel 的使用步骤
安装Node.js
命令行中安装 babel
配置文件 .babelrc
运行
安装 Node.js
官网
在命令行中,安装 babel
npm install @babel/core @babel/cli @babel/preset-env
配置文件 .babelrc
{
"presets": ["@babel/preset-env"]
}
在命令行中,运行
# 把转换的结果输出到指定的文件
babel index.js -o test.js
# 把转换的结果输出到指定的目录
babel src -d lib
参考:babel官网
ES6 扩展阅读
URL
)DNS 服务器
获取即将访问的网站 IP 地址
请求
端口
的服务器软件接收到这个请求,进行相应的处理响应
)安装和配置 Apache 服务器
应用软件架构一般分为两类:
Internet Protocol Address
[0-255].[0-255].[0-255].[0-255]
即为四个 0-255 的数字组成。在单个局域网下,结构非常简单,就是我们所连接的网络设备(网关)给我们分配了一个地址,在这个范围之内我们都可以通过这个地址找到我们的这个设备。
如果设备没有连接任何网络情况下,我们会有一个本地回环地址 127.0.0.1
计算机本身是一个封闭的环境,就像是一个大楼,如果需要有数据通信往来,必须有门,这个门在术语中就叫端口,每一个端口都有一个编号,每台计算机只有 65536 个端口(0-65535)。
一般我们把“占门”的过程叫做监听
端口号的作用,是标示计算机内的某个软件
可以通过在命令行中运行: netstat -an
命令监视本机端口使用情况
参考链接:
- https://baike.baidu.com/item/%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%AB%AF%E5%8F%A3
- https://baike.baidu.com/item/%E7%AB%AF%E5%8F%A3
http
默认的端口80
https
默认的端口是443
由于 IP 地址都是没有规律的一些数字组成的,很难被人记住,不利于广泛传播,所以就有人想出来要给 IP 起名字(别名)。
域名是需要花钱注册的
localhost
含义为本地主机,对应127.0.0.1 。这是一个保留域名,主要用于本地测试。
.com: 商业机构
.cn: 中国国家、地区域名 .hk,
.gov: 政府网站。
.org: 机构。
.edu: 教育网站。
.net: 网络服务商。
.mil: 军事。
通过宽带运营商提供的服务器解析一个域名背后对应的 IP,这个过程叫做 DNS 寻址,帮你完成 DNS 寻址过程的服务器叫做 DNS 服务器。
操作系统在发起对 DNS 服务器的查询请求之前,会优先检查本机的 hosts 文件。如果这个文件中包含了对当前需要解析的域名的配置,则不再发起对 DNS 服务器的请求,直接使用 hosts 文件中的配置。
文件所在路径:
C:\Windows\System32\drivers\etc\hosts
/etc/hosts
注意:
- 本机的 hosts 文件配置只能到影响本机的 DNS 寻址
- 只有以管理员权限运行的编辑器才有权利修改
hosts
文件
URL(Uniform Resource Locator),统一资源定位符,通俗点来说就是表示网络当中某一个网页的完整访问地址,它具有一定的格式:
例如:http://itcast.cn:80/schools/students?id=18&name=zs#photo
协议://主机地址[:端口]/路径?查询字符串#fragment
以下引自 Node.js 官网:
Node.js® is a JavaScript runtime built on Chrome’s V8 JavaScript engine.
- Node 打破了过去 JavaScript 只能在浏览器中运行的局面
- 前后端编程环境统一,大大降低了前后端语言切换的代价
知乎 - JavaScript能做什么,该做什么?
Atwood’s Law: any application that can be written in JavaScript, will eventually be written in JavaScript.
凡是能用 JavaScript 写出来的,最终都会用 JavaScript写出来。
没有 BOM、DOM
ECMAScript
全局成员
Global Objects
Node.js 为 JavaScript 提供的服务器级别的 API
导出模块 module.exports
导入模块 require
exports
和 module.exports
的区别
module.exports
module
对象exports
对象,模块最终导出的是此对象exports
exports
exports
指向了 module.exports
,exports = module.exports
在 Node 中对不模块的一个具体分类,一共就三种类别:
fs
文件操作模块、http
网络操作模块mime
、art-template
、marked
npm install
命令进行下载的,放到项目根目录下的 node_modules
目录。Node.js 中的模块化遵守 CommonJS 规范,CommonJS 是模块化的一种规范,Node.js 中实现了这种规范。
require('underscore')
underscore
目录,则找该目录下的 package.json
文件package.json
文件,则找该文件中的 main
属性,拿到 main 指定的入口模块node_modules
目录,规则同上npm
全称 Node Package Manager
(node包管理器),它的诞生是为了解决 Node 中第三方包共享的问题。npm
不需要单独安装。在安装Node的时候,会连带一起安装npm
。查看 npm
版本
npm --version
yarn --version
升级 npm
npm install npm --global
安装yarn
npm install -g yarn
初始化 package.json
npm init -y
yarn init
安装第三方包
npm install 包名
npm install 包名 包名
npm install 包名@版本号
yarn add 包名@version
从 package.json 安装依赖
npm install
yarn
安装指定包到依赖或者开发依赖
npm install --save [package]
yarn add [package]
npm install --save-dev [package]
yarn add [package] [--dev/-D]
安装包到全局
npm install --global [package]
yarn global add [package]
重新下载所有包
npm reubild
yarn install --force
卸载包
npm uninstall [package]
npm uninstall --save [package]
npm uninstall --save-dev [package]
yarn remove [package]
升级包
rm -rf node_modules && npm install
yarn upgrade
清除缓存
npm cache clean -force
yard cache clean
运行指令
npm run 指令
yarn run 指令
如果是start可以省略
本地安装
指的是将一个包下载到当前项目的node_modules
子目录,然后只有在项目目录之中,才能调用这个包。
全局安装
指的是将一个模块安装到系统目录中,各个项目都可以调用。一般来说,全局安装只适用于工具模块。
https://github.com/indexzero/http-server#readme
http://nodemon.io/
http://lesscss.org/
https://browsersync.io/
npm 存储包文件的服务器在国外,有时候会被墙,速度很慢,所以我们需要解决这个问题。
国内淘宝的开发团队把 npm 在国内做了一个备份,网址是:http://npm.taobao.org/。
# 下载包的时候切换源
npm install jquery --registry=https://registry.npm.taobao.org
# 全局设置
npm config set registry https://registry.npm.taobao.org
# 原始的路径
# https://registry.npmjs.org/
package.json
文件package.json
定义了这个项目所需要的各种模块,以及项目的配置信息npm install
命令根据这个配置文件,自动下载所需的模块,也就是配置项目所需的运行和开发环境。由三部分组成:请求行、请求头、请求体
浏览器 请求服务器上的 index.html,如果 index.html 连接了其它文件,浏览器再次发送请求,获取其它文件。
请求行
GET / HTTP/1.1
GET /index.html HTTP/1.1
请求头
Host: 127.0.0.1
浏览器可以解析的文件类型
Accept: text/html,application/xhtml+xml,application/xml;q=0.9
Cookie: Hm_lvt_743362d4b71e22775786fbc54283175c=1530695737
携带了客户端的信息(操作系统和浏览器)
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36
x-
POST 请求的时候会有另一个请求头
// 告诉服务器,post 过去的数据的格式长什么样子 name=zs&pwd=123456
Content-Type: application/x-www-form-urlencoded
Content-Length: 2952
参考链接
请求体
name=zs&pwd=123456
使用 chrome 监视请求
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g2VPCoeL-1588212489843)(/Users/wangjing/Documents/js/node/06-sql%E8%AF%AD%E6%B3%95/01-%E8%AE%B2%E4%B9%89/assets/1543976242956.png)]
响应报文由三部分组成:响应行、响应头、响应体
响应行
HTTP/1.1 404 Not Found
HTTP/1.1 200 OK
参考链接
响应头
由键值对组成
Content-Length: 51866
// 服务器告诉浏览器,发送给你的是什么类型的文件
Content-Type: text/html
Server: Apache/2.4.37 (Win64)
响应体
返回的主体内容,如果请求的是网页返回网页的内容,如果请求的是图片返回图片的内容
GET
POST
PUT
DELETE
……
参考链接
http://nodejs.cn/api/querystring.html
解析与格式化 URL 查询字符串,或者请求体中的数据
// name=zs&pwd=12345
let body = 'name=zs&pwd=12345';
const qs = require('querystring');
body = qs.parse(body);
//{
// name: 'zs',
// pwd: '12345'
//}
// 0. 加载 http 核心模块
const http = require('http')
// 1. 创建服务器,得到 Server 实例
const server = http.createServer()
// 2. 监听客户端的 request 请求事件,设置请求处理函数
server.on('request', (request, response) => {
// request.header
console.log('收到客户端的请求了')
})
// 3. 绑定端口号,启动服务器
// 真正需要通信的应用程序
// 如何从 a 计算机的 应用程序 通信到 b 计算机的 应用程序
// ip 地址用来定位具体的计算机
// port 端口号用来定位具体的应用程序
// 联网通信的应用程序必须占用一个端口号,同一时间同一个端口号只能被一个应用程序占用
// 开发测试的时候使用一些非默认端口,防止冲突
server.listen(3000, function () {
console.log('Server is running at port 3000.')
})
Node 服务器不同于 Apache,默认能力非常的简单,一切请求都需要自己来处理。
// 0. 加载 http 核心模块
const http = require('http')
// 1. 创建服务器,得到 Server 实例
const server = http.createServer()
// 2. 监听客户端的 request 请求事件,设置请求处理函数
// req 请求对象(获取客户端信息)
// res 响应对象(发送响应数据)
// end() 方法
server.on('request', (req, res) => {
// 发送响应数据
res.write('hello')
res.write(' hello')
// 数据写完之后,必须告诉客户端,我的数据发完了,你可以接收处理了
// 否则客户端还是会一直等待
// 结束响应,挂断电话
res.end()
})
// 3. 绑定端口号,启动服务器
// 真正需要通信的应用程序
// 如何从 a 计算机的 应用程序 通信到 b 计算机的 应用程序
// ip 地址用来定位具体的计算机
// port 端口号用来定位具体的应用程序
// 联网通信的应用程序必须占用一个端口号,同一时间同一个端口号只能被一个应用程序占用
// 开发测试的时候使用一些非默认端口,防止冲突
server.listen(3000, function () {
console.log('Server is running at port 3000.')
})
网站中的资源都是通过 url
地址来定位的,所以我就可以在请求处理函数获取客户端的请求地址,然后根据不同的请求地址处理不同的响应。
// 0. 加载 http 核心模块
const http = require('http')
// 1. 创建服务器,得到 Server 实例
const server = http.createServer()
// 2. 监听客户端的 request 请求事件,设置请求处理函数
// req 请求对象(获取客户端信息)
// res 响应对象(发送响应数据)
// end() 方法
// 任何请求都会触发 request 请求事件
// /a /b /c /dsanjdasjk
// req 请求对象中有一个属性:url 可以获取当前客户端的请求路径
server.on('request', (req, res) => {
// console.log(req.url)
// 127.0.0.1:3000/abc
// 一切请求路径都始终是以 / 开头
// / index page
// /login login page
// /about about me
// 其它的 404 Not Found.
// res.end('index page')
const url = req.url
// 通常情况下,都会把 / 当作首页
// 因为用户手动输入地址,不加任何路径,浏览器会自动补上 / 去请求
if (url === '/') {
console.log('首页')
res.end(`
首页
`)
} else if (url === '/login') {
console.log('登陆')
res.end('login page')
} else if (url === '/reg') {
console.log('注册')
res.end('reg page')
} else {
console.log('404 不认识')
res.end('404 Not Found.')
}
})
server.listen(3000, function () {
console.log('Server is running at port 3000.')
})
html 文件中的
响应头的Content-Type
// 设置响应头
response.setHeader('Content-Type', 'text/html; charset=utf-8');
建议每个响应都告诉客户端我给你发送的 Content-Type 内容类型是什么
/**
* http 结合 fs 发送文件内容
*/
const http = require('http')
const fs = require('fs')
const server = http.createServer()
server.on('request', (req, res) => {
const url = req.url
console.log(url)
if (url === '/') {
fs.readFile('./views/index.html', (err, data) => {
if (err) {
return res.end('404 Not Found.')
}
// 响应数据类型只能是:字符串 和 二进制数据
// TypeError: First argument must be a string or Buffer
// res.end(123)
res.setHeader('Content-Type', 'text/html; charset=utf-8')
res.end(data)
})
} else if (url === '/css/main.css') {
fs.readFile('./views/css/main.css', (err, data) => {
if (err) {
return res.end('404 Not Found.')
}
// 响应数据类型只能是:字符串 和 二进制数据
// TypeError: First argument must be a string or Buffer
// res.end(123)
res.setHeader('Content-Type', 'text/css; charset=utf-8')
res.end(data)
})
} else if (url === '/js/main.js') {
fs.readFile('./views/js/main.js', (err, data) => {
if (err) {
return res.end('404 Not Found.')
}
// 响应数据类型只能是:字符串 和 二进制数据
// TypeError: First argument must be a string or Buffer
// res.end(123)
res.setHeader('Content-Type', 'application/x-javascript; charset=utf-8')
res.end(data)
})
} else if (url === '/img/ab2.jpg') {
fs.readFile('./views/img/ab2.jpg', (err, data) => {
if (err) {
return res.end('404 Not Found.')
}
// 响应数据类型只能是:字符串 和 二进制数据
// TypeError: First argument must be a string or Buffer
// res.end(123)
// 只有文本类型需要加 charset 编码
// 图片不是文本,所以不用加编码
res.setHeader('Content-Type', 'image/jpeg')
res.end(data)
})
}
})
server.listen(3000, () => {
console.log('running...')
})
自己处理
使用第三方模块
https://github.com/broofa/node-mime
能够根据后缀名生成 Content-Type 的值
下载模块
# 创建package.json -- 项目文件夹不能有中文
npm init -y
npm install mime
使用模块
const mime = require('mime');
mime.getType('txt'); // ⇨ 'text/plain'
mime.getExtension('text/plain'); // ⇨ 'txt'
fs.readFile(‘相对路径’)
相对路径,是相对于工作目录 — node 程序执行的目录
建议 以后 使用fs.readFile 读取文件的时候,使用绝对路径
fs.readFile(path.join(__dirname, ‘xxx’))
我们已经基于 Node.js 开发了一个静态网站的 web 服务器。处理的过程找到你请求对应的路径 → 读取文件 → 将文件内容响应给客户端浏览器(文件原封不动的给你)。无法满足让网页内容动起来(随着数据动态变化)的需求。
动态网站的原理:不再将 HTML 固定写死,每次用户请求时,动态执行一段代码,临时生成一个用户想要的 HTML 页面。这种实现这种概念的技术有很多种:JSP、ASP.NET、PHP、Node 等等。
动态网站指的也就是每次请求时服务端动态生成 HTML 返回给用户的这种网站。
**目的:**了解服务端开发,以及某些其他对前端开发有帮助的东西。
存储数据-使用 JSON 格式
要存储留言信息的话,未来会使用专业的存储数据库
现在先使用简化的方式来处理 – JSON 格式的数据
JSON 格式跟对象类似,但是 JSON 是字符串形式的数据,例如:
描述对象,属性必须使用 双引号,值如果是字符串也要使用双引号
{ "name": "小红", age: 18 }
描述数组
[
{ "name": "小红", age: 18 },
{ "name": "张三", age: 19 }
]
JSON 格式的字符串和对象之间的转换
// JSON 对象
JSON.parse() // 把JSON格式的字符串转换成js对象
JSON.stringify() // 把js对象转换成JSON格式的字符串
发表留言使用 POST 请求
检查页面的表单,设置 method 和 action
判断如果是 GET 请求,返回页面
如果是 POST 请求,处理表单提交
if (request.method === 'POST') {
if (request.url === '/publish') {
// 处理 发表留言
}
}
获取 POST 过来的表单数据
表单提交数据的时候,想要提交到服务器的文本框(表单元素),都应该设置name属性
只有具有name属性的表单元素,才会提交给服务器(content=xxx)
request 读写的 data 和 end 事件
let body = '';
req.on('data', (chunk) => {
body += chunk;
});
req.on('end', () => {
console.log(body);
});
读取 JSON 对象,获取存储的留言数据,并添加留言
let lastMsg = msgs[msgs.length - 1];
let msg = {
id: lastMsg.id + 1,
img: lastMsg.img,
name: body.name,
content: body.content,
time: new Date()
};
msgs.push(msg);
fs.writeFile('xx.json', JSON.stringify(msgs), () => {
// 完毕
response.setHeader('Content-Type', 'text/html; charset=utf-8');
// response.end('添加完毕');
response.end('');
});
留言列表换成动态的数据列表
let list = '';
msgs.forEach((item) => {
list += `
-
${item.img}
" alt="" class="pic">
发表时间: ${item.time}
${item.name}: ${item.content}
上一步中,拼接字符串麻烦,而且 js 中有 html 代码
模板引擎可以大大的简化页面内容的拼接
node.js 服务端的模板
art-template
art-template 的使用
安装
初始化 package.json
npm init -y
下载 art-template
npm i art-template
导入 art-template
const template = require('art-template');
语法
基本使用
let html = template(绝对路径, 数据对象);
let html = template(path.join(__dirname, 'views/xx.html'), {
title: '这是数据'
});
输出数据
{{ title }}
条件输出
{{if value}}
<p>{{ value }}p>
{{/if}}
循环输出
{{each items}}
{{$index}} {{$value}}
{{/each}}
使用模板引擎改造留言板案例
参考文档:http://expressjs.com/en/starter/installing.html
# 创建并切换到 myapp 目录
mkdir myapp
cd myapp
# 初始化 package.json 文件
npm init -y
# 安装 express 到项目中
npm i express
参考文档:http://expressjs.com/en/starter/hello-world.html
// 0. 加载 Express
const express = require('express')
// 1. 调用 express() 得到一个 app
// 类似于 http.createServer()
const app = express()
// 2. 设置请求对应的处理函数
// 当客户端以 GET 方法请求 / 的时候就会调用第二个参数:请求处理函数
app.get('/', (req, res) => {
// send方法内部调用 response.end()
// 并且内部已经设置了 Content-Type和其它必要的响应头
res.send('hello world')
})
// 3. 监听端口号,启动 Web 服务
app.listen(3000, () => console.log('app listening on port 3000!'))
参考文档:http://expressjs.com/en/starter/basic-routing.html
app.METHOD(PATH, HANDLER)
其中:
app
是 express 实例METHOD
是一个 HTTP 请求方法PATH
是服务端路径(定位标识)HANDLER
是当路由匹配到时需要执行的处理函数下面是一些基本示例。
// 当你以 GET 方法请求 / 的时候,执行对应的处理函数
app.get('/', function (req, res) {
res.send('Hello World!')
})
// 当你以 POST 方法请求 / 的时候,指定对应的处理函数
app.post('/', function (req, res) {
res.send('Got a POST request')
})
路由的参考文档 routing guide.
参考文档:http://expressjs.com/en/starter/static-files.html
目录结构
.
├── node_modules npm安装的第三方包目录,使用 npm 装包会自动创建
├── public / statics页面需要使用的静态资源
│ ├── css
│ ├── js
│ ├── images
│ └── ...
├── views 所有页面(只存储 html 文件,模板)
│ ├── publish.html
│ └── index.html
├── app.js 服务端程序入口文件,执行该文件会启动我们的 Web 服务器
express 中提供了方便的处理静态资源的方式
// 开放 public 目录中的资源
// 不需要访问前缀
app.use(express.static('public'))
// http://127.0.0.1:3000/css/index.css
// http://127.0.0.1:3000/images/lj.jpg
// http://127.0.0.1:3000/images/timg.jpg
// 开放 files 目录资源,同上
app.use(express.static('files'))
// 限制访问前缀
app.use('/public', express.static('public'))
// http://127.0.0.1:3000/public/css/index.css
// 开放 public 目录资源,限制访问前缀
app.use('/static', express.static('public'))
// 开放 public 目录,限制访问前缀
// path.join(__dirname, 'public') 会得到一个绝对路径
app.use('/public', express.static(path.join(__dirname, 'public')))
注意: express.static()
使用相对路径的时候,相对于工作目录(执行 node 程序的目录),推荐此处使用绝对路径。
// 设置静态资源访问的路径
app.use('/public', express.static(path.join(__dirname, 'public')));
// 设置首页的路由
app.get('/', (request, response) => {
response.sendFile(path.join(__dirname, 'views/index.html'));
});
参考文档:
- GitHub - body-parser
body-parser
安装:
npm install body-parser
配置:
var express = require('express')
// 0. 引包
var bodyParser = require('body-parser')
var app = express()
// 配置 body-parser
// 只要加入这个配置,则在 req 请求对象上会多出来一个属性:body
// 也就是说你就可以直接通过 req.body 来获取表单 POST 请求体数据了
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json());
注意: body-parser的配置要放在,设置路由之前
使用:
// 可以通过 req.body 来获取表单 POST 请求体数据
app.post('/publish', (req, res) => {
res.send(req.body);
});
获取 post 过来的数据 - 配置body-parser
读取 db.json,把内容转换成js数组对象
构造留言对象,把对象添加到数组中
把留言数组转换成json字符串,写入db.json
提示并跳转
// 配置body-parser,解析post过来的数据,放到request.body中
app.use(bodyParser.urlencoded({ extended: false }));
app.post('/publish', (request, response) => {
// 1. 获取 post 过来的数据
// console.log(request.body);
// 2. 读取 db.json,把内容转换成js数组对象
fs.readFile(path.join(__dirname, 'db.json'), 'utf-8', (err, data) => {
if (err) throw err;
let msgs = JSON.parse(data);
// 3. 构造留言对象,把对象添加到数组中
let lastMsg = msgs[msgs.length - 1];
let msg = {
id: lastMsg.id + 1,
name: request.body.name,
content: request.body.content,
time: '2019-1-1 10:10:10',
img: lastMsg.img
};
msgs.push(msg);
// 4. 把留言数组转换成字符串,写入db.json
let str = JSON.stringify(msgs);
fs.writeFile(path.join(__dirname, 'db.json'), str, (err) => {
if (err) throw err;
// 浏览器弹出提示,并跳转
response.send('');
});
});
});
安装 art-template,导入模块
配置模板
{{ each msgs }}
<li>
<img src="{{ $value.img }}" alt="" class="pic">
<div class="list_con">
<div class="time">
<strong>发表时间: <i>{{ $value.time }}i>strong>
<img src="public/images/lj.jpg" alt="">
div>
<p><b>{{ $value.name }}:b> {{ $value.content }}p>
div>
li>
{{ /each }}
读取 db.json,把内容转换成js的数组对象
使用art-template渲染模板
把渲染的网页,发送给浏览器
app.get('/', (request, response) => {
// 读取 db.json,把内容转换成js的数组对象
fs.readFile(path.join(__dirname, 'db.json'), 'utf-8', (err, data) => {
if (err) throw err;
// 把 json字符串转换成数组对象
let msgs = JSON.parse(data);
// 使用art-template渲染模板
let html = template(path.join(__dirname, 'views/index.html'), {
msgs
});
// 给浏览器发送响应
response.send(html);
});
});
http://expressjs.com/en/guide/using-template-engines.html)
我们可以使用模板引擎处理服务端渲染,但是 Express 为了保持其极简灵活的特性并没有提供类似的功能。
同样的,Express 也是开放的,它支持开发人员根据自己的需求将模板引擎和 Express 结合实现服务端渲染的能力。
参考文档:
- art-template 官方文档
- express-art-template 官方文档
这里我们以 art-template 模板引擎为例演示如何和 Express 结合使用。
安装:
npm install art-template express-art-template
配置:
const expressTPL = require('express-art-template');
// 默认模板都放在views文件夹中
// 设置html文件为模板
app.set('view engine', 'html');
// 设置模板交给谁去处理
app.engine('html', expressTPL);
使用示例:
app.get('/', function (req, res) {
// render 方法默认会去项目的 views 目录中查找 index.html 文件
// render 方法的本质就是将读取文件和模板引擎渲染这件事儿给封装起来了
// 默认模板都是html文件,这里的.html可以省略
res.render('index', {
title: 'hello world'
})
})
如果希望修改默认的 views
视图渲染存储目录,可以:
// 第一个参数 views 是一个特定标识,不能乱写
// 第二个参数给定一个目录路径作为默认的视图查找目录
app.set('views', 目录路径)
改造留言板案例
下载 art-template express-art-template
配置 express 模板引擎
const expressTPL = require('express-art-template');
// 设置模板的后缀
app.set('view engine', 'html');
// 设置模板交给谁去处理
app.engine('html', expressTPL);
使用 express 模板引擎
response.render('index', {
msgs
});
JavaScript 模板引擎有很多,并且他们的功能都大抵相同,但是不同的模板引擎也各有自己的特色。
大部分 JavaScript 模板引擎都可以在 Node 中使用,下面是一些常见的模板引擎。
封装一个独立的数学模块,把不同的功能放到独立的模块(js 文件)中,通过一个出口文件统一导出所有模块。
math
文件夹modules.exports
导出一个计算的函数index.js
,导入所有模块,并导出相关成员
index.js
如何更改默认的导出的模块名称?此时就要使用 package.json
创建 package.json
npm init
npm init -y
main
main 字段指定了加载的入口文件,require('moduleName')
就会加载这个文件。这个字段的默认值是模块根目录下面的index.js
。
dependencies 依赖(复数)
"dependencies": {
"art-template": "^4.13.2",
"body-parser": "^1.18.3",
"express": "^4.16.4",
"express-art-template": "^1.0.1"
}
dependencies
字段指定了项目运行所依赖的模块npm install
可以安装所有的依赖1.2.2
,遵循“大版本.次要版本.小版本”的格式规定,安装时只安装指定版本。~1.2.2
,表示安装1.2.x的最新版本(不低于1.2.2),但是不安装1.3.x,也就是说安装时不改变大版本号和次要版本号。scripts
scripts
指定了运行脚本命令的 npm 命令行缩写,比如start指定了运行npm run start
时,所要执行的命令。
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node app.js",
"t": "dir c:\\"
}
运行 scripts
npm run t
npm run start
# 只有 start 可以简化调用
npm start
node_modules
中。使用第三方包的时候直接 require('第三方包的名字')
。require
的加载顺序
module.paths
中的路径一级一级往上查找require()
加载完毕,会把 模块/包 缓存起来,再次 require()
的时候直接从缓存加载require
优先加载缓存中的模块require('./main')
省略扩展名的情况main.js
,如果没有再加载 main.json
,如果没有再加载 main.node
(c/c++编写的模块)require('moment')
moment
目录,则找该目录下的 package.json
文件package.json
文件,则找该文件中的 main
属性,拿到 main 指定的模块node_modules
目录,规则同上[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JMxsMrF5-1588212489847)(./assets/nodejs-require.jpg)]
npm
全称 Node Package Manager
(node 包管理器),它的诞生是为了解决 Node 中第三方包共享的问题。npm
不需要单独安装。在安装Node的时候,会连带一起安装npm
。npm 存储包文件的服务器在国外,速度很慢,所以我们需要解决这个问题。
国内淘宝的开发团队把 npm 在国内做了一个备份,网址是:http://npm.taobao.org/。
# 查看当前的源
npm config ls
# registry = "https://registry.npm.taobao.org/"
# 下载包的时候切换源
npm install express --registry=https://registry.npm.taobao.org
# 全局设置
npm config set registry https://registry.npm.taobao.org
# 原始的路径
# https://registry.npmjs.org/
查看 npm
版本
npm --version
npm -v
升级 npm
npm install npm --global
npm install npm -g
初始化 package.json
npm init -y
安装第三方包
npm install 包名
npm install 包名 包名
npm install 包名@版本号
# 简写
npm i 包名
# 卸载包
npm uninstall 包名
从缓存目录安装包
# 查看缓存目录
npm config get cache
# 从缓存目录下载包
# --cache-min 后面跟的是时间,单位是分钟,超过这个时间才去服务器下载
npm install --cache-min 9999999 <package-name>
全局安装和本地安装
本地安装
指的是将一个包下载到当前项目的node_modules
子目录,然后只有在项目目录之中,才能调用这个包。
全局安装
指的是将一个模块安装到系统目录中,各个项目都可以调用。一般来说,全局安装只适用于工具模块。
# 查看全局安装目录
npm config ls
npm root -g
# prefix 是全局安装目录
# prefix = "C:\\Users\\你的用户名\\AppData\\Roaming\\npm"
演示全局安装的工具
npm install 包名 --global
npm install 包名 -g
https://github.com/indexzero/http-server#readme
http://nodemon.io/
http://lesscss.org/
browser-sync
npm install -g browser-sync
https://browsersync.io/
未来我们程序中的数据为了方便管理都通过数据库来存储。
作为前端开发人员,对数据库做一定了解即可。
MySQL 安装与配置
下载地址:
参考链接:
要在程序中对数据库进行操作需要 SQL 语句
什么是 SQL
执行 sql 语句
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T8ixndmo-1588212489848)(/Users/wangjing/Documents/js/node/06-sql%E8%AF%AD%E6%B3%95/01-%E8%AE%B2%E4%B9%89/assets/1544252556120.png)]
数据库和表的操作
数据库
创建
create database test;
删除
-- 删除数据库
-- 如果执行多条sql语句要带分号
drop database test;
数据表
建表
-- 切换数据库
use test;
-- 在 test 数据库建表
create table msg (
id int auto_increment primary key,
name varchar(20) not null,
content text null,
time datetime,
img varchar(100)
)
-- auto_increment 自动编号
-- primary key 主键,唯一标示一条数据
删除表
drop table msg;
增删改查
插入数据
INSERT INTO users (uname, upwd, uqq, uage) values('zs','123', '12345', 18)
-- 如果是所有列,可以省略列名称,不推荐
INSERT INTO users values(2,'zs','123', '12345', 18)
修改数据
UPDATE users SET uname='zsxxx', uqq='111' WHERE uid=1
-- 如果不写条件,所有数据都被更新,建议修改的时候一定要加条件
UPDATE users SET uname='zsxxx', uqq='111'
删除数据
DELETE FROM users WHERE uid = 1
-- 不带条件删除表中所有数据,禁止使用
DELETE FROM users
查询数据
SELECT * FROM users
SELECT 列1,列2 FROM users
导出 SQL 脚本
在数据库名字上点击右键
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4Ng7EilP-1588212489850)(/Users/wangjing/Documents/js/node/06-sql%E8%AF%AD%E6%B3%95/01-%E8%AE%B2%E4%B9%89/assets/1544363426601.png)]
导入 SQL 脚本
在数据库名字上点击右键,点击运行 SQL 文件,选择 SQL 文件的位置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TKloHF21-1588212489851)(/Users/wangjing/Documents/js/node/06-sql%E8%AF%AD%E6%B3%95/01-%E8%AE%B2%E4%B9%89/assets/1544363543195.png)]
条件查询
SELECT * FROM users WHERE uname='zs' AND uname='000000'
SELECT * FROM users WHERE uname='zs' OR uname='ls'
下面的运算符可在 WHERE 子句中使用:
操作符 | 描述 |
---|---|
= | 等于 |
<> | 不等于 |
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
BETWEEN…AND | 在某个范围内 |
LIKE | 搜索某种模式 |
模糊查询
SELECT * FROM users WHERE uname like '%s%'
in 语句
SELECT * FROM users WHERE uname in ('zs','ls')
排序
order by 要写在 sql 语句的最后
-- asc 默认是升序 desc 降序
SELECT * FROM users ORDER BY 字段(列) DESC
-- 先根据条件获取数据,再对数据排序
SELECT * FROM users WHERE uage > 18 ORDER by 字段(列) desc
限制查询条数
-- 取前3条数据
SELECT * FROM users LIMIT 3
-- 降序后去3条数据
SELECT * FROM users ORDER BY id DESC LIMIT 3
-- 跳过3条,取2条
SELECT * FROM users ORDER BY id DESC LIMIT 3,2
获取总条数
SELECT COUNT(*) FROM users
-- 修改返回数据的列名 as
SELECT count(*) as sum FROM users
表连接
SELECT column_name(s)
FROM table_name1
INNER JOIN table_name2
ON table_name1.column_name=table_name2.column_name
where 条件
使用 mysql 第三方包
https://github.com/mysqljs/mysql
npm install mysql
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'me',
password : 'secret',
database : 'my_db'
});
connection.connect();
connection.query('SELECT 1 + 1 AS solution', function (error, results, fields) {
if (error) throw error;
console.log('The solution is: ', results[0].solution);
});
connection.end();
基本查询:
connection.query('SELECT * FROM `books` WHERE `author` = "David"', function (error, results, fields) {
// error will be an Error if one occurred during the query
// results will contain the results of the query
// fields will contain information about the returned results fields (if any)
});
条件查询:
connection.query('SELECT * FROM `books` WHERE `author` = ?', ['David'], function (error, results, fields) {
// error will be an Error if one occurred during the query
// results will contain the results of the query
// fields will contain information about the returned results fields (if any)
});
var post = {id: 1, title: 'Hello MySQL'};
var query = connection.query('INSERT INTO posts SET ?', post, function (error, results, fields) {
if (error) throw error;
// Neat!
});
console.log(query.sql); // INSERT INTO posts SET `id` = 1, `title` = 'Hello MySQL'
connection.query('DELETE FROM posts WHERE title = "wrong"', function (error, results, fields) {
if (error) throw error;
console.log('deleted ' + results.affectedRows + ' rows');
})
connection.query('UPDATE users SET foo = ?, bar = ?, baz = ? WHERE id = ?', ['a', 'b', 'c', userId], function (error, results, fields) {
if (error) throw error;
// ...
})
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7z0Jogpl-1588212489852)(…/…/…/…/…/…/%E5%B7%A5%E4%BD%9C/%E6%9C%8D%E5%8A%A1%E7%AB%AF%E7%BC%96%E7%A8%8BNode.js/%E8%B5%84%E6%96%99/nodejs%E8%AE%B2%E4%B9%89/assets/connection-pool.png)]
var mysql = require('mysql');
var pool = mysql.createPool({
host : 'example.org',
user : 'bob',
password : 'secret',
database : 'my_db',
connectionLimit: 10 // 默认是 10 个
});
pool.getConnection(function(err, connection) {
// Use the connection
connection.query('SELECT something FROM sometable', function (error, results, fields) {
// 释放回连接池
connection.release();
// 处理错误
if (error) throw error;
// ...
});
});
const mysql = require('mysql')
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: '123456',
database: 'test',
connectionLimit: 10 // 默认是 10 个
})
exports.query = (...args) => {
// 从数组中弹出最后一个元素 callback 回调函数
const callback = args.pop()
pool.getConnection((err, connection) => {
if (err) {
return callback(err)
}
connection.query(...args, function (...results) { // ...results => [err, results, fields]
// 释放回连接池
connection.release()
// 把 ...results => [err, results, fields] 展开调用 callback 继续往外抛
callback(...results)
})
})
}
Vue.js 是目前最火的一个前端框架,React是最流行的一个前端框架(React除了开发网站,还可以开发手机App, Vue语法也是可以用于进行手机App开发的,需要借助于Weex)
Vue.js 是前端的主流框架之一,和Angular.js、React.js 一起,并成为前端三大主流框架!
Vue.js 是一套构建用户界面的框架,只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合。(Vue有配套的第三方类库,可以整合起来做大型项目的开发)
前端的主要工作?主要负责MVC中的V这一层;主要工作就是和界面打交道,来制作前端页面效果;
提高开发效率的发展历程:原生JS -> Jquery之类的类库 -> 前端模板引擎 -> Angular.js / Vue.js(能够帮助我们减少不必要的DOM操作;提高渲染效率;双向数据绑定的概念【通过框架提供的指令,我们前端程序员只需要关心数据的业务逻辑,不再关心DOM是如何渲染的了】)
在Vue中,一个核心的概念,就是让用户不再操作DOM元素,解放了用户的双手,让程序员可以更多的时间去关注业务逻辑;
增强自己就业时候的竞争力
MVC 主要是后端的分层开发思想;把 一个完整的后端项目,分成了三个部分:
MVVM是前端页面的分层开发思想,主要关注于 视图层 分离,也就是说:MVVM把前端的视图层,分为了 三部分 Model, View, ViewModel
为什么有了MVC还要有MVVM
{{info}}
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
info: '猥琐发育,别浪~!',
intervalId: null
},
methods: {
go() {
// 如果当前有定时器在运行,则直接return
if (this.intervalId != null) {
return;
}
// 开始定时器
this.intervalId = setInterval(() => {
this.info = this.info.substring(1) + this.info.substring(0, 1);
}, 500);
},
stop() {
clearInterval(this.intervalId);
}
}
});
.stop 阻止冒泡
.prevent 阻止默认事件
.capture 添加事件侦听器时使用事件捕获模式
.self 只当事件在该元素本身(比如不是子元素)触发时触发回调
.once 事件只触发一次
限制指定的键被触发执行,按键修饰符都是配合输入框使用的
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
n1: 0,
n2: 0,
result: 0,
opt: '0'
},
methods: {
getResult() {
switch (this.opt) {
case '0':
this.result = parseInt(this.n1) + parseInt(this.n2);
break;
case '1':
this.result = parseInt(this.n1) - parseInt(this.n2);
break;
case '2':
this.result = parseInt(this.n1) * parseInt(this.n2);
break;
case '3':
this.result = parseInt(this.n1) / parseInt(this.n2);
break;
}
}
}
});
这是一个邪恶的H1
这是一个邪恶的H1
这是一个邪恶的H1
这是一个邪恶的H1
:style
的形式,书写样式对象这是一个善良的H1
data
中,并直接引用到 :style
中data: {
h1StyleObj: { color: 'red', 'font-size': '40px', 'font-weight': '200' }
}
这是一个善良的H1
:style
中通过数组,引用多个 data
上的样式对象data: {
h1StyleObj: { color: 'red', 'font-size': '40px', 'font-weight': '200' },
h1StyleObj2: { fontStyle: 'italic' }
}
这是一个善良的H1
filterBy - 指令
{{item.id}}
{{item.name}}
{{item.ctime}}
删除
searchName
属性:
输入筛选名称:
v-for
指令循环每一行数据的时候,不再直接 item in list
,而是 in
一个 过滤的methods 方法,同时,把过滤条件searchName
传递进去:
{{item.id}}
{{item.name}}
{{item.ctime}}
删除
search
过滤方法中,使用 数组的 filter
方法进行过滤:
search(name) {
return this.list.filter(x => {
return x.name.indexOf(name) != -1;
});
}
vue-devtools
的安装步骤和使用Vue.js devtools - 安装方式 - 推荐
概念:Vue.js 允许你自定义过滤器,可被用作一些常见的文本格式化。过滤器可以用在两个地方:mustache 插值和 v-bind 表达式。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符指示;
{{item.ctime | dataFormat('yyyy-mm-dd')}}
filters
定义方式:
filters: { //私有局部过滤器,只能在当前 VM 对象所控制的 View 区域进行使用
dataFormat(input, pattern = "") { // 在参数列表中 通过 pattern="" 来指定形参默认值,防止报错
var dt = new Date(input);
// 获取年月日
var y = dt.getFullYear();
var m = (dt.getMonth() + 1).toString().padStart(2, '0');
var d = dt.getDate().toString().padStart(2, '0');
// 如果 传递进来的字符串类型,转为小写之后,等于 yyyy-mm-dd,那么就返回 年-月-日
// 否则,就返回 年-月-日 时:分:秒
if (pattern.toLowerCase() === 'yyyy-mm-dd') {
return `${y}-${m}-${d}`;
} else {
// 获取时分秒
var hh = dt.getHours().toString().padStart(2, '0');
var mm = dt.getMinutes().toString().padStart(2, '0');
var ss = dt.getSeconds().toString().padStart(2, '0');
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
}
}
}
使用ES6中的字符串新方法 String.prototype.padStart(maxLength, fillString=’’) 或 String.prototype.padEnd(maxLength, fillString=’’)来填充字符串;
// 定义一个全局过滤器
Vue.filter('dataFormat', function (input, pattern = '') {
var dt = new Date(input);
// 获取年月日
var y = dt.getFullYear();
var m = (dt.getMonth() + 1).toString().padStart(2, '0');
var d = dt.getDate().toString().padStart(2, '0');
// 如果 传递进来的字符串类型,转为小写之后,等于 yyyy-mm-dd,那么就返回 年-月-日
// 否则,就返回 年-月-日 时:分:秒
if (pattern.toLowerCase() === 'yyyy-mm-dd') {
return `${y}-${m}-${d}`;
} else {
// 获取时分秒
var hh = dt.getHours().toString().padStart(2, '0');
var mm = dt.getMinutes().toString().padStart(2, '0');
var ss = dt.getSeconds().toString().padStart(2, '0');
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
}
});
注意:当有局部和全局两个名称相同的过滤器时候,会以就近原则进行调用,即:局部过滤器优先于全局过滤器被调用!
Vue.directive('on').keyCodes.f2 = 113;
Vue.config.keyCodes.名称 = 按键值
来自定义案件修饰符的别名:
Vue.config.keyCodes.f2 = 113;
// 自定义全局指令 v-focus,为绑定的元素自动获取焦点:
Vue.directive('focus', {
inserted: function (el) { // inserted 表示被绑定元素插入父节点时调用
el.focus();
}
});
// 自定义局部指令 v-color 和 v-font-weight,为绑定的元素设置指定的字体颜色 和 字体粗细:
directives: {
color: { // 为元素设置指定的字体颜色
bind(el, binding) {
el.style.color = binding.value;
}
},
'font-weight': function (el, binding2) { // 自定义指令的简写形式,等同于定义了 bind 和 update 两个钩子函数
el.style.fontWeight = binding2.value;
}
}
Vue.elementDirective('red-color', {
bind: function () {
this.el.style.color = 'red';
}
});
使用方式:
1232
filterBy - 指令
{{item.id}}
{{item.name}}
{{item.ctime}}
删除
searchName
属性:
输入筛选名称:
v-for
指令循环每一行数据的时候,不再直接 item in list
,而是 in
一个 过滤的methods 方法,同时,把过滤条件searchName
传递进去:
{{item.id}}
{{item.name}}
{{item.ctime}}
删除
search
过滤方法中,使用 数组的 filter
方法进行过滤:
search(name) {
return this.list.filter(x => {
return x.name.indexOf(name) != -1;
});
}
vue-devtools
的安装步骤和使用Vue.js devtools - 安装方式 - 推荐
概念:Vue.js 允许你自定义过滤器,可被用作一些常见的文本格式化。过滤器可以用在两个地方:mustache 插值和 v-bind 表达式。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符指示;
{{item.ctime | dataFormat('yyyy-mm-dd')}}
filters
定义方式:
filters: { // 私有局部过滤器,只能在 当前 VM 对象所控制的 View 区域进行使用
dataFormat(input, pattern = "") { // 在参数列表中 通过 pattern="" 来指定形参默认值,防止报错
var dt = new Date(input);
// 获取年月日
var y = dt.getFullYear();
var m = (dt.getMonth() + 1).toString().padStart(2, '0');
var d = dt.getDate().toString().padStart(2, '0');
// 如果 传递进来的字符串类型,转为小写之后,等于 yyyy-mm-dd,那么就返回 年-月-日
// 否则,就返回 年-月-日 时:分:秒
if (pattern.toLowerCase() === 'yyyy-mm-dd') {
return `${y}-${m}-${d}`;
} else {
// 获取时分秒
var hh = dt.getHours().toString().padStart(2, '0');
var mm = dt.getMinutes().toString().padStart(2, '0');
var ss = dt.getSeconds().toString().padStart(2, '0');
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
}
}
}
使用ES6中的字符串新方法 String.prototype.padStart(maxLength, fillString=’’) 或 String.prototype.padEnd(maxLength, fillString=’’)来填充字符串;
// 定义一个全局过滤器
Vue.filter('dataFormat', function (input, pattern = '') {
var dt = new Date(input);
// 获取年月日
var y = dt.getFullYear();
var m = (dt.getMonth() + 1).toString().padStart(2, '0');
var d = dt.getDate().toString().padStart(2, '0');
// 如果 传递进来的字符串类型,转为小写之后,等于 yyyy-mm-dd,那么就返回 年-月-日
// 否则,就返回 年-月-日 时:分:秒
if (pattern.toLowerCase() === 'yyyy-mm-dd') {
return `${y}-${m}-${d}`;
} else {
// 获取时分秒
var hh = dt.getHours().toString().padStart(2, '0');
var mm = dt.getMinutes().toString().padStart(2, '0');
var ss = dt.getSeconds().toString().padStart(2, '0');
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
}
});
注意:当有局部和全局两个名称相同的过滤器时候,会以就近原则进行调用,即:局部过滤器优先于全局过滤器被调用!
Vue.directive('on').keyCodes.f2 = 113;
Vue.config.keyCodes.名称 = 按键值
来自定义案件修饰符的别名:
Vue.config.keyCodes.f2 = 113;
// 自定义全局指令 v-focus,为绑定的元素自动获取焦点:
Vue.directive('focus', {
inserted: function (el) { // inserted 表示被绑定元素插入父节点时调用
el.focus();
}
});
// 自定义局部指令 v-color 和 v-font-weight,为绑定的元素设置指定的字体颜色 和 字体粗细:
directives: {
color: { // 为元素设置指定的字体颜色
bind(el, binding) {
el.style.color = binding.value;
}
},
'font-weight': function (el, binding2) { // 自定义指令的简写形式,等同于定义了 bind 和 update 两个钩子函数
el.style.fontWeight = binding2.value;
}
}
Vue.elementDirective('red-color', {
bind: function () {
this.el.style.color = 'red';
}
});
使用方式:
1232
除了 vue-resource 之外,还可以使用 axios
的第三方包实现实现数据的请求
const http = require('http');
// 导入解析 URL 地址的核心模块
const urlModule = require('url');
const server = http.createServer();
// 监听 服务器的 request 请求事件,处理每个请求
server.on('request', (req, res) => {
const url = req.url;
// 解析客户端请求的URL地址
var info = urlModule.parse(url, true);
// 如果请求的 URL 地址是 /getjsonp ,则表示要获取JSONP类型的数据
if (info.pathname === '/getjsonp') {
// 获取客户端指定的回调函数的名称
var cbName = info.query.callback;
// 手动拼接要返回给客户端的数据对象
var data = {
name: 'zs',
age: 22,
gender: '男',
hobby: ['吃饭', '睡觉', '运动']
}
// 拼接出一个方法的调用,在调用这个方法的时候,把要发送给客户端的数据,序列化为字符串,作为参数传递给这个调用的方法:
var result = `${cbName}(${JSON.stringify(data)})`;
// 将拼接好的方法的调用,返回给客户端去解析执行
res.end(result);
} else {
res.end('404');
}
});
server.listen(3000, () => {
console.log('server running at http://127.0.0.1:3000');
});
script
标签,引入 vue-resource
的脚本文件;Vue
的脚本文件,再引用 vue-resource
的脚本文件;getInfo() { // get 方式获取数据
this.$http.get('http://127.0.0.1:8899/api/getlunbo').then(res => {
console.log(res.body);
})
}
postInfo() {
var url = 'http://127.0.0.1:8899/api/post';
// post 方法接收三个参数:
// 参数1: 要请求的URL地址
// 参数2: 要发送的数据对象
// 参数3: 指定post提交的编码类型为 application/x-www-form-urlencoded
this.$http.post(url, { name: 'zs' }, { emulateJSON: true }).then(res => {
console.log(res.body);
});
}
jsonpInfo() { // JSONP形式从服务器获取数据
var url = 'http://127.0.0.1:8899/api/jsonp';
this.$http.jsonp(url).then(res => {
console.log(res.body);
});
}
PHPStudy
;Navicat
这个数据库可视化工具,并激活;Navicat
工具,新建空白数据库,名为 dtcmsdb4
;右键
-> 运行SQL文件
,选择并执行 dtcmsdb4.sql
这个数据库脚本文件;如果执行不报错,则数据库导入完成;vuecms3_nodejsapi
内部,执行 npm i
安装所有的依赖项;nodemon
, 没有安装,则运行 npm i nodemon -g
进行全局安装,安装完毕后,进入到 vuecms3_nodejsapi
目录 -> src
目录 -> 双击运行 start.bat
app.js
中第 14行
中数据库连接配置字符串是否正确;PHPStudy 中默认的 用户名是root,默认的密码也是root为什么要有动画:动画能够提高用户的体验,帮助用户更好的理解页面中的功能;
动画哦
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
isshow: false
},
methods: {
myAnimate() {
this.isshow = !this.isshow;
}
}
});
/* 定义进入和离开时候的过渡状态 */
.fade-enter-active,
.fade-leave-active {
transition: all 0.2s ease;
position: absolute;
}
/* 定义进入过渡的开始状态 和 离开过渡的结束状态 */
.fade-enter,
.fade-leave-to {
opacity: 0;
transform: translateX(100px);
}
动画哦
OK
methods: {
beforeEnter(el) { // 动画进入之前的回调
el.style.transform = 'translateX(500px)';
},
enter(el, done) { // 动画进入完成时候的回调
el.offsetWidth;
el.style.transform = 'translateX(0px)';
done();
},
afterEnter(el) { // 动画进入完成之后的回调
this.isshow = !this.isshow;
}
}
.show{
transition: all 0.4s ease;
}
{{item}}
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
txt: '',
list: [1, 2, 3, 4]
},
methods: {
add() {
this.list.push(this.txt);
this.txt = '';
}
}
});
组件还有一个特殊之处。不仅可以进入和离开动画,还可以改变定位。要使用这个新功能只需了解新增的 v-move
特性,它会在元素的改变定位的过程中应用。
v-move
和 v-leave-active
结合使用,能够让列表的过渡更加平缓柔和:.v-move{
transition: all 0.8s ease;
}
.v-leave-active{
position: absolute;
}
const store = new vuex.store({
// state 通过 action 屌用 mutation,mutation 操作 state(devtool只监视mutation)
state:{a:5,b:12}, //初始状态 json
actions:{ //对mutation的封装
addA(context,n){ //context就是当前store对象 这个add随意定方法名,就是dispath来调用的方法名
context.commit('addA',n) //commit就是调用mutation里的方法(‘哪个方法’,传参数)
},
addB(context,n){ //context就是当前store对象 这个add随意定方法名,就是dispath来调用的方法名
context.commit('addB',n) //commit就是调用mutation里的方法(‘哪个方法’,传参数)
}
// 简写add({commit},n){commit('add',n)}
},
mutations:{ //操作state的
addA(state,n){ //state就是当前store的state
state.a+=n
},
addB(state,n){ //state就是当前store的state
state.b+=n
}
},
moudles:{
//对state做模块区分,加了这个读取state是一个json: {'device':{'a':'5','b':'12'},'user':{'a':'5','b':'12'}}
device, //设备相关js
user //用户相关js
},
getters:{ // 相当于computed ,当其中一个值变化,自动变化
count(state){
return state.a+state.b
}
}
})
// vuex 辅助工具
mapState //state 映射到 computed
mapActions //actions 映射到 methods
mapGetters //getters 映射到 computed
// vue组件修改
this.$store.dispatch('addA',5)
this.$store.getters.count
//getter还可以配合computed来用
//两个好处
//1.使用方便 {{count}} 相当于上面的使用
//computed可读可写
computed:{
count:{
get(){
return this.$store.getters.count;
},
set(value){
this.$store.dispatch('addA',value-5)
this.$store.dispatch('addB',5)
}
}
}
// 使用vuex辅助工具
import {mapState,mapAction,mapGetters} from 'vuex'
method:{
...maoActions(['addA','addB'])
},
computed:{
...mapState(['a','b']),
...maoGetters(['count'])
}
就是利用div自定义属性携带图片路径,然后在需要显示图片时通过js把路径给到img
通常用在加载首页和轮播图时有很多图片的情况
//服务器
//客户端
<script type="text/javascript" src="http://127.0.0.1:3000/data?callback=回调函数名"></script>
初始化一个Git仓库:git init [新建一个目录初始化]
添加文件到Git仓库:
添加到暂存区:git add file
提交到本地版本库:git commit -m
工作区的状态:git status
查看修改过的内容:git diff
回退到上几个版本:git reset --hard HEAD^ 【如果多个用HEAD~10】
查看提交历史: git log
回退到指定历史版本:git reset --hard commit_id
查看命令历史:git reflog
查看工作区和版本库里面最新版本的区别:git diff HEAD --
把暂存区的修改回退到工作区:git reset HEAD
用版本库里的版本替换工作区的版本:git checkout -- file 【工作区是修改还是删除一键还原】
删除版本库文件:git rm file
关联一个远程仓库:git remote add origin 地址 【origin相当于给地址定义一个名字】
本地库的内容推送到远程:git push -u origin master 【-u第一次推送加上可以把本地分支和远程分支关联起来】
克隆一个仓库:git clone 地址
查看分支:git branch
创建分支:git branch
切换分支:git checkout
创建+切换分支:git checkout -b
合并某分支到当前分支:git merge
删除分支:git branch -d
看到分支合并图:git log --graph
把当前工作现场“储藏”起来:git stash
普通方式合并并提交:git merge --no-ff -m "merged bug fix 101" issue-101 【有合并历史记录】
查看存储了哪些工作区文件:git stash list
把存储区内容恢复到工作区:
1)git stash apply 【恢复后,stash内容并不删除,你需要用git stash drop来删除;】
2)git stash pop 恢复的同时把stash内容也删了
3)git stash apply stash@{0} 恢复指定的stash
强行删除一个没有被合并过的分支:git branch -D
"no-alert": 0,//禁止使用alert confirm prompt
"no-array-constructor": 2,//禁止使用数组构造器
"no-bitwise": 0,//禁止使用按位运算符
"no-caller": 1,//禁止使用arguments.caller或arguments.callee
"no-catch-shadow": 2,//禁止catch子句参数与外部作用域变量同名
"no-class-assign": 2,//禁止给类赋值
"no-cond-assign": 2,//禁止在条件表达式中使用赋值语句
"no-console": 2,//禁止使用console
"no-const-assign": 2,//禁止修改const声明的变量
"no-constant-condition": 2,//禁止在条件中使用常量表达式 if(true) if(1)
"no-continue": 0,//禁止使用continue
"no-control-regex": 2,//禁止在正则表达式中使用控制字符
"no-debugger": 2,//禁止使用debugger
"no-delete-var": 2,//不能对var声明的变量使用delete操作符
"no-div-regex": 1,//不能使用看起来像除法的正则表达式/=foo/
"no-dupe-keys": 2,//在创建对象字面量时不允许键重复 {a:1,a:1}
"no-dupe-args": 2,//函数参数不能重复
"no-duplicate-case": 2,//switch中的case标签不能重复
"no-else-return": 2,//如果if语句里面有return,后面不能跟else语句
"no-empty": 2,//块语句中的内容不能为空
"no-empty-character-class": 2,//正则表达式中的[]内容不能为空
"no-empty-label": 2,//禁止使用空label
"no-eq-null": 2,//禁止对null使用==或!=运算符
"no-eval": 1,//禁止使用eval
"no-ex-assign": 2,//禁止给catch语句中的异常参数赋值
"no-extend-native": 2,//禁止扩展native对象
"no-extra-bind": 2,//禁止不必要的函数绑定
"no-extra-boolean-cast": 2,//禁止不必要的bool转换
"no-extra-parens": 2,//禁止非必要的括号
"no-extra-semi": 2,//禁止多余的冒号
"no-fallthrough": 1,//禁止switch穿透
"no-floating-decimal": 2,//禁止省略浮点数中的0 .5 3.
"no-func-assign": 2,//禁止重复的函数声明
"no-implicit-coercion": 1,//禁止隐式转换
"no-implied-eval": 2,//禁止使用隐式eval
"no-inline-comments": 0,//禁止行内备注
"no-inner-declarations": [2, "functions"],//禁止在块语句中使用声明(变量或函数)
"no-invalid-regexp": 2,//禁止无效的正则表达式
"no-invalid-this": 2,//禁止无效的this,只能用在构造器,类,对象字面量
"no-irregular-whitespace": 2,//不能有不规则的空格
"no-iterator": 2,//禁止使用__iterator__ 属性
"no-label-var": 2,//label名不能与var声明的变量名相同
"no-labels": 2,//禁止标签声明
"no-lone-blocks": 2,//禁止不必要的嵌套块
"no-lonely-if": 2,//禁止else语句内只有if语句
"no-loop-func": 1,//禁止在循环中使用函数(如果没有引用外部变量不形成闭包就可以)
"no-mixed-requires": [0, false],//声明时不能混用声明类型
"no-mixed-spaces-and-tabs": [2, false],//禁止混用tab和空格
"linebreak-style": [0, "windows"],//换行风格
"no-multi-spaces": 1,//不能用多余的空格
"no-multi-str": 2,//字符串不能用\换行
"no-multiple-empty-lines": [1, {"max": 2}],//空行最多不能超过2行
"no-native-reassign": 2,//不能重写native对象
"no-negated-in-lhs": 2,//in 操作符的左边不能有!
"no-nested-ternary": 0,//禁止使用嵌套的三目运算
"no-new": 1,//禁止在使用new构造一个实例后不赋值
"no-new-func": 1,//禁止使用new Function
"no-new-object": 2,//禁止使用new Object()
"no-new-require": 2,//禁止使用new require
"no-new-wrappers": 2,//禁止使用new创建包装实例,new String new Boolean new Number
"no-obj-calls": 2,//不能调用内置的全局对象,比如Math() JSON()
"no-octal": 2,//禁止使用八进制数字
"no-octal-escape": 2,//禁止使用八进制转义序列
"no-param-reassign": 2,//禁止给参数重新赋值
"no-path-concat": 0,//node中不能使用__dirname或__filename做路径拼接
"no-plusplus": 0,//禁止使用++,--
"no-process-env": 0,//禁止使用process.env
"no-process-exit": 0,//禁止使用process.exit()
"no-proto": 2,//禁止使用__proto__属性
"no-redeclare": 2,//禁止重复声明变量
"no-regex-spaces": 2,//禁止在正则表达式字面量中使用多个空格 /foo bar/
"no-restricted-modules": 0,//如果禁用了指定模块,使用就会报错
"no-return-assign": 1,//return 语句中不能有赋值表达式
"no-script-url": 0,//禁止使用javascript:void(0)
"no-self-compare": 2,//不能比较自身
"no-sequences": 0,//禁止使用逗号运算符
"no-shadow": 2,//外部作用域中的变量不能与它所包含的作用域中的变量或参数同名
"no-shadow-restricted-names": 2,//严格模式中规定的限制标识符不能作为声明时的变量名使用
"no-spaced-func": 2,//函数调用时 函数名与()之间不能有空格
"no-sparse-arrays": 2,//禁止稀疏数组, [1,,2]
"no-sync": 0,//nodejs 禁止同步方法
"no-ternary": 0,//禁止使用三目运算符
"no-trailing-spaces": 1,//一行结束后面不要有空格
"no-this-before-super": 0,//在调用super()之前不能使用this或super
"no-throw-literal": 2,//禁止抛出字面量错误 throw "error";
"no-undef": 1,//不能有未定义的变量
"no-undef-init": 2,//变量初始化时不能直接给它赋值为undefined
"no-undefined": 2,//不能使用undefined
"no-unexpected-multiline": 2,//避免多行表达式
"no-underscore-dangle": 1,//标识符不能以_开头或结尾
"no-unneeded-ternary": 2,//禁止不必要的嵌套 var isYes = answer === 1 ? true : false;
"no-unreachable": 2,//不能有无法执行的代码
"no-unused-expressions": 2,//禁止无用的表达式
"no-unused-vars": [2, {"vars": "all", "args": "after-used"}],//不能有声明后未被使用的变量或参数
"no-use-before-define": 2,//未定义前不能使用
"no-useless-call": 2,//禁止不必要的call和apply
"no-void": 2,//禁用void操作符
"no-var": 0,//禁用var,用let和const代替
"no-warning-comments": [1, { "terms": ["todo", "fixme", "xxx"], "location": "start" }],//不能有警告备注
"no-with": 2,//禁用with
"array-bracket-spacing": [2, "never"],//是否允许非空数组里面有多余的空格
"arrow-parens": 0,//箭头函数用小括号括起来
"arrow-spacing": 0,//=>的前/后括号
"accessor-pairs": 0,//在对象中使用getter/setter
"block-scoped-var": 0,//块语句中使用var
"brace-style": [1, "1tbs"],//大括号风格
"callback-return": 1,//避免多次调用回调什么的
"camelcase": 2,//强制驼峰法命名
"comma-dangle": [2, "never"],//对象字面量项尾不能有逗号
"comma-spacing": 0,//逗号前后的空格
"comma-style": [2, "last"],//逗号风格,换行时在行首还是行尾
"complexity": [0, 11],//循环复杂度
"computed-property-spacing": [0, "never"],//是否允许计算后的键名什么的
"consistent-return": 0,//return 后面是否允许省略
"consistent-this": [2, "that"],//this别名
"constructor-super": 0,//非派生类不能调用super,派生类必须调用super
"curly": [2, "all"],//必须使用 if(){} 中的{}
"default-case": 2,//switch语句最后必须有default
"dot-location": 0,//对象访问符的位置,换行的时候在行首还是行尾
"dot-notation": [0, { "allowKeywords": true }],//避免不必要的方括号
"eol-last": 0,//文件以单一的换行符结束
"eqeqeq": 2,//必须使用全等
"func-names": 0,//函数表达式必须有名字
"func-style": [0, "declaration"],//函数风格,规定只能使用函数声明/函数表达式
"generator-star-spacing": 0,//生成器函数*的前后空格
"guard-for-in": 0,//for in循环要用if语句过滤
"handle-callback-err": 0,//nodejs 处理错误
"id-length": 0,//变量名长度
"indent": [2, 4],//缩进风格
"init-declarations": 0,//声明时必须赋初值
"key-spacing": [0, { "beforeColon": false, "afterColon": true }],//对象字面量中冒号的前后空格
"lines-around-comment": 0,//行前/行后备注
"max-depth": [0, 4],//嵌套块深度
"max-len": [0, 80, 4],//字符串最大长度
"max-nested-callbacks": [0, 2],//回调嵌套深度
"max-params": [0, 3],//函数最多只能有3个参数
"max-statements": [0, 10],//函数内最多有几个声明
"new-cap": 2,//函数名首行大写必须使用new方式调用,首行小写必须用不带new方式调用
"new-parens": 2,//new时必须加小括号
"newline-after-var": 2,//变量声明后是否需要空一行
"object-curly-spacing": [0, "never"],//大括号内是否允许不必要的空格
"object-shorthand": 0,//强制对象字面量缩写语法
"one-var": 1,//连续声明
"operator-assignment": [0, "always"],//赋值运算符 += -=什么的
"operator-linebreak": [2, "after"],//换行时运算符在行尾还是行首
"padded-blocks": 0,//块语句内行首行尾是否要空行
"prefer-const": 0,//首选const
"prefer-spread": 0,//首选展开运算
"prefer-reflect": 0,//首选Reflect的方法
"quotes": [1, "single"],//引号类型 `` "" ''
"quote-props":[2, "always"],//对象字面量中的属性名是否强制双引号
"radix": 2,//parseInt必须指定第二个参数
"id-match": 0,//命名检测
"require-yield": 0,//生成器函数必须有yield
"semi": [2, "always"],//语句强制分号结尾
"semi-spacing": [0, {"before": false, "after": true}],//分号前后空格
"sort-vars": 0,//变量声明时排序
"space-after-keywords": [0, "always"],//关键字后面是否要空一格
"space-before-blocks": [0, "always"],//不以新行开始的块{前面要不要有空格
"space-before-function-paren": [0, "always"],//函数定义时括号前面要不要有空格
"space-in-parens": [0, "never"],//小括号里面要不要有空格
"space-infix-ops": 0,//中缀操作符周围要不要有空格
"space-return-throw-case": 2,//return throw case后面要不要加空格
"space-unary-ops": [0, { "words": true, "nonwords": false }],//一元运算符的前/后要不要加空格
"spaced-comment": 0,//注释风格要不要有空格什么的
"strict": 2,//使用严格模式
"use-isnan": 2,//禁止比较时使用NaN,只能用isNaN()
"valid-jsdoc": 0,//jsdoc规则
"valid-typeof": 2,//必须使用合法的typeof的值
"vars-on-top": 2,//var必须放在作用域顶部
"wrap-iife": [2, "inside"],//立即执行函数表达式的小括号风格
"wrap-regex": 0,//正则表达式字面量用小括号包起来
"yoda": [2, "never"]//禁止尤达条件
https://wangdoc.com/javascript/stdlib/regexp.html
Element.getBoundingClientRect()方法返回元素的大小及其相对于视口的位置。
DOMRect 对象包含了一组用于描述边框的只读属性——left、top、right和bottom,单位为像素。除了 width 和 height 外的属性都是相对于视口的左上角位置而言的,也就是会随着滚动变化
Element.clientWidth / element.clientHeight (内边距 + 内容框)
属性表示元素的内部宽度/高度,以像素计。该属性包括内边距,但不包括垂直/水平滚动条(如果有)、边框和外边距(只读)
element.offsetWidth / element.offsetHeight (边框 + 内边距 + 内容框)
返回一个元素的布局宽度。一个典型的(译者注:各浏览器的offsetWidth可能有所不同)offsetWidth是测量包含元素的边框(border)、水平/垂直内边距(padding)、垂直/水平滚动条(scrollbar)(如果存在的话)、以及CSS设置的宽度(width)/高度的值。
element.scrollWidth / element.scrollHeight
这个只读属性是元素内容宽度/高度的一种度量,包括由于overflow溢出而在屏幕上不可见的内容。
值等于元素在不使用水平/垂直滚动条的情况下适合视口中的所有内容所需的最小宽度/高度。
它还可以包括伪元素的宽度,例如::before或::after。
如果元素的内容可以适合而不需要水平滚动条,则其scrollWidth等于clientWidth
element.clientTop / element.clientLeft
上边框、左边框
element.offsetTop / element.offsetLeft
当前元素顶部距离最近父元素顶部/左边的距离(只读)
element.scrollTop / element.scrollLeft
这个元素的顶部/左边到视口可见内容(的顶部/左边)的距离的度量(元素被卷进去的高度和宽度)(可读可写)
window.innerHeight / window.innerWidth
浏览器窗口的视口(viewport)高度/宽度(以像素为单位);如果有水平/垂直滚动条,也包括滚动条高度/宽度。(只读)
Window.outerHeight / Window.outerWidth
获取整个浏览器窗口的高度/宽度(单位:像素),包括侧边栏(如果存在)、窗口镶边(window chrome)和窗口调正边框(window resizing borders/handles)(只读)
(window.scrollX/window.pageXOffset ) / (window.scrollY/window.pageYOffset )
返回文档/页面水平方向滚动的像素值(是一个浮点数)/返回文档在垂直方向已滚动的像素值(是一个浮点数)
window.screenX / window.screenY
返回浏览器左边界到操作系统桌面左边界的水平距离像素值。/返回浏览器顶部距离系统桌面顶部的垂直距离。
window.screen.width / window.screen.height
操作系统桌面(屏幕)的宽/高
window.screen.availWidth / window.screen.availHeight
操作系统桌面(屏幕)可用宽高(去除任务栏)
设置/获取文档滚动条距离的时候,DTD是否存在会影响document.body.scrollTop 与 document.documentElement.scrollTop的取值
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;