目录
ps切图、vscode、git——工作中使用方法:(2、4、8必看)
13、position定位(relative相对----absolute绝对-----static静态----fixed固定)
20、两个块级元素,如果一个里边设置文字大小,另一个没有设置,默认是基线对齐,会下掉?
24、Math常用的方法(称为数学函数,是对象数据类型,用来操作数字的)
26、if语句——判断成绩——(if中是==比较)——先转为相同类型,再比较
27、switch case语句——判断成绩——(switch中是===比较)——类型和值都必须相等
29、关于for的_for in _打印奇偶项_1-10_1-100求和_任意数求和......
34、dom的回流和重绘——回流一定引起重绘,但重绘不一定回流
44、原型继承:B既然想用A的私有的,也想用公有的,更改原型指向,指向要用的A
45、中间类继承:某实例不属于某类,但想用其原型上的方法,可手动更改实例的_proto_
47、寄生组合继承:B想用A公有的,把B原型指向一个空对象,空对象的_proto_指向A原型
52、定时器清除的方法:clearTimeout(obj)和clearInterval(obj) 且timer = null;
10、混入(一种非常灵活的方式,来分发 Vue 组件中的可复用功能)
15、vuex——管理公共状态的一种工具——放在这里的数据会自动加getter和setter
2、三次握手(A说我要和你建立连接啦,B说可以,A说好的那开始啦 )
3、四次挥手(A说我没有数据发啦,B说好的这边看一下都接收完了没,B说好的接收完了可以断开了,A说好的)
移动、 pc端用公用一套代码以及自适应怎么实现:(参考简书)
1、首先,在网页代码的头部,加入一行viewport元标签。
3、相对大小的字体(rem相对于根元素来说,em相对于父元素来说的)
ps切图、vscode、git——工作中使用方法:(2、4、8必看)
1、你在公司如何用ps切图?
①打开psd文件(多个图层)的方式-------直接拖到ps中上方------或者直接文件打开-----或者ctrol-o--------可以点击左边双箭头变成两列工具栏--------把窗口里除了图层的都别勾选------点放大镜可以放大------alt键可以缩小-------手的工具或者按住空格可以移动整个图---------吸管吸取的颜色会放到前景色上-----双击前景色面板出来的弹框可以看到rgb色值
②传统切图:按住切片工具不松------出现隐藏的工具------选中切片工具-------先隐藏背景色,只切出来透明样式即可--------一般背景色在图层底部--------把眼睛勾选掉-------背景变成马赛克状------开始切图------自己确定切图大小进行调整-------切片选中后-----ctrl+shift+s保存--------弹出框选择格式为PNG-24(因为是透明图,不是透明选中jpg就行)--------去桌面找images文件-----过程中可以右击删除切片--------也可以去用“切片选择工具”再次调整切片大小-----点击视图-----选中清除切片
总结:选中切片--隐藏背景--点击图标--ctrl+shift+s
③蓝湖切图:安装蓝湖插件-----打开ps-----点击窗口-------扩展功能--------选择蓝湖-----出现蓝湖面板-----调到切图页面------把左上角"自动选择"勾上-------紧挨着右边有图层/组(看自己需要选择)-------在ps中双击T可以查看文字颜色大小-------选中移动工具-------点到需要切的图片上边------标记为切图-------如果有一组的就切整个图层组-------图片都标记完了后-------调到上传页面-------上传全部画板-------显示上传成功-----点击蓝色按钮去web端查看-------找到刚切的双击------ctrl+可以放大------选中图片可以看具体宽高值-------点击左边栏有一个“刀状”工具(是切图下载)-------选中web@1x-------点击“下载该页全部切图”-------选择下载路径-------桌面--------window+d切到桌面-------把压缩包放到一个文件夹中-----解压------OK!
总结:选择蓝湖--调到切图--勾上自动--选中图标--标记切图--调到上传--上传全部--web查看--刀状下载--全部切图--window+d--解压
精辟:选中切图--标记切图--上传全部
2、git的使用
ls:查看当前所有的目录
git stash:想临时保存一下,去修改bug
git stash pop:项恢复之前的工作
git pull:每天第一件事
git status:查看当前工作状态--红色(工作区)--绿色(暂存)---clean(已到历史或者无更新)
git add .:工作区全部提交到暂存区(git status后是clean)
git commit -m"注释":暂存区提交到历史区(git status后是clean)
git push:提交到远程仓库
git branch:查看本地拥有的分支
git reanch xxx:创建一个xxx分支
git checkout xxx:切换到当前xxx分支上
git remove -v:查看远程仓库和本地仓库链接的状态(有两行地址说明关联成功)
git log:生成版本信息
git reflog:生成版本信息的前七位
git reset --hard xxxxxxx:快速回滚到这个xxxxx版本号
git reset --hard HEAD^:撤销上次提交
git merge master :把master主分支代码合并到当前分支上,保证当前是最新的
git checkout master:切换到当前分支上
git merge xxx:把当前xxx分支合并到master上
3、vsCode你上班第一天是怎么配置的?
1、安装汉化插件---chinese(必须安装)
2、安装open in browser---右击直接可以打开open in default browser(必须安装)
3、安装live server---实时刷新(必须安装)
4、安装auto rename tag---标签同步(必须安装)
5、安装power mode---炫酷效果
4、你怎么搭建vue框架的?
window系统如何创建一个vue项目?
新建文件夹
打开文件夹输入cmd
vue create xxx回车
选最后一个Manually select featurec 回车
选12567回车
不用管显示选的2.x回车
出来Use history,写yes 回车,用less 回车
出现In dedicated config files,再回车 OK
-------------------------------------------------------------------------------------------------------------------------------
Mac创建一个vue脚手架项目的流程:
npm init -y------初始化一个仓库
npm i vue@2------下载vue2版本的
npm i--global vue-cli------下载全部脚手架
开始:
sudo npm i -g vue cli-----mac专属代码
196825------电脑密码
vue -v------查看vue版本
vue -version------查看vue版本
vue init webpack xxx-------起名
Name....
5、你用npm下载过什么?
npm下载相关内容:
npm init -y:初始化一个项目,并且生成一个package.json文件,里边是项目描述
npm i jquery:下载最新的jQuery,放到node-moudle里边去
npm i jquery@1:下载1版本的jquery
npm i element-ui:下载element-ui
npm uni jquery:卸载jquery
npm i jquery swiper:同时下载两个
6、你上班怎么提交代码?
One____提交代码:
git add .
git commit -m'注释'
git config --global alias.gpush '!f() { : push ; r=$1; [[ -z $r ]] && r=origin; b=$2; t=$(awk "{ print \$2 }" $(git rev-parse --git-dir)/HEAD); t=${t#refs/heads/}; [[ -z $b ]] && b=$t; cmd="git push $r HEAD:refs/for/$b"; echo $cmd; echo; $cmd; }; f'
git gpush
出现连接--过一下
git commit --amend---代码修改提交后需要修改commit message,或者是之前提交过一次,新的修改想要和前面的提交合并成一个节点
git gpush----最后再次git gpush
Two____提交代码:
pull
gitsmart中选中提交项---点击stage(add)
commit
去控制台git push--出现错误按照提示操作
复制地址过一下
如果途中出现错误---就撤回合入---去gitsmart双击adran...----sort----重新commit就行
7、跨域你们公司用的什么?
涉及跨域需要复制过来的代理---config.js中
proxy: {
'/crm': {
target: 'http://aifanfan-test.baidu-int.com',
changeOrigin: true,
secure: false,//可以显示cookie
headers: {
cookie: cookie,
'User-Info': 'uc_id=;uc_appid=585;acc_token=;acc_id=;login_id=26615263:0;device_type=;paas_appid=1'
} } } },
8、为什么要跨域,还有什么其他解决方法吗
因为浏览器有同源策略限制,只要协议名、子域名、主域名、端口号其中任意一个不同就会产生跨域。
解决方法:
1、jsonp:因为浏览器中script、img、iframe标签不受同源限制,可以请求第三方服务器资源,所以可以在script的src属性设置接口地址(接口参数,必须带个自定义函数名,去接收后台返回的数据),优点是兼容好,简单,但是只支持get和http,不支持https
2、cors:在服务端设置响应头中Access-control-allow-origin为对应的域名,如果考虑安全性的话最好不用
3、寻找相同主域document.domain,相当于他有两个共同爸爸,只适用于iframe跨域
4、同上,window.name,就是把不同域的信息放在window.name中,只适用于iframe
5、同上,window.postMessage,但是不能和服务端交换,只能两个iframe交换
6、proxy代理,因为浏览器向服务器发送请求时候受到了限制,但是服务器和服务器之间没有限制,所以可以利用代理服务器,在收到请求后,转发给正真的服务器
CSS方面:(1-15必看)
1、标签语义化:
简单来说就是合适的标签做合适的事,比如标题我们为什么要用h1,优点:对搜索引擎友好,利于网站推广
2、性能优化:
①请求方面:1.合并压缩css和js,为减少http请求次数
2.能用css就不用js,能用js的就不用插件,避免引入大量的第三方库
3.利用字体图标代替png,因字体图标是矢量图,放大了不变形
4.使用精灵图和雪碧图(所有小图展示在一个大图,利用定位显示小图)
5.图片懒加载、路由懒加载
②代码方面:1.js中尽量减少闭包的使用,因闭包坐在上下文不会被释放
2.css中减少@import引入(同步),用link引入(异步)
3.在js封装中,低耦合,高内聚,减少页面冗余代码
4.尽量把绑定事件变成事件委托,因绑定事件需要多次处理函数
5.利用浏览器缓存技术,多做一些缓存
③其他方面:1.第一次不加载音频、视频类的,将它们设置成reload=none;
2.keep-alive钩子函数(保存其他组件不被销毁用的)
3、让一个元素水平垂直居中的方法
1、父元素:display:flex;
justify-content:center;
align-item:center;
2、元素:position:absolute;
letf:50%;
top:50%;
margin-left:负盒子宽度的一半
margin-top:负盒子高度的一半
3、元素:position:absolute;
left:0;
right:0;
top:0;
bottom:0;
margin:auto;
4、元素:position:absolute;
left:50%;
top:50%;
transform:translate(-50%,-50%)
4、制作一个三角形的方法
1、#box{
width: 0; //梯形的话就把这个值改大就可以
height: 0;
border: 50px solid;
border-color: green transparent transparent transparent;
//IE6下不支持透明,IE6下, 设置余下三条边的border-style为dashed
border-style:solid dashed dashed dashed;
2、 #box{
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red; }
3、canvas绘制三角形
var context = canvas.getContext('2d');// 创造一个用于在画布上绘图的环境。
context.beginPath();//准备开始绘制(拿起笔)
context.moveTo(0, 0);//笔尖放到起点(相对于画布大小来说,默认是0,0)
context.lineTo(100, 0);//笔尖移动到100,0位置
context.lineTo(50, 100);//下一个坐标
context.closePath();//创建从当前点到开始点的路径,自动封闭收尾路径
5、浮动造成的盒子塌陷问题怎么解决?
1、给浮动元素的父级增加height
2、给浮动元素的父级增加overflow:hidden;
3、给浮动元素末尾增加一个元素,给这个元素设置clear:both;
4、复制代码,且给浮动元素父级增加clearfix
6、盒模型理解:
content:主内容---总盒子宽度=content的宽度+2个padding+2个border
padding:内填充
margin:外边距
border:边框
标准盒模型(content部分的宽高):box-sizing:content-box;
ie盒模型(总盒子的,常用):box-sizing:border-box;
7、0.5px线怎么弄?
1、把元素的伪类高度设为1px,背景渐变,一半有颜色,一半透明。
2、transform:scale()来达到压缩一半的目的。
补充:如何实现两点一线
.demo{
width: 300px;
height: 0;
border-bottom: 10px solid black;
}
--------------------------------------
canvas绘制
var context=canvas.getContext("2d");
context.moveTo(100,100)
context.lineTo(700,700)
context.stroke()
8、flex布局
display:flex; --------div上下排列(块级)
display:inline-flex;--------div左右排列(行内块)
① flex容器的属性:
flex-direction:column;------主轴方向是竖着(默认是横着row)
flex-wrap:wrap;-------控制项目是否换行(默认是不换行nowrap)
flex-flow:row wrap;-------上边两个简写
justifu-content : flex-start;---------------主轴------从前往后排列
:flex-end;----------------主轴------从后往前排列
:center;------------------主轴------居中
:space-between;------主轴------两端对齐
:sapce-around;--------主轴-----每元素相同左边距与右边距|中间是两边二倍
:space-evenly;---------主轴-----每个元素左右相等,不存在二倍关系
align-items:flex-start;-----侧轴-------从前往后
:flex-end;-----侧轴------从后往前
:center;-------侧轴--------居中
:stretch;------侧轴-------侧轴无元素时直接把主轴元素拉下来,填满,用时删高
:baseline;----侧轴-------每个元素的文本对齐
//下边这个用在换行定义多根线轴时候的对齐方式
align-content:flex-start;-------多轴------从开始,一行一行排
:flex-end;--------多轴------样子不变,占倒数第几行
:center;----------多轴-------样子不变,占中间几行
:stretch;---------多轴-------样子不变,侧轴无元素时,占满,变大
:space-between;-----多轴-------行与行分散开对齐
:space-around;-------多轴-------加相同行距,中间二倍
//下边这个控制单个元素位置
align-self:center;
②flex项目的属性:(子元素的属性)
:flex:1;----等分(如全部li都是1,等分,如果有2,则这个是其他2倍)
:order:0------顺序(默认0,越小越靠前)
:flex-grow:0----放大多少数字(默认0,不放大)
:flex-shrink:1;----(默认1,剩余空间不够,该元素缩小,若全是1,都缩)
----(若全是1,只有一个是0,则该元素不缩小,负值无效)
:flex-basis:200px ;------设置弹性和基准值宽高(默认auto)
-------------------------------------------------------------------------------------------
:flex:0 1 auto;------flex-grow + glex-shrink + flex-basis 的默认简写
:flex : 0 0 auto;===flex:none;
:flex : 1 1 auto;===flex:auto;
:flex:number 1 0%===flex:number;
9、行内、行内块、块
行内元素:写宽高没用,内容定大小,并列一行
span
a
格式化标签------加粗:b strong 斜体:i em 下划线:u ins 删除线 s del
行内块:写宽高有用,并列一行,特殊行内元素
img
video\audio
input
select
textarea
块元素:写宽高有用,独占一行
h1-h6
div
p
hr
pre
table
form
三大列表: ul ol li ------ dl dt dd (一般用在网页底部)
10、 让一个元素消失有几种办法:
1、display:none;----位置不在
2、opacity:0;-----透明度,位置在
3、visibility:hidden;-----隐藏,位置在
4、margin负值,调节到另一边
5、层级关系,z-index
6、设置宽高为0
11、圣杯布局(两边固定,中间自适应)
1、设一个容器,里边放三个盒子,让它们左浮--------两侧盒子固定,中间100%
左右下掉,可用负边距实现一行------左盒设margin-left:-100%,右设-200px
main左右文字被盖,可以给父加内边距-------container{ padding: 0 200px}
左右贴边。给左右加相对定位-----.left,.right{position:relative; left:-200px}
总结:两边固定,中间自适应,用margin负值使同行,若看不见中间文字,可加padding,再给两边定位回去
2、flex实现,父亲设置display:flex, ( order:-1,值越小越靠前)
flex-basis,给left和right设置固定宽度
main设置flex:1(占满其余空间)
总结:两边用flex-basis设置固定宽度,中间flex:1
12、双飞翼布局(两边固定,中间自适应)
1、和圣杯相似,只不过在main中间位置文字被挡时候,它不给中间挤,而是创建子div, 给子div设置margin,然后给左右留出位置
13、position定位(relative相对----absolute绝对-----static静态----fixed固定)
1、relative(相对定位):
①于自己原来位置,占位,层级高于普通文档流。
②可给绝对定位做参照物,但是必须写在它的父级或者祖先级
③负数
2、absolute(绝对定位):
①相对于参照物来说位置,不占位,层级高。(z-index控制层级)
②寻找参照物按就近原则,若无就是body
③参照物本身已用position,那它就可做绝对定位,就不用参照物
④块元素不写宽高可撑满父级,但设了absolute,大小就由自身定
⑤如absolute中元素宽用百分比表示,且参照物与父级不是同一个,那听参照
(百分比指的是元素占参照物的百分之多少)
3、fixed(固定定位):相对于整个窗口的定位
14、transform常用的几个值
1、translate------位移
transform:translate(100px);-----水平位移100px
transform:translateY(100px);------垂直位移100px
transform:translate(100px,200px);-----复合位移xy
2、scale------缩放
transform:scale(x,y);---------缩放宽度的x倍,缩放高度的y倍
transform:scale(n);---------同时缩放宽和高的n倍
3、rolate------旋转
transfom:rolateX(45deg);-------围绕X轴转45度
transfom:rolateY(45deg);-------围绕Y轴转45度
transfom:rolateZ(45deg);-------围绕Z轴转45度
4、skew------倾斜
transform:skewX(45deg);---------沿x轴倾斜45度
transform:skewY(45deg);--------沿y轴倾斜45度
transform:skew(25deg,15deg);-------沿x,y倾斜转换
5、origin-------设置旋转元素的基点位置
transform: rotate(45deg);
transform-origin:20% 40%;
6、style------使被转换的子元素保留其 3D 转换:
transform: rotateY(60deg);
transform-style: preserve-3d;
7、近大远小
给图片加:hover { transform : rolateY ( 45deg ) }
给父级加:perspective:100px; // 距离呈现
15、transition过渡动画
CSS3中的帧动画:animation(有两部分)
1、
transition-property : run ; ---------动画属性名称
transition-duration : 2s ;----------完成动画需要多久
transition-timing-function : linear;-------动画运动曲线
transition-delay : 1s;---------延迟多久开始动画
transition-iteration-count : infinite ;--------动画播放次数,可是数字
以上简写为:transition:run 3s linear 1s infinite forwards backwards both
名 时 曲线 延 循环 结停最后 防延迟 代前两
2、制作运动的轨迹(每一帧元素的样式) @keyframes
@keyframes 动画名{
0%或者from{ 第一帧的样式 }
50%{ 中间某帧的样式 }
100%或者to{ 最后一帧的样式
}
16、overflow常用的几个值:
overflow:hidden;----超出隐藏
overflow:auto;----根据情况自动添加滚动条
overflow:scroll;-----不用根据情况,直接添加滚动条
17、 margin值穿透问题:
描述:外边大盒子不设置padding-top或者border-top,只给小盒子设置margin-top,外边大盒子会随着小盒子下掉
解决:1、给大盒子加border-top:1px solid transparent;或者加paddng-top
2、给大盒子加overflow:hidden;
18、margin值合并问题:
描述:上下两个盒子box1和box2,给上box1设置了margin-bottom,给box2设置了margin-top,它俩中间值是是多少?
解决:取最大的哪个
19、回车造成两个块级元素中有缝隙怎么办?
解决:在结构中消除换行符
给他们父级加font-size:0;里面的子元素再单独设置
20、两个块级元素,如果一个里边设置文字大小,另一个没有设置,默认是基线对齐,会下掉?
解决:根据情况改变其对齐方式
vertical-align:top;-----顶线对齐
:middle----中线对齐
:bottom;-----底线对齐
:baseline;-----基线对齐
21、 浮动的特点:
1、脱离正常文档流,不占位置了
2、浮动针对的是父级
3、正常文档流中,宽度可以继承,一旦浮动,宽便不能继承父级的,而是由自身大小决定的
4、行内元素写宽高本身不起作用,一旦浮动,就起作用了
5、浮动的本质,是为了实现图文混排
22、引入css的四种方式:
内嵌式:最常见的
行内式:行间
外链式:在头部加<link rel:>
导入式:在头部加style,里面写@import url(index.css)
23、你知道哪些默认样式清除表?
*:全选通配符
list-style:none;-----清除默认列表样式
text-decoration:none;------清除a标签的下划线
text-indent:2em;------段落首行缩进
24、说说你知道的选择器:
1、通配符选择器*:权重0
2、标签选择器:权重1
3、类选择器:权重10
4、属性选择器:权重10 ------[index]---[index="b"]
5、id选择器:权重100
6、分组选择器:逗号 权重按照逗号前后分开算
8、子选择器:> 权重之和
9、后代选择器:空格 权重之和
10、交集选择器:什么也不加 且关系 权重之和
11、相邻兄弟选择器:例如h1+p 就是向下找所有挨着h1的p标签 权重之和
12、通用兄弟选择器:不用挨着 只要是兄弟就选中 权重之和
13、伪类选择器:a:link 默认|a:visited 访问后|a:hover 滑上显示|a:active 点击了
14、CSS3新增选择器::nth-child(3);------选中正数第三个
:nth-child(2n);------选中偶数
:nth-child(2n+1);------选中奇数
:nth-last-child(3);------选中倒数第三个
:first-child;-----选中第一个
:last-child;-----选中最后一个
25、关于a标签值和锚点跳转怎么实现?
a标签:空值代表刷新,#代表回到顶部,javascript:;代表禁止跳转
锚点跳转:给显示内容地方加id="ss",给跳转按钮a标签加href="#ss"
26、 css三大特定:
继承性:color font-size
层叠性:两个选择器给同一个属性不同的值,css这种处理冲突的能力 按权重和顺序来判断的
优先级:!import > 行内 > id > 类 > 标签 > * > 继承 > 浏览器
27、常用的表单元素有什么:
1、input
type:text---文本输入框
type:password----密码输入框
type:reset----重置
type:submit----提交
type:button----按钮
type:radio----单选
type:checkout----多选
属性:
placeholder---提示文字
autofocus-----自动获取焦点
required----校验(非空,是必填的)
checked----input的默认选中
2、button
默认有提交表单功能,想禁止,添加type:"button"
3、textarea
文本域,评论框
4、下拉框
<select name:"" id>
<option value:"" disabled>河北</option>----禁止点击
<option value:"" selected>河北</option>----默认选中
5、单选文字关联功能,用lable标签把文字括起来,给lable行间加一个for属性,属性值与id中一致
<lable for="man">男</lable> <input id="man" name="sex" type="radio">
<lable for="woman">男</lable> <input id="woman" name="sex" type="radio">
28、padding值怎么写
padding若有四个值:上右下左(顺时针)
三个值:上 左右 下
两个值:上下 左右
29、你知道的backgorund值都有什么:
background-img:url("图片路径")
backgoryund-position:center center;------(图片水平垂直位置)
:left center
:50px 50px
:50% 50%
backgorund-repeat :no-repeat--------(图片不平铺)
:repeat-x(水平平铺)
:repeat-y(垂直平铺)
backgroun-origin:padding-box----从内填充开始,默认的,-------( 指定图像的定位区域 )
:border-box-----从边框开始
:content-box----从content部分开始
若是背景图像backgorund-attachment是固定,则此属性无效
backgorund-attachment:fixed;--------(背景图固定)
:scroll(背景图随着滑动而滑动,默认)
background-clip:border-box;------超出边框部分背景裁剪掉,默认的,(背景裁剪)
:padding-box---超出边框部背景分裁剪掉
:content-box---超出content部分背景裁剪掉
background-size:100px 100px;------(图片宽高)
:100% 100%;------(图片自适应)
:cover;-------(背景图全覆盖)
:contain;------(只要高或者宽一边铺满,就停止放大)
30、css3中私有前缀
-webkit-border-radios:50%;-------谷歌
-moz-border-radios:50%;--------火狐
-ms-border-radios:50%;--------ie
-o-border-radios:50%;------欧朋
31、绘制圆形
width: 200px;
height: 200px;
border-radius: 50%;
background: green;
32、box-shadow----阴影
box-shadow : 10px 10px 5px 5px yellow inset (cutset默认外)
阴影x\y轴偏移 模糊度 大小 颜色 内阴影
33、渐变
1、线性渐变----Linear gradients(默认是从上到下)
background:linear-gradient(red,green);-----上---下
backgorund:linear-gradient ( left,red,green);------左----右
backgorund:linear-gradient ( left top,red,green);------左上----右下
backgorund:linear-gradient ( 90deg,red,green);-----角度
2、径向渐变-----radial gradients ( 默认是椭圆,至少有两个颜色值)
background:radial-gradient (circle,red,green);-------圆
backgorund:radial-gradient (ellipse,red,green);------椭圆
34、less的使用
①嵌套:
#header {
color: black;
}
#header .navigation {
font-size: 12px;
}
#header .logo {
width: 300px;
}
---------------用下边的less语言可以实现上边的css
#header {
color: black;
.navigation {
font-size: 12px;
}
.logo {
width: 300px;
}
}
----------------嵌套 结合 伪类选择器 的使用(&代表当前选择器的父级)
.clearfix {
display: block;
zoom: 1;
&:after {
content: " ";
display: block;
font-size: 0;
height: 0;
clear: both;
visibility: hidden;
}
}
②变量:
@width: 10px;
@height: @width + 10px;
----------------------以上是定义两个less变量,以后用到它的直接调用就可以
#header{
width: @width;
height: @height;
}
----------------------编译后为:
#header {
width: 10px;
height: 20px;
}
③混合:将A组选择器混入到B组选择器中,那么B中也就可以有A中的样式了
.bordered {
border-top: dotted 1px black;
border-bottom: solid 2px black;
}
#menu a {
color: #111;
.bordered();---------------------想用上边类名中的,直接这样混入就可以
}
.post a {
color: red;
.bordered();
}
④@规则嵌套和冒泡(说实话,对这个有点不理解,如果有懂行的高手,可以及教教我)
.component {
width: 300px;
@media (min-width: 768px) {
width: 600px;
@media (min-resolution: 192dpi) {
background-image: url(/img/retina2x.png);
}
}
@media (min-width: 1280px) {
width: 800px;
}
}
-----------------------------------编译后
.component {
width: 300px;
}
@media (min-width: 768px) {
.component {
width: 600px;
}
}
@media (min-width: 768px) and (min-resolution: 192dpi) {
.component {
background-image: url(/img/retina2x.png);
}
}
@media (min-width: 1280px) {
.component {
width: 800px;
}
}
⑤运算:算术运算符 +
、-
、*
、/
可以对任何数字、颜色或变量进行运算。如果可能的话,算术运算符在加、减或比较之前会进行单位换算。计算的结果以最左侧操作数的单位类型为准。如果单位换算无效或失去意义,则忽略单位。无效的单位换算例如:px 到 cm 或 rad 到 % 的转换。
------------------------以下操作数被转换成相同的单位
@conversion-1: 5cm + 10mm; // 结果是 6cm
@conversion-2: 2 - 3cm - 5mm; // 结果是 -1.5cm
-------------------------以下转换无效
@incompatible-units: 2 + 5px - 3cm; // 结果是 4px
-------------------------变量和举例
@base: 5%;
@filler: @base * 2; // 结果是 10%
@other: @base + @filler; // 结果是 15%
乘法和除法不作转换。因为这两种运算在大多数情况下都没有意义,一个长度乘以一个长度就得到一个区域,而 CSS 是不支持指定区域的。Less 将按数字的原样进行操作,并将为计算结果指定明确的单位类型。
@base: 2cm * 3mm; // 结果是 6cm
你还可以对颜色进行算术运算:
@color: #224488 / 2; //结果是 #112244
background-color: #112244 + #111; // 结果是 #223355
⑥calc()特例:在嵌套函数中会计算变量和数学公式的值。
@var: 50vh/2;
width: calc(50% + (@var - 20px)); // 结果是 calc(50% + (25vh - 20px))
⑦转义:允许你使用任意字符串作为属性或变量值。任何 ~"anything"
或 ~'anything'
形式的内容都将按原样输出,除非 interpolation。
@min768: ~"(min-width: 768px)";
.element {
@media @min768 {
font-size: 1.2rem;
}
}
----------------编译后:
@media (min-width: 768px) {
.element {
font-size: 1.2rem;
}
}
----------------注意,从 Less 3.5 开始,可以简写为:
@min768: (min-width: 768px);
.element {
@media @min768 {
font-size: 1.2rem;
}
}
----------------在 Less 3.5+ 版本中,许多以前需要“引号转义”的情况就不再需要了。
⑧函数:用法非常简单。下面这个例子将介绍如何利用 percentage 函数将 0.5 转换为 50%,将颜色饱和度增加 5%,以及颜色亮度降低 25% 并且色相值增加 8 等用法:
@base: #f04615;
@width: 0.5;
.class {
width: percentage(@width); // returns `50%`
color: saturate(@base, 5%);
background-color: spin(lighten(@base, 25%), 8);
}
⑨命名空间和访问符:将一些混合(mixins)和变量置于 #bundle
之下,为了以后方便重用或分发
#bundle() {
.button {
display: block;
border: 1px solid black;
background-color: grey;
&:hover {
background-color: white;
}
}
.tab { ... }
.citation { ... }
}
--------------------把 .button 类混合到 #header a 中
#header a {
color: orange;
#bundle.button(); // 还可以书写为 #bundle > .button 形式
}
----------------------如果不希望它们出现在输出的 CSS 中,例如 #bundle .tab,请将 () 附加到命名空间(例如 #bundle())后面。
⑩映射
#colors() {
primary: blue;
secondary: green;
}
.button {
color: #colors[primary];
border: 1px solid #colors[secondary];
}
------------------输出
.button {
color: blue;
border: 1px solid green;
}
补充:作用域
@var: red;
#page {
@var: white;
#header {
color: @var; // white
}
}
--------------------上下两个例子都是向上查找
@var: red;
#page {
#header {
color: @var; // white
}
@var: white;
}
补充:导入使用
@import "library"; // library.less
@import "typo.css";
35、说说你知道的自适应布局(BFC)
JS方面:(1-10、15、18、22必看)
1、this:
①执行看点-------点前是谁就是谁
②全局、自执行函数、回调-----一般是window
③构造函数、原型------一般是当前实例
④箭头函数-------无this
2、作用域:
①全局作用域------供js执行的环境,最大的window
②私有作用域-----函数执行时候形成,不受外界影响
③块级作用域-----es6新增
3、原型链:
①所有函数身上都有一个属性prototype(又是对象数据类型),它天生自带一个constructor,指向所属类(也就是构造函数)
②所有对象都有一个属性_proto_,指向所属类的原型
4、闭包作用:
①保护:放在全局中,造成全局污染,放在函数中,执行完了会销毁,所以这时候我们需要给这个函数设置个儿子,让这儿子返回这个变量,以便之后继续使用
②保存:return出去了,就相当于保存下来可以继续用了
5、面向过程与面向对象区别:
①面向过程:蛋炒饭-混合-灵活性差-耦合度高-可维护差------适合少代码,性能好---C语言
②面向对象:盖浇饭-分离-灵活性好-耦合度低-可维护好------适合多代码,性能差-----JS、java、c++、php、.net
6、异步编程——Promise
①Promise是es6新增的一个内置类,默认有一个状态---等待态,和两个事件池子,一个成功的,一个失败的。
②当我们new一个promise实例的时候,会给它传递一个回调函数,这个回调有两个形参,一个是成功态函数resolve,一个是失败态函数reject
③promise内部,当你执行resolve时候,就会把当前状态变为成功,且发布成功池子里函数,
当你执行reject时候,会把当前状态变为失败态,且发布失败池子里的函数
④如果你new promise里的函数函数出错了,它内部是把exector拿try catch包了一下,错了就执行catch中的失败回调,否则正常执行
⑤then就是给不同的池子订阅不用的方法
promise.catch(()=>{});//捕获错的
promise.finally(()=>{});//不管上边怎么样,都执行
promise.all();//所有异步任务都是成功态的时候,执行all
promise.race();//赛跑的意思,只要第一个执行了,是成功就是成功,失败就是失败
7、异步编程——微任务、宏任务
微任务:requestAnimationFrame(实现动画)---有争议
promise.then/catch/finally
async/await
queueMicrotask----创建异步微任务
IntersectionObserver------监听当前dom元素和可视窗口交叉状态的信息
MutationObserver-------监听当前dom元素信息的改变
process.nextTick (node用)------执行下一个任务或者队列
宏任务: 定时器、
整体代码
事件绑定/事件队列、
XMLHttpRequest(ajax)/Fetch、
messageChannel(消息通知队列)、
setImmediate(只在node中有)
总结:
1、先执行宏任务的script整体代码
2、遇到定时器——放到异步 宏任务队列
3、promise和async——放到异步 微任务队列
4、宏任务的整体代码执行完了——去微任务队列看情况
5、微任务队列都执行完两位——去宏任务队列执行剩余定时器
//练习----答案:2,4,5,7,9,3,1,6,8
setTimeout(()=>{
console.log(1)
},20);
console.log(2);
setTimeout(()=>{
console.log(3)
},10);
console.log(4);
for(let i=0;i<90000000;i++){
}
console.log(5);
setTimeout(()=>{
console.log(6);
},8)
console.log(7);
setTimeout(()=>{
consle.log(8);
},15)
console.log(9)
//练习二
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(()=>{
console.log('setTimeout');
},0)
async1();
new Promise((resolve)=>{
console.log('promise1');
resolve();
}).then(()=>{
console.log('promise2');
});
console.log('script end');
答案:
script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout
8、MVC和MVVM
MVVM即Model-View-ViewModel的简写。即模型-视图-视图模型。模型(Model)指的是后端传递的数据。视图(View)指的是所看到的页面。视图模型(ViewModel)是mvvm模式的核心,它有两个方向:一是将模型(Model)转化成视图(View),即将后端传递的数据转化成所看到的页面。实现的方式是:数据绑定。二是将视图(View)转化成模型(Model),即将所看到的页面转化成后端的数据。实现的方式是:DOM 事件监听。这两个方向都实现的,我们称之为数据的双向绑定。
MVC是Model-View- Controller的简写。即模型-视图-控制器。M和V指的意思和MVVM中的M和V意思一样。C即Controller指的是页面业务逻辑。使用MVC的目的就是将M和V的代码分离。MVC是单向通信。也就是View跟Model,必须通过Controller来承上启下。MVC和MVVM的区别并不是VM完全取代了C,只是在MVC的基础上增加了一层VM,只不过是弱化了C的概念,ViewModel存在目的在于抽离Controller中展示的业务逻辑,而不是替代Controller,其它视图操作业务等还是应该放在Controller中实现。
总结:也就是说MVVM实现的是业务逻辑组件的重用,减少操作dom,自动交互,使开发更高效,结构更清晰,增加代码的复用性。
9、深克隆与浅克隆
1、深克隆(相当于把深层的地址也克隆的,修改的时候不会相互影响)
var obj={name:"lii",a:{a:100}};
var obj2=JSON.parse(JSON.stringify(obj));
obj.a.c=300;//把自己的改了,不会影响克隆的
console.log(obj)//{ name: 'lii', a: { a: 100, c: 300 } }
console.log(obj2)//{ name: 'lii', a: { a: 100 } }
2、浅克隆(相当于只克隆了一层,底层会相互影响)
var obj={name:"lii",a:{a:100}};
var obj3={};
for(var key in obj){
obj3[key]=obj[key]
}
obj.a.c=300;//把自己的改了,会影响克隆的
console.log(obj)//{ name: 'lii', a: { a: 100, c: 300 } }
console.log(obj3)//{ name: 'lii', a: { a: 100, c: 300 } }
10、es6新特性:
①let和const:1. 其中const声明的时候必须有初始值(不能const a,必须const=a)
2.与var相比,没有了变量提升
3.在同一个作用域,变量不允许重名(不能let a,又出现let a)
4.有块级作用域概念,即{}
中间的部分是一个块级作用域。例如:for
循 环、 if
逻辑判断、while
循环等语句后面的 {}
都是一个块级作用域。
5.暂时性死区(在声明之前都不可以用)
②解构赋值:1.数组的解构赋值——let [a,b,c]=ary;
2.对象的解构赋值——let {obj,name}=data;
3.函数的解构赋值——function fn([x,y]){console.log(x,y)} var ary=[1,2]; fn(ary)
③拓展运算符:1.var ary3=[...ary1,...ary2]; //合并ary1和ary2
2.var obj3=Object.assign(obj1,obj2); //另一种合并方式
④箭头函数:1.无this,若用了this,会按照作用域向上查找
2.无arguments,但是可用剩余运算符得到
3.如果只有一个形参,可以省略小括号
4.如果只有return一行代码,可以省略return和大括号
5.如果renturn的是一个对象,要省略的话,可给省略后的结果加一个小括号
6.也可以和普通函数一样,给形参赋默认值
7.箭头函数不能当类用
⑤类:(下边演示普通函数和类的转换与区别)
普通:
function fn(x,y){
this,x=100;
this.y="y";
}
fn.prototype.getX=function(){
return "getX" ;
}
fn.num="num";
let fn1=new fn(1,2);//正确
类:
class fn{
a=300;//相当于添加私有属性a
constructor(x,y){//构造函数
this.x=100;
this.y="y";
}
getX(){//原型上
return "getX" ;
}
static num="num";//把类当成对象给它添加静态属性
let fn1=new fn(1,2);//正确
fn();//class不能当成普通函数执行
⑥:set数据结构:1.set是一个内置类,是一种数据结构,不是数据类型,和数组类似
2.set实例中每项不允许重复(字符串1和数字1它认为不重复)
3.set()里的参数可以是数组、类数组、字符串
4.var a = new set("aaaabc");//输出a的话,{"a","b","c"},可实现数组去重
5.set原型上一些方法:add、delete、clear、has
11、webpack介绍
webpack是代码编译工具,有入口,出口、loader和插件。webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具。当 webpack 处理应用程序时,它会在内部构建一个依赖图,此依赖图对应映射到项目所需的每个模块,并生成一个或多个 bundle。
12、js的组成
1、ECMAScript的核心语法
2、dom (document object model)文档对象模型-------用来提供方法和属性
3、bom (browser object model)浏览器对象模型--------让js可以操作浏览器
13、创建变量的六种方式
1、var-----声明一个变量(es3)
2、let------声明一个变量(es6)
3、const----声明一个常量(es6)
4、class----创建一个类(es6)
5、function-----声明一个函数(es3)
6、import-------信息导入(es6)
14、js命名规范
1、区分大小写
2、遵循驼峰命名法,以数字、字母、下划线、$符组成(不能以数字开头)
3、不能是关键字或者保留字
4、命名要语义化
15、js数据类型
1、基本数据类型:
number、string、boolean、null、undefined
2、引用数据类型
object:普通对象、数组、正则、Math、Date
function:函数
3、symbol ( 代表唯一的一个值 )
16、js检测数据类型的4种方式+检测对象的公私属性
1、typeof---------typeof("name");//String
2、instanceof
1 instanceof Number-----flase // 不能检测字面量创建出来的基本数据类型
new Number(1) instanceof Number-------true // 如果在类的原型中,我们检测出来的未必准确
[ ] instanceof object------true // 只要在当前实例的原型链上,检测出来的都是true
3、constructor
[ ].constructor===Array;-------true
" ".constructor===String;-------true
true.constructor===Boolean;------true
Fn的原型.constructor===Fn;-------true
注意:let obj={constructor:100}; console.log(obj.constructor===Object);------false------被重定向就不管用了
4、Object.prototype.toString.call( )
准确常用的,原理:先获取Object原型上的toString方法,让方法执行,并改变方法中this指向
Object.prototype.toString.call(Fn);-------[object Function]
Object.prototype.toString.call(1);------[object Number]
Object.prototype.toString.call("2");-------[object String]
5、in的用法——检测当前h1对象是否存在age属性(不区分共有和私有属性,普通或构造函数)
“age” in f1 //true
6、hasOwnProperty——检测name属性是不是obj对象的私有属性
obj.hasOwnProperty("name")
7、封装一个检测共有属性的
Object.prototype.hasPubProperty=function(attr){
return attr in this &&!this.hasOwnProperty(attr)?true:false;
}
obj.hasPubProperty("name");//false
17、js创建对象的两种方式
1、字面量:var obj={};
2、基于构造函数:var obj=new Object()
18、数据类型转换
1、parseInt:转整型,从左到右遇到非有效数字就停止
parseInt(12.5p)-------12
2、parseFloat:转浮点,同理
parseFloat(12.5p)------12.5
3、isNaN:检测是否有效数字
true是非有效,false是有效,若检测非数字,则隐式调用number
4、除了null、undefined、0、" "、NaN这五种转布尔是flase,其余转布尔都是true
5、针对4的补充:null和undefined用在什么时候?
1、null
在不确定一个变量具体数据类型的时候,可先赋值null
获取页面中不存在元素的时候
想清除对象空间地址的时候
2、undefined
只声明,没定义,缺少值的时候
给了形参,没传递实参的时候
函数没有返回值时候
3、null==undefined // true
null===unedfined // false------类型不同,null是“object”,undefined是unedfined
null和undefined与其他值永远不相等
NaN也永远不等于任何一个数据类型
6、json对象转字符串
const obj = {
id: 0,
name: '小米',
age: 12
}
const objToStr = JSON.stringify(obj)
console.log('obj:', obj)
console.log('objToStr:', objToStr)
7、json字符串转对象
const str = '{"id":0,"name":"张三","age":12}'
const strToObj = JSON.parse(str)
console.log('str:', str)
console.log('strToObj:', strToObj)
19、对象的增删改查
1、增加属性名与属性值:
var obj={"name":"lili"};
obj.age=18;
obj["age"]=18;
obj [ 2 ]=18; /若属性名是数字,只能用这一种方法增加
2、删除属性值:
var obj={"name":"liii"};
obj.name=null;
delete obj.name;
3、修改属性值:
var obj={"name":"lili"};
obj.name="zhangtao"
4、查询属性值是什么:
var obj={"name":"liili"};
obj.name
obj["name"]
obj.job //无,返回undefined
20、&&、||
&&且:前后条件都满足,才能执行-----------||或:只要满足一个,就能执行
21、栈内存与堆内存
占内存:存基本数据类型,按值操作,供js执行的环境
堆内存:存引用数据类型,按空间地址操作,---------对象的话:有键值对,函数的话,把整个函数当字符串
22、数组中常用的方法
1、shift——删头——无参——改原——返删
var ary=[1,2,3,4,5];
var res=ary.shift();
console.log(ary);//[2,3,4,5]
console.log(res);//1
2、pop——删尾——无参——改原——返删
var ary=[1,2,3,4,5];
var res=ary.pop();
console.log(ary);//[1,2,3,4]
console.log(res);//5
3、unshift——加头——参加——改原——返长
var ary=[1,2,3,4,5];
var res=ary.unshift(0);
console.log(ary);//[0,1,2,3,4,5]
console.log(res);//6
4、push——加尾——参加——改原——返长
var ary=[1,2,3,4,5];
var res=ary.push(6);
console.log(ary);//[1,2,3,4,5,6]
console.log(res);//6
5、srort——排序——无参|函数——改原——返排
var ary=[1,6,3,4,5];
var res=ary.sort();//1,3,4,5,6
ary.sort(function(a,b){
return a-b//升序-----从小到大
// return b-a//倒序------从大到小
})
6、reverse——倒序——无参——改原——返倒
var ary=[1,2,3,4,5];
var res=ary.reverse();
console.log(ary);//[5,4,3,2,1]
console.log(res);//[5,4,3,2,1]
7、splice(n,m,x,y)——从索引n开始(包含n),删除m项,并用x、y替换——改原——返删
var ary=[1,2,3,4,5];
var res=ary.splice(0,2,8,9);//从索引0开始,删除两项,用89替换
console.log(ary);//[8,9,3,4,5]
console.log(res);//1,2返回删除项
-----------下边是利用splice给开头增加一项---------- -删除开头就是ary.splice(0,1)
var ary=[1,2,3,4,5];
var res=ary.splice(0,0,6);//从索引0开始删除0项,用6替换
console.log(ary);//[6,1,2,3,4,5]
console.log(res);//[]
-----------下边是利用splice给末尾增加一项------------删除末尾就是ary.splice(ary.length-1,1)
var ary=[1,2,3,4,5];
var res=ary.splice(ary.length,0,6);//从最后一项开始删除0项,用6替换
console.log(ary);//[1,2,3,4,5,6]
console.log(res);//[]
注意—————ary[ary.length]=200也可给末尾加
8、slice(n,m)——从数组中选索引n到索引m的数(不包m)——参数n,m——不改——返选中的
var ary=[1,2,3,4,5,6];
res=ary.slice(0,2);//选中索引0-2不包含2
console.log(ary);//[1,2,3,4,5,6]
console.log(res);//[1,2]
--------------------下边可以复制整个数组-----复制的新数组和原来值不相等,因为不同的地址
ary.slice(0);
ary.slice()
9、concat——拼接——不改——返新
var ary=[1,2,3];
ary2=[4,5,6];
var res=ary.concat(ary2,7);
console.log(ary);//[1,2,3]不改原
console.log(res);//[1,2,3,4,5,6,7]拼接后的新数组
10、toString——数组转字符串——不改——返串
var ary=[1,2,3];
var res=ary.toString();
console.log(ary);
console.log(res);
11、join——数组转字符串——并用指定分隔符分隔——不改——返串
var ary=[1,2,3];
var res=ary.join("+");//不传参就是返回普通字符串
console.log(res);//"1+2+3"
---------------以下可利用它有连接符,实现求和
var res2=eval(ary.join("+"));
console.log(res2);//6
12、indexOf(x,y)——检测x第一次出现的位置,从索引y开始检测——不改——返位置
13、lastIndexOf(x,y)——检测x最后一次出现的位置,到索引y时停止——不改——返位置
14、includes——判断是否包含——不改——返布尔
15、forEach——遍历——不改——无返回
var ary=[5,6,7];
var res=ary.forEach(function(item,index){
console.log(item)//每一项的数字
console.log(index)//每一项的索引
})
console.log(ary);//[5,6,7]
16、map——映射——不改——返映射后的
var ary=[5,6,7];
var res=ary.map(function(item,index){
return item+2;//给每一项加2
})
console.log(ary);//[5,6,7]
console.log(res);//[7,8,9]
17、filter——过滤——不改——返符合条件的新数组
let arr = [100,200,300,400,500,600];
let res = arr.filter((item,index)=>{
return item>300;
});
console.log(res);//[400,500,600]
18、find——查找———不改————符合的第一项
let arr = [100,200,300,400,500];
let res = arr.find((item)=>{
return item>400
});
console.log(res);//500
19、some——查找——不改——只要有一个符合就停止循环,返回true,否则就false
let arr = [100,200,300,400,500];
let res = arr.some((item)=>{
return item>900
});
console.log(arr);//[100,200,300,400,500]
console.log(res);//false
20、every——查找——不改——每一项都符合返回true,否则就false
let arr = [100, 200, 300, 400, 500];
let res = arr.every((item) => {
return item > 50
});
console.log(arr);//[100,200,300,400,500]
console.log(res);//true
21、数组去重的方法
var ary=[1,1,1,1,1,4,4,9,4]
function unique(ary){
for(var i=0;i<ary.length-1;i++){//制定比较的条件
var getItem=ary[i]//拿出每一项
for(var j=i+1;j<ary.length;j++){//依次比较,如有重复,就删除
if(getItem==ary[j]){
ary.splice(j,1);
j--;
}
}
}return ary;
}
var res=unique(ary);
console.log(res);
var ary=[1,2,3,1,1];
function unique(ary){
var newAry=[];//新数组
for(var i=0;i<ary.length;i++){
var getItem=ary[i];
//如果newAry没此项,再添加
//!newAry.includes(getItem)
if(newAry.includes(getItem)==false){
newAry.push(getItem)
}
}
return newAry; //newAry是私有变量,所以只能return
}
var res=unique(ary);//函数执行的返回结果,用新函数承接了一下,直接打印也可以console.log(unique(ary))
console.log(res);
22、对象去重
var ary=[1,2,1,3,1]
function unique(ary){
var obj={};
for(var i=0;i<ary.length;i++){
var item=ary[i];
//i=0索引 item=1
//判断obj中有没有item这个项
if(obj[item]==item){
ary.splice(i,1);
i--;
}else{
//如果对象中没有这样的属性名和属性值,
obj[item]=item;
}
}
return ary;
}
var res=unique(ary);
console.log(res);
23、求数组中最大一项
var ary=[20,100,30,50];
ary.sort(function(a,b){
return b-a;//降序
})[0]//第一项最大
----------------------------------------------
var ary=[20,100,30,50];
ary.sort(function(a,b){
return a-b;//升序
})[ary.length-1]//最后一项最大
---------------------------------------------
var ary=[20,100,30,50];
ary.sort(function(a,b){
return a-b;//升序
}).pop();//最后一项最大,删除最后一项,打印删除项
---------------------------------------------
var ary=[2,6,1,0];
Math.max(...ary);
--------------------------------------------
var ary=[20,100,40,30];
var res=Math.max.apply(null,ary);
console.log(res);
---------------------------------------------
var ary=[20,100,40,30];
for(var i=0;i<ary.length-1;i++){
if(ary[i]>ary[i+1]){
var temp=ary[i];
ary[i]=ary[i+1];
ary[i+1]=temp;
}
}
24、求平均数
//求平均数,去掉最高分和最低分,传递的个数不确定
function average(...arg){
var ary=arg.sort(function(a,b){
a-b;
})
ary.pop();//删除最后一项
ary.shift();//删除第一项
var total=0;
for(var i=0;i<ary.length;i++){
total+=ary[i];
}
return total/ary.length;
}
var res=average(1,2,8,10);
console.log(res);
------------------------------------------------------------
//求平均数,去掉最高分和最低分,传递的个数不确定
function average(...arg){
var ary=arg.sort(function(a,b){
a-b;
})
ary.pop();//删除最后一项
ary.shift();//删除第一项
return total=eval(ary.join("+"))/ary.length;
}
var res=average(1,2,8,10);
console.log(res);
------------------------------------------------------------
25、类数组转数组方法
1、
function fn(){
var res=Array.from(arguments);
console.log(res);
}
fn(1,2,3);
2、
function fn(){
var res=[...arguments];
console.log(res);
}
fn(1,2,3);
3、
function fn(...arguments){
var res=Array.prototype.slice.call(arguments)
console.log(res);
}
fn(1,2,3)
4、
function toArray(likeArray){
var newAry=[];//备一个新数组
for(var i=0;i<likeArray.length;i++){
newAry.push(likeArray[i])//把类数组一项一项给空数组放
}
return newAry;
}
function fn(){
var res= toArray(arguments);//调用这个方法
console.log(res);
}
fn(9,2,3);
26、数组拼接的方法有哪些
1、concat——var res=ary.concat(ary2,7);
2、Object.assign(obj,obj1);//把后边合并到前边里
3、apply——a.push.apply(a,b);——a.push.apply(a,[4,5,6]);——a.push(4,5,6);
23、字符串中常用的方法
注:按值操作,不修改原数据,str.length长度、str[0]第一个字符串、str[str.length-1]最后一个
1、charAt——获取索引对应的字符——参索引——返串
var str="zhangtao";
var res=str.charAt(0);
console.log(res);
2、charCcdeAt——获取索引对应的ASCII码值——参索引——返ASCII
var str="zhangtao";
var res=str.charCodeAt(0);
console.log(res);//122 十进制
3、slice(n,m)——从字符串中选索引n到索引m的数(不包m)——参数n,m——返选中的
var str="zhangtao";
console.log(str.slice(1,3));//ha
console.log(str.slice(1));;//hangtao-----不写m就查到最后
console.log(str.slice());//copy一份
console.log(str.slice(0));//copy一份
console.log(str.slice(-3,-1));;//ta-------转正str.length+负索引值
4、substring(n,m)——功能同上——唯一不同就是它不支持负数索引
5、substr(n,m)——从索引n开始(包n)截m个字符串——也支持负索引
var str="abcdefg";
var res=str.substr(0,4);//不传参就是返回普通字符串
console.log(res);//"abcd"
4、split("-")——字符串转数组(可按照指定分隔符分隔)——参数分隔符——返数组
var str="1-2-3"
var res=str.split("-");
console.log(res);//[ '1', '2', '3' ]
5、replace(x,y)——用y替换x——x可以是正则
var str="zhangtao";
var res=str.replace("zhang","替换了");
console.log(res);
6、IndexOf、lastIndexOf——判断某字符串第一次和最后一次出现的位置的索引
var str="zhangtao";
var res=str.lastIndexOf("a");
console.log(res);//6
//返回-1说明不包含,也可以用这个来判断是否包含
7、toUpperCase()——字符串转大写
8、toLowerCase()——字符串转小写
24、Math常用的方法(称为数学函数,是对象数据类型,用来操作数字的)
1、Math.abs(-2)——求绝对值——取正数
2、Math.floor()——向下取整——不管正负,取最小值
Math.floor(1.5)------1
Math.floor(-1.3)-------2
3、Math.ceil()——向上取整——不管正负,取最大值
Math.ceil(1.1)--------2
Math.ceil(-1.3)------- -1
4、Math.round()——四舍五入——正数正常——负数想进1,必须比5大一点点
Math.round(1.5)------2
Math.round(-1.1)---------1
Math.round(-1.5)-------- -1
Math.round(-1.51)-------- -2
5、Math.random()——0-1之间随机小数
获取n-m之间的随机小数——Math.random()*(m-n)+n
获取10-20之间随机小数——Math.random()*(20-10)*+10
6、Math.max(1,2,3);——最大值
7、Math.min(1,2,3);//最小值
8、Math.sqrt(9);——9的开平方
9、Math.pow(2,3);——2的三次幂
10、Math.PI();——3.1415926
25、三元运算符
条件?成立执行:不成立执行(如果是单独一个值,先把它转为布尔,真条件成立,假不成立)
举例:num>0?(num<10?num++:num--):(num==0?(num++,num/10):null)
//无else可以用null、undefined、void 0做占位符
26、if语句——判断成绩——(if中是==比较)——先转为相同类型,再比较
<script>
var score = +prompt("请输入您的分数");
if (score > 100) {
alert("不是合法的分数");
} else if (score >= 90) {
alert("优秀");
} else if (score >= 80) {
alert("良好");
} else if (score >= 60) {
alert("及格");
} else if (score >= 0) {
alert("不及格");
} else {
alert("不是合法的分数");
}
27、switch case语句——判断成绩——(switch中是===比较)——类型和值都必须相等
把switch括号中的表达式与每个case作对比,如果匹配,则往下执行,到break为止,否则执默
<script>
var score=parseInt(prompt('请输入你的成绩'));
switch(true){
case score>=0&&score<60:
alert('不及格');
break;
case score>=60&&score<=70:
alert('及格');
break;
case score>70&&score<=80:
alert('良好');
break
case score>80&&score<=90:
alert('优秀');
break;
case score>90&&score<=100:
alert('太棒了');
break;
default:
alert('输入不合法');
}
</script>
28、while与do while
1、while循环——只要条件成立,就会一直走循环体里的语句
var num=1;
while(num>0&&num<5){
num++;
}
console.log(num);//5
2、do while循环——无论条件是否成立,一上来就会执行一次循环体里的语句
var num = 12;
do{
num++;
}while(num<9);
console.log(num);//13
29、关于for的_for in _打印奇偶项_1-10_1-100求和_任意数求和......
1、当我们按照某种规律去做某事时候,用for循环
for(var i=0;i<ary.length;i++){
循环体
}; //只要条件成立,就执行循环体中内容,不满足条件时,就停止
2、for in 循环
<script>
var obj={"name":"lili",age:19};
for(var key in obj){
console.log(key);//获取属性名
console.log(obj[key]);//获取属性值
}
</script>
3、用for循环打印数组中的每一项
var ary=[1,3,4,5,6];
for(var i=0;i<ary.length;i++){
console.log(ary[i]) //1,3,4,5,6
}
4、用for循环倒着打印数组每一项
var ary=[1,3,4,5,6];
for(var i=ary.length-1;i>=0;i--){
console.log(ary[i]) //6,5,4,3,1
}
5、打印奇数项
var ary=[1,2,3,4,5,6,7,8,9,10];
for(var i=0;i<ary.length;i++){
if(i%2==0) //此时说明索引数偶数项,但是内容恰好是奇数
console.log(ary[i]) //1,3,5,7,9
}
6、打印偶数项
var ary=[1,2,3,4,5,6,7,8,9,10];
for(var i=0;i<ary.length;i++){
if(i%2!=0)
console.log(ary[i]) //2,4,6,8,10
}
7、for循环打印1-10
for(i=1;i<=10;i++){
console.log(i);
}
8、for循环实现1-100求和
function total(x,y){
var res=1;
for(var i=2;i<=100;i++){
res+=i;
}
return res;
}
console.log(total(1,100));
var res=0;
for(var i=0;i<=100;i++){
res=res+i;
}
console.log(res);
9、求1-100中同时能被2,又能被3整除的所有数量之和
var total=null;
for(var i=1;i<=100;i++){
if(i%2==0&&i%3==0){
total+=i;
}
}
console.log(total);
10、任意数求和,包含非有效数字
function total(){
var num=arguments.length;//任意不知道长度求和
var res=0;//备一个空字符串
for(var i=0;i<num;i++){
var result=Number(arguments[i]);//result承接每一个数,给它转成数字
if(!isNaN(result)){//不是数字就没法相加
res=res+result;
}
}
return res;
}
console.log(total(1,2,3,"12px"));
11、++i与i++
//++a是先自身累加,再赋给b
var a=1;
var b=++a;
console.log(a,b);//2 2
//a++是先赋给b,再自身累加
var a=1;
var b=a++;
console.log(a,b);//2 1
12、countinue:结束本轮循环,继续从头进行下一轮循环
13、break:结束整个循环,不再循环
30、函数——种类——角色——求和......
1、函数:有形参和实参(执行传入),接收参数的两种形式:形参接收、arguments接收
<script>
function fn(name,age){
console.log(arguments.length);
console.log(arguments);
}
var res=fn({"name":"lili",age:18})
</script>
2、函数(实名、匿名、自执行、箭头)
function fn(){}//实名函数
var f1=function(){}//匿名函数
btn.onclick=function(){}//匿名函数
(function(){
console.log(1)
})();//自执行函数
~function(){
console.log(2)
}();//自执行函数,开头写~、+、-、!都可以
var fn=function(x,y){}//以下都是基于这个的箭头函数
var fn=(x,y)=>{}
var fn=x=>{}
3、函数的三种角色
1、普通函数:fn(1,2)-------this是window
2、构造函数:var f1=new Fn(1,2)-----this是当前实例
3、对象:Fn.age=100;------它是函数中的一个实例,所以也是对象
4、两数求和
<script>
function total(x,y){
return x+y;
}
console.log(total(2,2));
</script>
5、求和,不知道传的个数
<script>
function total(){
var res=0;
for(var i=0;i<arguments.length;i++){
res=res+arguments[i]
}
return res;
}
console.log(total(1,2,3));//6
</script>
6、求和,遇到非有效数字
<script>
function total(){
var res=0;
for(var i=0;i<arguments.length;i++){
var item=Number(arguments[i]);//先转成数字类型
if(!isNaN(item)){//如果不是是非有效数字,才相加
res=res+arguments[i]
}
}
return res;
}
console.log(total(1,2,3,"12px"));//6
</script>
7、什么是变量提升
在“当前上下文”中(函数执行形成的私有作用域就是上下文),代码执行之前,浏览器首先会把所有带var和function关键字的内容进行提前声明或者定义,最后代码自上而下执行。
1、 带var的:提前声明
2、带function的:声明+定义(赋值)都完成了(但是在if中就和var一样,不定义)
3、let、const、import、class声明的变量不存在变量提升
31、js操作dom的方法
var res=document.getElementById("box");
var lis=document.getElementsByTagName("li");//通过标li签获取一组数
var ul=document.getElementById("ul");
var lis=ul.getElementsByTagName("li");//也可以这样获取一组数
var div=document.getElementsByClassName("box");//通过类名获取一组元素
var input=document.getElementsByName("username");//通过name名获取一组表单元素
document.querySelector(".main>li");//获取main下第一个li
document.querySelectorAll(".main>li");//获取main下的全部li
document.head
document.body
document.documentElement;//获取整个html文档
var w=document.documentElement.clientWidth||document.body.clientWidth;//获取一屏幕的宽度
var h=document.documentElement.clientHeight||document.body.clientHeight;//获取一屏幕的高度
32、获取某个节点方法
box.parentNode;//获取某个节点的父节点,也相当于父元素
main.childNodes;//获取当前节点下面所有的子节点
oul.childNodes;//获取oul下面的子节点
oul.children;//获取当前节点下面所有的子元素(li)ie6-ie8不兼容
box.previousSibling;//获取当前节点的哥哥节点(向上的)
box.previousElementSibling;//获取当前节点的哥哥元素节点(ie6-ie8不兼容)
h1.nextSibling.nextSibling;//获取当前节点的弟弟节点(向下的)
h1.nextElementSibling;//获取向下的兄弟元素(ie6-ie8不兼容)
main.firstChild;//获取当前及节点下面的子节点
main.firstElementChild;//获取当前及节点下面的子元素(ie6-ie8不兼容)
main.lastChild;//获取当前及节点下面的最后一个子节点
main.lastElementChild;//获取当前及节点下面的最后一个子元素(ie6-ie8不兼容)
33、dom的增删改查
<body>
<div id="main">
<h1>h1</h1>
</div>
</body>
</html>
<script>
var oh1=documnet.createElement("h1"); //创建一个元素
var otext=document.createTextNode("哈哈");//创建一个文本节点
oh1.appendChild(otext);//容器.appendChild(节点);节点放到容器的里面
document.body.appendChild(oh1);
main.inserBefore(h2,h1);//把h1插入到h2前面
main.cloneNode();//浅克隆,单纯的值克隆了一层
main.cloneNode(true);//深克隆,把里面所有结构都克隆
//一组搭配:把属性名和属性值添加到了dom结构上,不能与第二种方法混用
main.setAttribute("index",0)//给元素添加属性
main.getAttribute("index")//获取特定属性对应的属性值
main.removeAttribute("index")//删除属性
//添加属性名和属性值的第二种方法,添加到堆内存中了,可以通过console.dir(某个元素),详细输出一下,就可以看到其属性名和属性值了。
main["index"]=100;
main.index=100;
//获取
main["index"]
main.index;
//删除
delete main["index"];
delete main.index;
</script>
34、dom的回流和重绘——回流一定引起重绘,但重绘不一定回流
// DOM的回流:当页面中删除一个元素、改变一个元素的大小、移动一个元素时,其他元素的位置要进行重新的计算,那这个过程是非常消耗性能的;这种现象就是DOM的回流
// DOM的重绘:当元素的样式、背景。字体颜色、透明度等属性发生变化时,不会引起元素位置的变化,但是浏览器要重新描绘这个元素,这就是DOM的重绘
35、获取最新日期时间案例
36、倒计时案例
37、开关灯小案例
js实现开关灯案例_一只蓝胖子~的博客-优快云博客_js开关灯案例
38、隔行换色小案例
39、选项卡小案例
40、for循环、while实现四位无重验证码
for和while实现无重复四位验证码_一只蓝胖子~的博客-优快云博客
41、url问号传参处理小案例
//问号后边的参数变成对象,用的时候比较方便,直接obj.name
var str ="https://www.baidu.com?name=zhangtao&age=10&id=14";
function getParams(str) {//从str上获取参数属性
var obj={};//创一个新对象
var params=str.split("?")[1];//以?分隔,拿到索引为1的,也就是name=zhangtao&age=10&id=14
if(params){
var paramsAary=params.split("&"); //拿到后边的,再以&分隔
for(var i=0;i<paramsAary.length;i++){
var item=paramsAary[i]; //循环拿到每一个被分隔后的键值对
var key=item.split("=")[0]; //用=分隔,拿到键
var value=item.split("=")[1]; //用=分隔,拿到值
obj[key]=value; //把键值对放进obj里
}
return obj;
}
}
var res=getParams(str);
console.log(res.age)
console.log(res.name)
42、冒泡排序小案例
var ary=[8,2,1,5];
//轮数
for(var i=0;i<ary.length-1;i++){
//两两进行比较
for(var j=0;j<ary.length-1-i;j++){//i代表轮数
//如果前者比后者大,就交换顺序
if(ary[j]>ary[j+1]){
var temp=ary[j];//存着
ary[j]=ary[j+1];
ary[j+1]=temp;
}
}
}
console.log(ary);//[1,2,5,8]
43、选择排序
function selectSort(arr){
var minIndex = 0;
for(var i=0; i<arr.length; i++){
minIndex = i;
for(var j=i; j<arr.length; j++){
if(arr[j] < arr[minIndex]){//首先从未排序序列中选出最小值的元素,放到数组起始位置,
minIndex = j;
}
}
var temp = arr[i];//然后从剩下未排序序列中继续寻找找最小值,放到已排序序列末尾
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
return arr;
}
var arr = [3,5,4,1,2];
console.log(selectSort(arr)); // [1,2,3,4,5]
44、原型继承:B既然想用A的私有的,也想用公有的,更改原型指向,指向要用的A
让类B的原型指向类A的实例,那么以后类B的实例既可以调取类A实例的私有属性,也可以调取类A原型上的公有属性,那这种继承方式就是原型继承,不能应用于内置类
// 原型继承目的:通过类B的实例去调用类A实例的私有属性和公有属性
function A() {
this.getX = function () { console.log('恭喜发财') }
};
A.prototype.getY = function () {
console.log('贾世豪,我是你的韬妮呀')
};
function B() { }
B.prototype = new A;//核心
let f = new B; // 创建一个类B的实例
f.getX();
f.getY();
45、中间类继承:某实例不属于某类,但想用其原型上的方法,可手动更改实例的_proto_
let obj = {};
obj.__proto__ = Array.prototype;//核心
obj.push(800); //1
46、call继承:B不仅要用自己私有的,还要用A私有的
<script>
function A(){
this.x = 100;
this.y = 200;
}
function B(){
// this-->f
this.d = 300;
A.call(this); // call会让A函数以普通函数的身份运行,并且把A函数的this指向了类B的实例
// 不仅要有B私有,还要有A私有的
}
let b = new B; // {d:300,x:100,y:200}
console.log(b);
</script>
47、寄生组合继承:B想用A公有的,把B原型指向一个空对象,空对象的_proto_指向A原型
<script>
function A(){
this.x = 100
};
A.prototype.ss = 200;
function B(){
A.call(this); // 只能继承私有的属性
}
B.prototype = Object.create(A.prototype);// 创建一个新对象,并且这个新对象的__proto__会指向create函数的第一个实参
console.log( B.prototype.ss);//200
</script>
48、call、apply、bind
都是Function原型上的方法,函数和object基类可调用(object中对象不行)——call、apply、bind都是改变this指向的方法
1、call——fn.call(obj,1,2,3)// 改变fn中的this,并且把fn立即执行
① 首先把要操作的函数中的this关键字变为call
方法第一个传递的实参,并且把第二个以后传递进来的实参传递给函数
②非严格模式,如果不传参数,或者第一个参数是null
或nudefined
,this
都指向window
let fn = function(a,b){
console.log(this,a,b);
}
let obj = {name:"obj"};
fn.call(obj,1,2); // this:obj a:1 b:2
fn.call(1,2); // this:1 a:2 b:undefined
fn.call(); // this:window a:undefined b:undefined
fn.call(null); // this=window a=undefined b=undefined
fn.call(undefined); // this=window a=undefined b=undefined
③严格模式,第一个参数是谁,this就指向谁,包括null和undefined,如果不传参数this就是undefined
"use strict"
let fn = function(a,b){
console.log(this,a,b);
}
let obj = {name:"obj"};
fn.call(obj,1,2); // this:obj a:1 b:2
fn.call(1,2); // this:1 a:2 b=undefined
fn.call(); // this:undefined a:undefined b:undefined
fn.call(null); // this:null a:undefined b:undefined
fn.call(undefined); // this:undefined a:undefined b:undefined
2、apply——fn.apply(obj, [1, 2,3]);——区别call传参方式是数组了
3、bind——fn.bind(obj, 1, 2); // 改变fn中的this,fn并不执行,预处理更改this
49、正则相关知识点
正则的用法(js中数据类型之一)_一只蓝胖子~的博客-优快云博客_js 身份证校验
50、js的13个盒子模型
clientWidth——无边框的宽
clientHeight——无边框的高
clientLeft——左边框
clientTop——上边框
offsetWidth——有边框的宽
offetHeight——有边框的高
offsetLeft——左偏移量(当前左外距离父级参照物左内的宽)
offsetTop——上偏移量(当前上外距离父级参照物上内的高)
offsetParent——计算偏移量的父级参照物
scrollWidth——不溢出=无边框的宽,溢出=内容真实宽
scrollHeight——不溢出=无边框的高,溢出=内容真实高
scrollLeft——当前滚动条 横向卷曲 的宽度
scrollTop——当前滚动条 纵向卷曲 的高度
51、函数的防抖和节流
1、防抖:在触发某方法执行的时候,在规定的时间之内,只让他触发一次,如果在规定的时间之内用户再次触发该事件,那就会重新计时
设计思路:在setTimeout中调用事件处理函数,如果在定时器触发函数执行之前又触发函数,清除定时器。
function debounce(fn, timeout){
timeout = timeout || 1000;
let timer;
return () => {
if(timer){ clearTimeout(timer)}
timer = setTimeout(() => {
fn()
},timeout)
}
}
function printEvent(){
console.log('1121212')
}
window.addEventListener('scroll',debounce(printEvent,1000),false)
2、节流:稀释函数执行的频率,并不是让函数只触发一次,在规定的时间之内触发一次,如果滑动超过了规定的时间就可以再次连续触发
定时器实现模式:定时器在延时时间执行过后,重置为null, 定时器为null时,重新设置定时器,如此循环
//节流函数
function throttle(fn, range){
range = range || 1000;
let timer;
return () => {
//console.log(111,typeof timer)
if(!timer){
timer = setTimeout( () => {
fn()
timer = null
},range)
}
}
}
window.addEventListener('mousemove',throttle(printEvent,1000),false)
比如在页面的无限加载场景下,我们需要用户在滚动页面时,每隔一段时间发一次 Ajax 请求,而不是在用户停下滚动页面操作时才去请求数据。这样的场景,就适合用节流技术来实现。、
52、定时器清除的方法:clearTimeout(obj)和clearInterval(obj) 且timer = null;
53、手写轮播图
在我的内容可以查找
54、鼠标跟随
55、京东放大镜
56、鼠标点击拖拽
57、鼠标点击拖拽2
58、树形层叠菜单举例
59、媒体查询
<style>
#box{
width: 200px;
height: 200px;
background: orangered;
}
/* @media screen and (min-width: 400px) {
如果屏幕尺寸大于400就会执行此处的样式
#box {
background: green;
}
}
@media screen and (min-width: 600px) {
// 如果屏幕的只存大于600px就会执行此处的样式
#box {
background: yellow;
}
} */
/* @media all and (max-width:600px) and (min-width:200px) {
如果屏幕的尺寸大于200或者小于600就可以执行此处的样式
#box {
background: violet;
}
}*/
</style>
</head>
<body>
<div id="box"></div>
<script>
// 媒体查询
</script>
60、rem核心代码
<script>
function resize(){
let winW = document.documentElement.clientWidth;
let res = 100*winW/750;
document.documentElement.style.fontSize = res + 'px';
}
window.onresize = resize;
resize()
</script>
61、音乐播放条
音乐播放条(放入音乐即可听)_一只蓝胖子~的博客-优快云博客
Vue方面:
1、搭建vue框架所需要的步骤
2、vue指令
1、v-html 页面渲染,可以识别字符串标签,输出原样html页面
2、v-text 页面渲染,不能识别字符串标签,(加上它,花胡子不会闪,自上而下机制,操作纯文本 {{}} )
3、v-on (简写@)给元素绑定事件
4、v-for 循环数组、对象、数字,优先级高于v-if
<div v-for="(item, index) in items" :key="index"></div>(数组每一项,每一项索引)
<div v-for="(val, key) in object"></div>——(属性值,属性名)
5、v-bind (简写:)给标签普通行间属性动态取值,属性名也可以动态获取
6、v-else
<div v-if="type === 'A'"> A </div>
<div v-else-if="type === 'B'"> B </div>
<div v-else-if="type === 'C'"> C </div>
<div v-else> Not A/B/C </div>
7、v-else-if
8、v-if 控制元素的显示隐藏,操作dom结构,适合页面加载时候显示与否
9、v-show 控制元素显示隐藏,操作display:none,适合频繁切换场景使用
10、v-model 视图与数据的双向绑定,仅适用于表单元素
11、v-slot 插槽(后边详细再列举)
12、v-once 只渲染元素和组件一次
13、v-pre 跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。
14、v-cloak 可以隐藏未编译的 {{}} 标签直到实例准备完毕
3、vue中的事件修饰符
.stop
<!-- 阻止事件冒泡传播机制 --> <a @click.stop="doThis"></a>
.prevent
<!-- 阻止事件的默认行为 --> <form @:submit.prevent="onSubmit"></form>
.capture
<!-- 控制事件在捕获阶段执行--><div @click.capture="doThis">...</div>
.self
<!--只有点击自己的时候才能出发,不能通过冒泡捕获等触发-->
<div v-on:click.self="doThat">...</div>
.once
只触发一次方法(不会阻止事件冒泡)
.passive
passive就是为了告诉浏览器,不用查询了,我们没用preventDefault阻止默认动作
passive和prevent冲突,不能同时绑定在一个监听器上。
补充
<!-- 修饰符可以串联 --> <a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 --> <form v-on:submit.prevent></form>
使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。
因此,用 v-on:click.prevent.self
会阻止所有的点击,
而 v-on:click.self.prevent
只会阻止对元素自身的点击。
4、键盘事件修饰符(keyCode)
<input type="password" v-model="pwd" @keyup.enter="handleSubmit"/>
enter 回车键
tab 制表键
delete 删除键delete\backspace
esc 返回键
up 向上键
down 向下键
left 向左键
right 向右键
4、vue中class与style的使用
vue中class与style的绑定_一只蓝胖子~的博客-优快云博客
5、vue的双向数据绑定原理
1、Object.defineProperty(操作的对象,属性名,属性描述符)对数据进行劫持,说着说重新定义的对象的get和set,后加进来的没有响应式,因为没有get和set
2、Object.defineProperty(data, key, {//设置的时候进行数据劫持,执行set,把数据修改了
get() {
return val
},
set(newVal) {
val = newVal
}
});
3、vue3使用的是proxy代理实现的:优点
1、可以省去for in、闭包等内容来提升效率,因为defineProperty只能监听某个属性,不能监听整个对象,而proxy可以直接绑定整个对象
2、也不用再去单独对数组做特异性操作,因为vue3可以监听到数组内部数据的变化
6、vue的构成
let app=new Vue({
el:"#app",
data(){//用函数,因为组件是可复用的,若写对象,则所有组件将引用同一份数据,而函数的是由自己独立的空间地址,不会数据错乱
return{//不写return的数据,就全局可见,会变量污染,加了return,数据就只在当前组件可用
name:"lii"
} },
props:{//接收父组件传过来的属性,挂到当前实例上,可以是 [ ]、{ }、值
},
methods:{//methods每一次更新视图都更新,return可有可无,写方法的
},
computed:{//计算属性,依赖data中数据变化而变化,有缓存,有return,不可异步
ss(){//之所以有这个计算属性,是因为都写在methods中耗费性能
return this.num/7;//返回计算结果,多个数据对应data中一个数据
}
},
watch:{//监t听vue实例上属性变化而执行的函数,无reurn,可以写异步
data:{
handler(newVal){
this.change_number++
},
deep:true,//深度监听。所有属性都加上监听器,其中一个变了,就执行某个函数
immediate:true;//true首次加载就监听数据变化,false,发生变化才监听
}
num(){
this.msg=this.num/7;//num变化,就执行这个函数,一个监听多个
}
}
}
7、模板字符串的使用
8、filter过滤器的使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<!-- |是管道符,符号左边的值会自动传递给右边函数的第一个实参 -->
<!-- 管道符只能配合filters里边的方法使用 -->
<p>{{num | toFixed(5)}}</p>
<p>{{num | toFixed(2) | addZero()}}</p>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let app=new Vue({
el:"#app",
data:{
num:3.1415926,
},
filters:{//过滤
toFixed(num,n){//保留小数
return num.toFixed(n);
},
addZero(num){//判断够不够10位,不够补0
num=Number(num);
return num<10?'0'+num:num;
}
/* data、methods、filters、里边的方法不要重名 */
},
})
</script>
</body>
</html>
9、methods、computed、watch的区别
1、methods: {}
此函数每一更新视图ta都会更新
没有缓存
2、computed:{}
依赖data的某个数据变化而变化
有缓存的
不能写异步,有return
多对一
3、watch:{}
watch是监听vue实例上的属性的变化而执行的函数
可以写异步,因为没有return
一对多
10、混入(一种非常灵活的方式,来分发 Vue 组件中的可复用功能)
1、全局混入: Vue.mixin({},//里边可以写data,methods,钩子函数...
同名的属性、方法如果有就混不进去
钩子函数可以,先执行混入,后执行自己的
2、局部混入: mixins:[obj,obj2], // 局部混入,他只会在你指定的组件中生效
12、生命周期函数
实例初始化之前,数据没加载,页面没显示,做loading请求加载的过程
实例初始化完成,只请求到了数据、事件、属性,但是还没加载页面
可以更改data,不会引发视图的再次更新
可发数据请求,不操作dom的话
生成的dom模板挂载到真实dom之前
可以改data,因为还没挂载完成
dom模板挂载到真实dom上了,页面正常显示
改data会引发视图的再次更新
可发数据请求,可以获取到渲染之后的dom
------------------------以上四个,在第一次初始化的时候执行,以后不再执行--------------------------------
更改响应式数据之前
更改响应式数据完成,视图渲染完成之后执行,初次渲染时,这两个不执行
使用keep-alive做缓存的组件激活时候调用
使用keep-alive做缓存的组件停用时候调用
销毁实例之前
实例销毁,一旦调用,vue实例就不能用了,无响应是了,死页面了
当捕获一个来自子孙组件的错误时被调用
此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串
此钩子可以返回 false
以阻止该错误继续向上传播。
补充1:
组件的加载顺序:父beforeCreate=>父created=>父beforeMount=>渲染父组件render,遇到了调用子组件=》子beforeCreate=>自create=>子beforeMount=>子组件渲染=》子mounted=>子组件第一次渲染完成=》父mounted
父组件更新数据,重新渲染:父beforeUpdate=>父render=>子beforeUpdate=>子render=>子updated=>父updated
总结:
父beforeCreate--父Created--父beforeMount--子beforeCreate--子created--子beforeMount--子mounted--父mounted
父beforeUpdate--子beforeUpdate--子updated--父updated
补充2:
<keep-alive :include=['a','b']></keep-alive>//控制让a,b组件缓存
<keep-alive :excluce=['a','b']></keep-alive>//不让让a,b组件缓存
<keep-alive :max="10"></keep-alive>//控制最大的缓存数是10
12、局部组件与全局组件
1、全局组件:
1、全局组件必须写在Vue实例创建之前,才在该根元素下面生效;
2、每个组件都有自己的样式、结构、逻辑、data、methods、生命周期
Vue.component('com1',{
data(){
return{
num:100
msg:"我是com1全局组件"
}}
})
2、局部组件:
局部组件的使用方式
1、创建组件
2、注册组件(在哪里用就在哪里注册,下边注册必须用小写,可以加——)
3、使用组件,不能和原生重名
4、根组件可以没有,局部组件必须有
let com2={
data(){
return{
num:100;
}}
}
component:{
com2:com2
}
13、组件之间的传参
注意
1、父子之间的通信,不管是状态还是方法,都写在父组件身上,子组件想改父组件身上的方法,可以订阅,父组件想更改子组件中的数据,可以通过prop属性
2、父组件data中后加的数组有get和set,可以直接this.arr=去修改,但是里边的内容没有,所以可以用那给定的七个数组方法去子改后加的data数据
3、父组件data后加的对象有get和set,对象中的数也有get和set,因为对象会深度劫持
4、父组件中this.person.name = 'ljx' //通过直接添加person对象是无法添加,但是我们可以在methods方法中写this.$set(this.person,'name','ljx')添加,相当于this.$set(object,key,value),添加多个属性和方法,this.person = Object.assign({},this.person,{ age:55, height:1.99 })
5、且因为data中的数据都已经做过数据劫持了,有get和set,以后父组件里methods中方法去修改data中数据的时候,其他组件也会一起更新,这涉及到了vue生命周期的执行顺序,执行父亲update时候,会把子组件的updata也更新了,才渲染上去
1、父传子:prop属性
此时父亲的数据状态改了,其他main子组件中必须也得改,那就需要父传子了,可以在父组件中写<vote-main :supNum="supNum" :oppNum="oppNum"></vote-main>,然后去子组件main中写,下边这段代码利用props接收,接收的是:后边的属性,因为是父组件传过来的,没有get和set,是只读的,若想更改,可以在子组件中1、把父组件传过来的数据放到子组件自己的data中,以后直接修改自己data,就可以实现自改父,2、父组件盗用子组件的时候传递不同的值也可以,3、对父组件传过来的值进行监听
2、子改父:$on $emit(eventBus)---原理:发布订阅
就拿上边图举例子,点击子组件中按钮,想触发父组件中的change方法,我们需要在父组件Vote中写 <vote-footer @AAA="change"></vote-footer>,相当于给footer子组件定义了一个事件池子,把change方法订阅进去,之后再利用去footer子组件中写一个@click事件,绑一个函数,一点击就执行这个函数,里边写this.$emit('AAA',type);去发布这个事件池子,type是我点击时候传递的参数,这样就间接实现了子改父,那以后子组件上的按钮,一点就通过type参数去发布父组件上的方法,父组件就可以随着子组件变化了
3、兄弟组件:eventBus,
兄弟组件传参的话,比如A想触发兄弟B中的方法,可以创建一个eventBus.js文件,在B中<vote-footer @AAA="change"></vote-footer>,然后利用$on把写好的事件订阅到一个事件池子中,然后去A中利用this.$emit去发布这个事件池子,后边跟的是传递给B的参数
4、其他传参方法
1、$parent、$children
动态传值传过来后,
this.$parent.num=100;
this.$children.num=200;
2、ref、$refs
子组件或者dom元素行间写ref=""
那在他的父组件和兄弟组件中就都可以利用$refs去获取那个组件身上的属性了
下边是举例子:
在组件行间或者dom元素行间写上ref="xxx",那么在他们共同的父亲实例身上的$refs属性里就可以快速获取到当前有ref的组件或者dom元素
在vue里利用ref和$refs可以快速获取到原生的dom元素
<body>
<div id="app">
<div ref ='a'>100</div>---------------
<com ref='b'></com>-------------
<com1 ref="c"></com1>-----------------
</div>
<script>
const com = {
data(){
return {
num:100
}
},
methods:{
fn(){
console.log('我想改com1的东西');
this.$parent.$refs.c.num = 800;--------------------
}
},
template:`<div>{{num}}<button @click="fn">点击</button>-------</div>`
}
const com1 = {
data(){
return {
num:200--------------------------------
}
},
template:`<div>{{num}}com1</div>`
}
const vm = new Vue({
el: '#app',
data: {},
methods: {},
components:{
com,com1
}
});
</script>
</body>
3、父组件provide 子组件inject,
provide里边放基本值没有响应式,想让provide中的值加上响应式,那就把data中的某一个响应式的对象放到provide中
14、插槽
1、普通插槽与具名插槽:在子组件标签中间如何添加内容
//我是父组件
<template>
<div class="hei">
我是父组件divdivdivdividividviidvdvidv中中中<br>
<zi>普通插槽加入的话<br><!--普通插槽:只要子组件div中写一个<slot>/slot>就行-->
<template v-slot:header><!-- 具名插槽:父加v-slot,子加name,两个名字对应上 -->
具名插槽header
</template> <br>
<template v-slot:container><!-- 具名插槽:父加v-slot,子加name,两个名字对应上 -->
具名插槽container
</template>
</zi>
</div>
</template>
//我是子组件
<template>
<div class="heihei">我是子组件divdivdivdivdividvidvdivdiv中中中<br>
<slot>如果父组件中,子组件标签什么也不写,就显示这个默认内容</slot><br>
<slot name="header">如果不给name或者找不到匹配name,就显示这个默认内容</slot><br><!-- 具名插槽 -->
<slot name="container"></slot><!-- 具名插槽 -->
</div>
</template>
2、作用域插槽方法1——利用具名插槽接收子组件的数据
父组件想用子组件data数据,不能直接用,所以可以通过作用域插槽,在子组件slot行间给它动态传值写 :user="user",然后让父组件中v-slot具名插槽的名字后边用=接收过来,就可以拿到了
//我是父组件
<template>
<div class="hei">
<zi>
<template v-slot:container="abc"><!-- 作用域插槽 -->
作用域插槽container
{{abc}}
{{abc.aaa.a}}
{{abc.bbb.name}}
</template>
</zi>
</div>
</template>
//我是子组件
<template>
<div class="heihei">
<slot name="container" :aaa="user" :bbb="name"></slot><!-- 作用域插槽 -->
</div>
</template>
<script>
export default {
data() {
return {
user:{
a:1,
b:2
},
name:"zhangtao"
} },}
</script>
3、作用域插槽方法2——利用slot-scope接收子组件的数据
//我是父组件
<template>
<div class="hei">
<zi>
<template slot-scope="slotProps"><!-- 作用域插槽 -->
{{slotProps.aaa}}
</template>
</zi>
</div>
</template>
//我是子组件
<template>
<div class="heihei">
<slot :aaa="user">32432</slot><!-- 作用域插槽 -->
</div>
</template>
<script>
export default {
data() {
return {
user:{
a:1,
b:2
},
} },}
</script>
15、vuex——管理公共状态的一种工具——放在这里的数据会自动加getter和setter
1、作用:把公共状态抽离出来,并且每个组件都可以使用它,而且还可以更改它,既然是公共的额,当其中任意一个组件把这个公共状态改了之后,凡是依赖这个公共状态的组件都会得到更新。
2、特点: ①vuex存储是响应式的(store中状态变了,相应组件也会变)
②不能直接更改store中的状态,想改它的唯一途径就是提交mutations
Vue.use(Vuex)
let store = new Vuex.Store({
state:{},//状态,子组件能通过this.$store.state访问到状态
getters:{},//相当于computed,也可认为是store中的计算属性,可以store.getters.num
mutations:{},//写更改state中状态的方法,不支持异步,因为mutation会记录状态,如果你用了定时器,记录的值与定时器后的值不一样了就
actions:{},//写commit来提交mutations,支持异步
modules:{}//每一个小store
})
用法:
dispatch分发actions中的方法
actions中写commit,由commit来提交mutation中的方法
mutation最终来修改state中的状态
export default store;
// mapState可以快速把state的状态存储到当前组件的计算属性中,他的返回值是一个对象,对象里存储的就是mapState执行时传递的数组中对应的计算状态,若用了命名空间,需要看下边第一条
methods: {
...mapMutations('mytodo',['changeCount']),
...mapMutations(['changeCount']),
...mapActions(['changeColorAsync']),
---------------------------------------------------上边代替下边
add(){//在这里触发mutation中函数,从而实现兄弟改值
this.$store.commit('changeCount',10);
},
color(){
this.$store.dispatch('changeColorAsync',1,2,3)
}
----------------------------------------------------------------------------------
computed:{
// type(){//函数行写在上边花胡子里边
// return this.$store.getters.type
// },
// count(){
// return this.$store.state.count;
// }
//若不想用count,想重新起名,也想处理数据,可以如下方式
...mapState({
mycount:'count',
mycount2:function(state){
return state.count+100;
}
}),
...mapGetters(['type'])
},
16、vuex刷新数据会丢失怎么办
原因:因为vuex里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载vue实例,vuex里面的数据就会被重新赋值。
解決:将vuex中的数据直接保存到浏览器缓存中(sessionStorage、localStorage、cookie)
在页面刷新的时候再次请求远程数据,使之动态更新vuex数据,我选择的是sessionStorage,原因是由于vue是单页面,是在一个页面跳转路由,另一个原因是sessionStorage可以保证打开页面时sessionStorage的数据为空,而如果是localStorage则会读取上一次打开页面的数据。
17、vueRouter
1、路由的两种模式
hash: 不美观
有长度限制
更改页面不刷新,但它会触发hashchange事件,可监听hashchange实现页面刷新
history:无长度限制,可存对象,可读取历史记录
this.$router.back()回到上一页,
this.$router.forward()前进一页,
this.$router.go(1)前进一页
this.$router.go(-1)后退一页
this.$router.replace()跳转到指定URL,替换history栈中最后一个记录,点击后退会返回至上上一个页面
this,$router.push旧的新的记录都有
刷新时,如果服务器中没有相应的响应或者资源,可能会出现404
2、路由的跳转方式
声明式
<router-link :to="{name:'home'}">
<router-link :to="{path:'/home'}"> //name,path都行, 建议用name
// 链接如果是'/'开始就是从根路由开始,如果开始不带'/',则从当前路由开始。
编程式
this.$router.push('/b')
3、组件传参的两种方式
query:配合path来使用,参数会会显示在hash上,不美观,不安全
parmas:配合name来使用,美观,安全,无长度限制,但是刷新数据会丢失,location本地
//$route:接收路由跳转信息的
//$router:跳转的方式用
18、vue3
18、你封装过什么插件?
1、轮播图
19、封装插件需要考虑什么因素?
1、复用性
20、单页面和多页面
1、单页面:切换快、首屏慢、seo差(因为一个html)、组件切换、开发便捷、局部刷新
2、多页面:切换慢、首屏块、seo好、重复代码多、整页刷新
21、简单的linux命令
ls----查看当前所有的目录
22、Vue中的style怎么区分公共私有使用地方
1、在大App.vue中我们一般写公共样式,比如所有页面的公用框架、所有页面的公用字体样式等等,直接<style lang="less"></style>
2、在小组件中我们一般写私有样式,别的地方可能用不到,<style lang="less" scoped></style>,加上scoped后他会给它自动添加一个私有类名
23、vue的单向数据流理解
1、父组件调用子组件的时候,可以把一些信息基于属性prop传递给子组件,反之子组件是无法基于属性把信息传递给父组件的,但是可以基于$emit触发父组件方法
2、还可以参考上边生命周期加载顺序(一种深度遍历优先原则)
3、问题:一个父组件包着一个子组件,从服务器获取数据的时候,好多人会写在子组件的created里,但是created只在第一次渲染的时候执行,以后把父组件的数据更新了,而子组件的数据没变是为什呢,因为父组件重新更新,子组件走的也是重新更新,而不是第一次渲染,所以created也不执行,数据只在第一次渲染的时候执行,以后就不执行了
解决:1、v-if第一次渲染了,之后把我把它改成false,就释放了,以后再为true时候,又重新渲染了(相当于走第一次的逻辑)
2、watch监听,只要父组件调用子组件,父组件渲染,每次传给子组件的属性不一样,可以监听这个属性值,只要这个属性值变了,我就怎么怎么样
Element-ui方面:
Vant方面:
echarts方面:
canvas方面:
React方面:
移动端方面:
1、移动端新增标签:
<header></header>
<footer></footer>
<main>主内容</main>
<nav>导航</nav>
<section>div</section>
<aside>侧边栏</aside>
<figure>配图</figure>
<figcaption>配图说明</figcaption>
<video>视频</video>
<audio>音频</audio>
<input type="number">数字
<input type="search">搜索
<input type="tel">电话
<input type="color">颜色面板
<input type="file">文件
<input type="date">日期
<input type="range">范围
<input type="email">邮件
2、html和html5的区别?
html:超文本标记语言(英语:HyperText Markup Language,简称:HTML)是一种用于创建网页的标准标记语言,下边是html的一些标签:
标签 | 英文全称 | 中文说明 |
---|---|---|
a | Anchor | 锚 |
abbr | Abbreviation | 缩写词 |
acronym | Acronym | 取首字母的缩写词 |
address | Address | 地址 |
alt | alter | 替用(一般是图片显示不出的提示) |
b | Bold | 粗体(文本) |
bdo | Direction of Text Display | 文本显示方向 |
big | Big | 变大(文本) |
blockquote | Block Quotation | 区块引用语 |
br | Break | 换行 |
cell | cell | 巢 |
cellpadding | cellpadding | 巢补白 |
cellspacing | cellspacing | 巢空间 |
center | Centered | 居中(文本) |
cite | Citation | 引用 |
code | Code | 源代码(文本) |
dd | Definition Description | 定义描述 |
del | Deleted | 删除(的文本) |
dfn | Defines a Definition Term | 定义定义条目 |
div | Division | 分隔 |
dl | Definition List | 定义列表 |
dt | Definition Term | 定义术语 |
em | Emphasized | 加重(文本) |
font | Font | 字体 |
h1~h6 | Header 1 to Header 6 | 标题1到标题6 |
hr | Horizontal Rule | 水平尺 |
href | hypertext reference | 超文本引用 |
i | Italic | 斜体(文本) |
iframe | Inline frame | 定义内联框架 |
ins | Inserted | 插入(的文本) |
kbd | Keyboard | 键盘(文本) |
li | List Item | 列表项目 |
nl | navigation lists | 导航列表 |
ol | Ordered List | 排序列表 |
optgroup | Option group | 定义选项组 |
p | Paragraph | 段落 |
pre | Preformatted | 预定义格式(文本 ) |
q | Quotation | 引用语 |
rel | Reload | 加载 |
s/ strike | Strikethrough | 删除线 |
samp | Sample | 示例(文本 |
small | Small | 变小(文本) |
span | Span | 范围 |
src | Source | 源文件链接 |
strong | Strong | 加重(文本) |
sub | Subscripted | 下标(文本) |
sup | Superscripted | 上标(文本) |
td | table data cell | 表格中的一个单元格 |
th | table header cell | 表格中的表头 |
tr | table row | 表格中的一行 |
tt | Teletype | 打印机(文本) |
u | Underlined | 下划线(文本) |
ul | Unordered List | 不排序列表 |
var | Variable | 变量(文本) |
HTML5的设计目的是为了在移动设备上支持多媒体,
HTML5 中的一些有趣的新特性:
- 用于绘画的 canvas 元素
- 用于媒介回放的 video 和 audio 元素
- 对本地离线存储的更好的支持
- 新的表单控件,比如 calendar、date、time、email、url、search
- 新的特殊内容元素,比如 article、footer、header、nav、section
<canvas> 新元素
标签 | 描述 |
---|---|
<canvas> | 标签定义图形,比如图表和其他图像。该标签基于 JavaScript 的绘图 API |
新多媒体元素
标签 | 描述 |
---|---|
<audio> | 定义音频内容 |
<video> | 定义视频(video 或者 movie) |
<source> | 定义多媒体资源 <video> 和 <audio> |
<embed> | 定义嵌入的内容,比如插件。 |
<track> | 为诸如 <video> 和 <audio> 元素之类的媒介规定外部文本轨道。 |
新表单元素
标签 | 描述 |
---|---|
<datalist> | 定义选项列表。请与 input 元素配合使用该元素,来定义 input 可能的值。 |
<keygen> | 规定用于表单的密钥对生成器字段。 |
<output> | 定义不同类型的输出,比如脚本的输出。 |
新的语义和结构元素
HTML5提供了新的元素来创建更好的页面结构:
标签 | 描述 |
---|---|
<article> | 定义页面独立的内容区域。 |
<aside> | 定义页面的侧边栏内容。 |
<bdi> | 允许您设置一段文本,使其脱离其父元素的文本方向设置。 |
<command> | 定义命令按钮,比如单选按钮、复选框或按钮 |
<details> | 用于描述文档或文档某个部分的细节 |
<dialog> | 定义对话框,比如提示框 |
<summary> | 标签包含 details 元素的标题 |
<figure> | 规定独立的流内容(图像、图表、照片、代码等等)。 |
<figcaption> | 定义 <figure> 元素的标题 |
<footer> | 定义 section 或 document 的页脚。 |
<header> | 定义了文档的头部区域 |
<mark> | 定义带有记号的文本。 |
<meter> | 定义度量衡。仅用于已知最大和最小值的度量。 |
<nav> | 定义导航链接的部分。 |
<progress> | 定义任何类型的任务的进度。 |
<ruby> | 定义 ruby 注释(中文注音或字符)。 |
<rt> | 定义字符(中文注音或字符)的解释或发音。 |
<rp> | 在 ruby 注释中使用,定义不支持 ruby 元素的浏览器所显示的内容。 |
<section> | 定义文档中的节(section、区段)。 |
<time> | 定义日期或时间。 |
<wbr> | 规定在文本中的何处适合添加换行符。 |
已移除的元素
- <acronym>
- <applet>
- <basefont>
- <big>
- <center>
- <dir>
- <font>
- <frame>
- <frameset>
- <noframes>
- <strike>
- <tt>
3、移动端的事件
// 移动端的其他事件
// touchstart touchmove touchend touchcancel
// 事件对象也是存在的,
// touchstart在手指刚刚触摸的时候触发
// touchmove在手指移动的时候触发
// touchend 在手指离开的时候触发
// touchcancel是被动触发的,比如在你触摸过程中突然来电话了,此事件就会触发
// 在移动端querySelector选择器的兼容性比其他的好一些
//可以使用第三方的js插件去除300ms延时 获取拿zepto.js中的tap绑定事件没有300ms的延时
let box = document.querySelector('#box');
box.ontouchstart = function(e){
console.log('手指触摸',e);
}
box.ontouchmove = function(){
console.log('手指移动');
}
box.ontouchend = function(){
console.log('触摸结束');
}
box.onclick = function(){
console.log('click');
}
// touchmove和click是互斥的。他俩不能一起触发
4、点透事件与解决
// 当手指触摸到屏幕的时候,系统生成两个事件,一个是touch 一个是click,touch先执行,touch执行完成后,box2从文档树上面消失了,而且由于移动端click还有延迟200-300ms的关系,当系统要触发click的时候,发现在用户点击的位置上面已经没有box2了,目前离用户最近的元素是box1,所以就直接把click事件作用在元素box1上面了
<script>
box2.ontouchstart = function(e){
console.log('box2 start');
// e.preventDefault(); // 他会阻止当前元素的所有默认行为 在移动端click会被当做默认行为
// 利用定时器让box2在点击事件执行完成之后消失
setTimeout(()=>{
box2.style.display = 'none';
},1000);
}
box1.onclick = function(){
console.log('box1 click');
}
</script>
小程序方面:
uniapp方面:
浏览器:(2、3、4、5、7、10、11、16必看)
1、协议、域名、端口号
// http://www.baidu.com:8080/bkrcredit/cardDetail?cardCode=3051005&sid=detailhot
// - 协议:(https://):传输协议就是能够把客户端和服务端通讯的信息进行传递的工具
// + http:超文本传输协议,除了传递文本,还可以传递媒体资源文件以及XML格式数据
// + https:更加安全的http,一般涉及支付的网站都要采用https协议(s:ssl加密传输)
// + ftp:文件传输协议(一般用于把本地资源上传到服务器,就是把你的前端资源代码上传到服务器的时候用到的一种传输协议)【画图FTP】
// - 域名(每一个服务器都有自己的唯一的IP地址,每一个域名都可以和ip进行绑定)
// - 域名:(www.baidu.com)
// + 顶级域名 baidu.com (以后花钱买域名的时候,只需要把顶级域名买下就可以,去万网买)
// + 一级域名 credit.baidu.com
// + 二级域名 know.credit.baidu.com
// + 三级域名 cqw.know.credit.baidu.com
// + .com 国际域名(想面向国际化)
// + .cn 中文域名(想在中国玩一玩)
// + .com.cn
// + .edu 教育类
// + .gov 政府类 (政府:government )
// + .io 博客 (博客:Blog)
// + .org 官方组织 (官方:official)
// + .net 系统类
// - 端口号:(:80) 0~65535,用端口号来区分同一台服务器上不同的项目,一个端口下可以部署一个项目
// + http默认端口号是80
// + https默认端口号是 443
// + ftp默认端口号是 21
// + 如果项目采用的就是默认端口号,那我们在写地址的时候可以不加端口号,浏览器在发送请求的时候会帮我们加上
2、三次握手(A说我要和你建立连接啦,B说可以,A说好的那开始啦 )
1、浏览器需要发送一个SYN码给服务器,告诉服务器我要和你建立连接啦
2、服务器接收到SYN码之后,服务器在给客户端发送一个SYN+ACK码,告诉客户端咱们可以建立连接
3、客户端收到ACK码之后验证是否正确,如果正确,在向服务端发送一个ACK码,告诉服务端好的,咱们马上建连接吧!
3、四次挥手(A说我没有数据发啦,B说好的这边看一下都接收完了没,B说好的接收完了可以断开了,A说好的)
1、当客户端无数据要传输了,会发送FIN码告诉服务器,我发送完毕了;
2、当服务端接收完毕后,告诉客户端ACK码,告诉客户端你可以把数据通道关闭了;
3、当服务器发送完毕之后,也会发送FIN码,告诉浏览器,数据发送完毕;
4、当客户端接收完毕之后,同样发送ACK码,告诉服务器,数据接收完毕,你可以关闭;
三次握手和四次挥手的好处:确保数据的安全和完整
4、浏览器的渲染顺序
1、解析html
2、构建dom树
3、dom树结合css文件,构建呈现树
4、布局
5、绘制
5、输入url、按下回车发生了什么
1、DNS域名解析
2、建立TCP连接
3、发送HTTP请求
4、服务器处理请求
5、返回响应结果
6、关闭TCP连接
7、浏览器解析HTML
8、浏览器布局渲染
6、HTTP报文=请求报文 + 响应报文
- 请求报文:所有经过传输协议,客户端发送给服务端的内容,都是请求报文
+ 请求头
+ 请求体
- 响应报文: 所有经过传输协议,服务端响应给客户端内容,都是响应报文
+ HTTP状态码
+ 响应头
+ 响应体
7、http状态码
1**:信息,服务器收到请求,需要请求看继续执行操作
2**:成功,操作被成功接收并处理
3**:重定向,需要进一步操作,以完成请求
4**:客户端错误,请求包含语法错误或无法完成请求
5**:服务器出错,服务器在处理请求过程中发生了错误
200——客户端发送给服务器的请求被正常处理并返回
204——服务器处理了请求,但没有资源可以返回(无响应体)
206——部分内容。服务器成功处理了部分GET请求
301——永久重定向
302——临时重定向
303——临时重定向,应用get方法请求
304——表示客户端发送附带条件
307——临时重定向,不会从post变成get
400——语法错误
401——未经许可
403——访问权限(可以清除缓存,并硬性加载)
404——找不到请求的资源
500——服务器执行请求时发生了错误
503——服务器暂时处于超负荷或者停机维护中,无法处理请求
505——服务器不支持请求的http协议的版本
8、转码
1、encodeURI(url),只会对汉字进行编码,适合于转码整个url
let url= 'http://www.baidu.com:8080/info?name=二丫'
url = encodeURI(url); // 转码
url = decodeURI(url); // 解码
console.log(url);//"http://www.baidu.com:8080/info?name=%E4%BA%8C%E4%B8%AB"
2、encodeURIComponent(url),适合于转码参数,不使用于整个url,用它的话全部转了
let url= 'http://www.baidu.com:8080/info?name=zhangtao'
url = encodeURIComponent(url);
console.log(url);
//"http%3A%2F%2Fwww.baidu.com%3A8080%2Finfo%3Fname%3Dzhangtao"
注:基于encodeURIComponent进行编码,他会对字符串的数字和码,一般用于给参数部分进行编码, encod字母以外的值进行编eURIComponent和encodeURI是window上的方法,可以直接使用,但是md5是一个js插件,下载才可以使用,
md5(123456) // md5加密是不可逆的,是不能转码的
9、 location和history
1、location对象
// location的使用
// console.log(location);
// location是一个大对象,里面存储着当前url里的各种信息
// hash:当前的hash值
// host:域名+端口号
// hostname:域名
// href:整个url
// origin:协议+域名+端口号
// pathname:资源路径名称
// port:端口号
// protocol:协议
// search:问号参数
//-------------
// reload() 刷新页面
// replace() 替换当前的url,打开一个新的页面,不会反回之前的页面
// 给href赋值也能打开一个新的页面,但是是可以返回上一个页面的
2、history对象
back()——返回上一页
forward()——跳到下一页
go()——跳到指定页面,1是下一页,-1是上一页
10、get和post请求
1、GET(发送少,得到多,不安全,走缓存)
1、发送的少,得到的多,因浏览器对URL大小有限制(IE限制2kb,谷歌限制7kb左右),
2、不安全,问号传参,参数会直接暴露在url上,别人可以很容易篡改或者获取,
3、如果第一次请求的url和第二次一样,会默认走缓存
2、POST(发送多,得到少,安全,不走缓存)
1、发送的多,得到的少
2、把参数存储到请求主体中,别人不容易获取和篡改
3、不走缓存的
3、 客户是怎样把信息传递给服务器的
// - 问号传参 xhr.open('xxx/getDate?id=1') 适用于get系列请求
// - 设置请求头的方式 xhr.requestHeader('key',value) 不区分请求方式
// - 设置请求主体 xhr.send(请求主体) 适用于post系列请求
4、那服务器怎样把信息返回给客户端
// - 通过响应头
// - 通过响应体(大部分都是基于响应体拿)
11、强缓存和协商缓存
1、强行缓存:
浏览器请求一次,弄一个备份(etage),设置一个规定时间,一年之内都走缓存,
过期了就带着备份去和服务器上做对比,如果没变,还用缓存,
如果变了,把新的备份带过来,有效期还是一年
强缓存就是为了给客户端自给自足用的
2、协商缓存:
自己存一份,请求一次和服务器对比一次
每次都拿新的,协商缓存就是需要客户端和服务器两端进行交互的
12、axios是什么
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
从浏览器中创建 XMLHttpRequests
从 node.js 创建 http 请求
支持 Promise API
拦截请求和响应
转换请求数据和响应数据
取消请求
自动转换 JSON 数据
客户端支持防御 XSRF
13、axios的配置
import axios from 'axios';
axios.defaults.baseURL = 'http://127.0.0.1:8888';
//基础公共url,后期再发请求,url前公共部分就不用写了
axios.defaults.withCredentials = true;
//跨域请求中允许携带资源凭证(例如cookie信息)
axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded';
//设置请求头:POST系列中,我们传递给服务器数据的格式一般以x-www-form-urlencoded格式为主
axios.defaults.transformRequest = function (data) {
、、设置请求拦截器(只对POST系列有用):把基于请求主体传递给服务器的内容进行拦截,把内容格式变为x-www-form-urlencoded这种格式,再传递给服务器
if (!data) return data;
let result = ``;
for (let attr in data) {
if (!data.hasOwnProperty(attr)) break;
result += `&${attr}=${data[attr]}`;
}
return result.substring(1);//从索引1开始截取,到最后
};
axios.interceptors.response.use(function onFulfilled(response) {
// 设置响应拦截器:[成功状态]把从服务器获取的结果中的响应主体信息获取到即可,[失败状态]手动把错误信息抛出异常
return response.data;
}, function onRejected(reason) {
return Promise.reject(reason);
});
axios.defaults.validateStatus = function (status) {
//自定义配置成功态(把promise状态改为fulfilled)
return /^(2|3)\d{2}$/.test(status);
//状态码必须是2或者3开头的三位数
}
export default axios;
14、手写ajax
<script>
let data = null;
let xhr = new XMLHttpRequest;
xhr.open('get','xxx');
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && xhr.status === 200){
data = JSON.parse(xhr.response);
}
}
xhr.send();
function renderHtml(){
// 渲染页面
};
renderHtml();
</script>
15、ajax的属性和方法
<script>
let xhr = new XMLHttpRequest;
// console.log(xhr.readyState); // 0 刚刚创建完成ajax实例,而且没有调用xhr.open()
xhr.open('post','./data.json?id=1',true);
xhr.timeout = 2000; // 设置请求的超时时间
xhr.ontimeout = function(){
console.log('超时');
}
console.log(xhr);
xhr.setRequestHeader('ss',100); // 必须在open执行后,send执行之前去设置请求头
// console.log(xhr.readyState);//1 已经打开了一个open请求
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status == 200){
console.log(xhr.response);
}
}
// console.log(xhr.readyState);
// console.log(xhr.status);
// console.log(xhr.getAllResponseHeaders());
// console.log(xhr.getResponseHeader('Date'));
// let res = xhr.getAllResponseHeaders();
// console.log(res.split(/\n/)); // split也可以传递正则
// console.log(JSON.parse(res));
}
xhr.send('name=1&age=2&sex=3');
// 当前xhr中的readyState分别代表的意思是:
// DONE: 4 响应体已经接受完毕(所有东西都应接受完毕了)
// HEADERS_RECEIVED: 2 已经开始响应可以拿到http的状态码,可以拿到响应头了
// LOADING: 3 开始接受响应体
// OPENED: 1 已经执行了open方法了
// UNSENT: 0 刚刚建立一个xhr实例(open还没有执行)
----------------------------------------------------------------------------------
// xhr.getAllResponseHeaders();获取所有的响应头的数据(大的字符串)
// xhr.getResponseHeader('key');在响应头中获取某一个属性名对应的属性值
// xhr.setRequestHeader('ss',100); 设置请求头的信息
// xhr.timeout = 1000; // 设置请求的超时时间
// xhr.ontimeout = function(){} // 设置请求超时之后执行的事件
// xhr.withCredentials // 在跨域的时候是否允许携带资源凭证(cookies)
// xhr.abort() // 手动终止一个请求
// status:http状态码
// readyState:请求的步骤
// response:返回的请求体
// responseURL:请求的url
// open:配置一个基本的请求信息
// onreadystatechange=function(){}:监听readyState的变化的事件
</script>
16、本地存储
1、 localStorage
localStorage是永久性的本地存储,你不手动删除,那么他会永远存储在你的浏览器里,
localStorage会存储5mb左右,localStorage是H5新增的,低版本的浏览器不支持
localStorage.setItem('key',value); // 设置新的本地存储,当设置的时候会把浏览器会默认
把value转换成字符串在去存储;如果你存储的值是引用数据类型的,可以先拿JSON.stringify转一下在存储
// let obj = {a:2,b:2};
// obj = JSON.stringify(obj);//json对象转字符串
// localStorage.setItem(obj,obj);// 当获取的时候,把获取的值在拿JSON.parse转一下即可
// localStorage.getItem('key'); // 获取key存储的值
// localStorage.removeItem('key');//根据key删除掉值
// localStorage.clear(); // 清除全部localStorage存储
2、cookies
cookie几乎可以兼容所有浏览器,
一般浏览器允许在同一个域下最多8kb。
可以设置过期时间,但是一般情况下载没有到达时间之前cookie都被清除了(浏览器里的清除浏览记录也可以清除cookie,无痕浏模式不会设置cookie)
cookie经常会穿梭于浏览器和服务器之间
cookie会自动通过请 求头发送给服务端
后台也可以设置cookie信息,在响应头设置一个字段 setCookies:'a=1;b=2',当请求成功的时候,浏览器会检测当前的响应头中有没有setCookies字段,如果有的话,就会把此字段对应的信息存储到浏览器的cookie中
3、sessionStorage
存储的数据仅仅局限于当前的页面,如果页面关闭,那存储的数据就都没有了
4、以上三个本地存储的共同的特点
不管是哪一种存储,每一个不同的域下以及不同浏览器都会有一套独立的本地存储,相互不冲突
本地存储是明文存储,谁都可以看见,这样是不太友好的,所有如果有一些比较敏感的数据要存储到本地的话,最好加密或者转码
5、session (后台服务器存储)
session大小没有限制。
不太稳定(只要把服务器关闭了,那存储的session信息就没有了),也有过期的时间
补充区别:
Cookie、SessionStorage、 LocalStorage都是浏览器的本地存储。 它们的共同点:都是存储在浏览器本地的 它们的区别:cookie是由服务器端写入的,而SessionStorage、 LocalStorage都是由前端写入的,cookie的生命周期是由服务器端在写入的时候就设置好的,LocalStorage是写入就一直存在,除非手动清除,SessionStorage是页面关闭的时候就会自动清除。cookie的存储空间比较小大概4KB,SessionStorage、 LocalStorage存储空间比较大,大概5M。Cookie、SessionStorage、 LocalStorage数据共享都遵循同源原则,SessionStorage还限制必须是同一个页面。在前端给后端发送请求的时候会自动携带Cookie中的数据,但是SessionStorage、 LocalStorage不会 加分回答 由于它们的以上区别,所以它们的应用场景也不同,Cookie一般用于存储登录验证信息SessionID或者token,LocalStorage常用于存储不易变动的数据,减轻服务器的压力,SessionStorage可以用来检测用户是否是刷新进入页面,如音乐播放器恢复播放进度条的功能。
移动、 pc端用公用一套代码以及自适应怎么实现:(参考简书)
1、首先,在网页代码的头部,加入一行viewport元标签。
<meta name="viewport" content="width=device-width, initial-scale=1.0">
也就是viewport是网页默认的宽度和高度,上面这行代码的意思是,网页宽度默认等于屏幕宽度(width=device-width),原始缩放比例(initial-scale=1)为1.0,即网页初始大小占屏幕面积的100%。
所有主流浏览器都支持这个设置,包括IE9。对于那些老式浏览器(主要是IE6、7、8),需要使用css3-mediaqueries.js。
2、不可以使用绝对宽度、
由于网页会根据屏幕宽度调整布局,所以不能使用绝对宽度的布局,也不能使用具有绝对宽度的元素只能指定百分比宽度:width: xx%;或者width:auto;
3、相对大小的字体(rem相对于根元素来说,em相对于父元素来说的)
字体也不能使用绝对大小(px)(这真的是大忌,之前都是用的em的,这次头晕全程使用的px,最后屏幕一缩小,字体都看不清了),而只能使用相对大小(em)。body {font: normal 100% Helvetica, Arial, sans-serif;}上面的代码指定,字体大小是页面默认大小的100%,即16像素。h1 {font-size: 1.5em;}然后,h1的大小是默认大小的1.5倍,即24像素(24/16=1.5)。small {font-size: 0.875em;}small元素的大小是默认大小的0.875倍,即14像素(14/16=0.875)
4、流动布局
流动布局是什么意思呢,即使各个区域的位置都是浮动的,不是固定不变的,但是使用的时候也要小心,需要不同个尺寸的的测试,在这个项目里就是没有充分的测试,最后屏幕尺寸缩小浮动的div就会随便跑了。
5、选择加载 css
自适应网页设计的核心:就是css引入Media Query的模块 ,他的意思就是,自动探测屏幕宽度,然后加载相应的css文件。
例如:如果屏幕宽度小于400像素(max-device-width: 400px),就加载tinyScreen.css文件。
如果屏幕宽度在400像素到600像素之间,则加载smallScreen.css文件。、
除了用html标签加载CSS文件,还可以在现有CSS文件中加载。
@import url(“tinyScreen.css”) screen and (max-device-width: 400px);
6、CSS的@media规则
同一个CSS文件中,也可以根据不同的屏幕分辨率,选择应用不同的CSS规则。
@media screen and (max-device-width: 400px) {
.testInput{
width:50%;
height:80%;
}
}
@media screen and (min-device-width: 401px) {
.testInput{
width:90%;
height:90%;
}
}
7、图片的自适应
除了布局和文本,自适应网页还必须实现图片的自动缩放,这只要一行CSS代码:img { max-width: 100%;}
这行代码对于大多数嵌入网页的视频也有效,所以可以写成:img, object { max-width: 100%;}
老版本的IE不支持max-width,所以只好写成:img { width: 100%; }
此外,windows平台缩放图片时,可能出现图像失真现象。这时,可以尝试使用IE的专有命令:img { -ms-interpolation-mode: bicubic; }
或者,Ethan Marcotte的imgSizer.js。
addLoadEvent(function() {
var imgs = document.getElementById("content").getElementsByTagName("img");
imgSizer.collate(imgs);
});