配置
上传到GitHub后overview未变绿
登录github—>settings—>Emails—>Add email address
\
whistle代理设置
1、安装whistle
npm install -g whistle
2、启动whistle
w2 start
默认端口号为 8899 ,浏览器访问 http://127.0.0.1:8899/ ,则可访问
3.规则设置
可在 Rules 菜单中设置匹配规则,具体匹配原则请看 whistle 文档
4.浏览器代理配置
安装 chrome代理插件,推荐 switchyOmega,
5.手机配置代理(暂未遇到,等待完善…)
body、document、window区别
document
代表整个html文档,可以访问页面里所有元素
body
代表document的主题子对象,除了浏览器头部的地方,页面中能看到的内容
window
代表浏览器中打开的窗口,代表运行环境,地位很高,因为它是浏览器脚本引擎中的globalobject。
document对象是一个跟当前文档相关的对象,拥有一些操作文档内容的功能,其功能上跟window对象差不多,因为window拥有一些操作浏览器窗口的功能。但是document对象地位没有window对象高,window拥有其他所有根对象的引用,包括browser、navigator、location等等。
webpack的scripts里
windows环境下
cross-env NODE_ENV='development' gulp devQQ
mac
NODE_ENV='development' gulp devQQ
nvm node版本管理工具
(nvm安装后要修改环境配置C:\Users\erekli\AppData\Roaming\nvm)
遇到问题可以版本回退,有的node不兼容
yarn
全局安装最新版本的yarn,
npm install yarn@latest -g
安装完成后,运行yarn,
报错:无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本。
解决方法:
1.win+X键,使用管理员身份运行power shell
2.输入命令:set-executionpolicy remotesigned
3.输入”Y“,回车,问题解决。
关闭进程
查询3000端口占用的程序;此处模拟为2212
netstat -nao | findstr 4000
强制终止占用端口号的
taskkill /F /pid 2212
性能监控
先保存stats.js
Use window.self
instead of self
.
ts安装库
在custom.d.ts里面添加 declare module ‘react-infinite-scroller’;
git commit 提交的时候报错husky > pre-commit hook failed (add –no-verify to bypass)(解决办法)
这个问题是因为当你在终端输入git commit -m “XXX”,提交代码的时候,pre-commit(客户端)钩子,它会在Git键入提交信息前运行做代码风格检查。如果代码不符合相应规则,则报错,而它的检测规则就是根据.git/hooks/pre-commit文件里面的相关定义。查询了网上的解决办法,总结为以下三种解决方案,个人喜欢第三种:
卸载husky。只要把项目的package.json文件中devDependencies节点下的husky库删掉,然后重新npm i 一次即可。或者直接在项目根目录下执行npm uninstall husky –save也可以,再次提交,自动化测试功能就屏蔽掉。
进入项目的.git文件夹(文件夹默认隐藏,可先设置显示或者命令ls查找),再进入hooks文件夹,删除pre-commit文件,重新git commit -m ‘xxx’ git push即可。
将git commit -m “XXX” 改为 git commit –no-verify -m “XXX”。
css
适配rem
1 | 750是设计稿的宽度:之后的单位直接1:1使用设计稿的大小,单位是rem |
详解transform变换
https://www.zhangxinxu.com/wordpress/2012/09/css3-3d-transform-perspective-animate-transition/
文章写得 很有深度哈哈
瀑布流布局
参考文章
1、所有图片宽度一致,高度由内容决定
2、定位后确定浏览器显示区域内,一行能放多少列图片盒子。
- 获取页面的宽度
- 获取图片盒子的宽度
- 显示的列数 = 页面宽度/(图片盒子宽度+间隙)
column = pageWidth / (itemWidth+gap)
3、确定列数之后,排列第一行
- 下面还有很多图片盒子,我们先要排列第
1
行,所以在for
循环里就要判断一下,当i
(所有图片盒子的索引) <column
(显示列数)的时候,说明在第1
行; - 知道在第
1
行之后,动态设置每个图片盒子的left
值就能排好第1
行。 - `left = i * ( itemWidth + gap );
4、第1行排列好之后,获取第1行所有图片盒子的高度
- 需要定义一个数组
arr
,将获取到的高度存在数组中,因为第2
行排列的时候需要考虑top
值,此时只能根据第1
行图片盒子的高度来设置; - 获取图片高度的时候要注意,程序必须写在入口函数
onload
里面,因为图片的加载特性是:等页面都加载完之后才去请求加载,所以不写在入口函数里可能会出现高度获取不到的情况。
5、排列第2行
- 获取到刚刚数组中,高度最小的那一列,将第
2
行的第1
个图片盒子放置在它的下方; - 此时的
left
值就是高度最小列的offsetLeft
;top
值就是:第1
行高度最小列的高度(为了布局美观可以加上上下间隙gap
)。 - 记录下高度最小列的索引
index
,后面计算会用到; - 设置完成之后,会发现后面所有的图片都叠在这个高度最小列的下面,原因就是此时的最小列高度没有改变,应该加上下面图片的高度,得出一个新高度。
6、改变最小列当前高度
- 此时的这一列高度其实已经发生改变了,所以需要将新高度赋值给数组
- 当前高度最小列的高度 = 当前高度最小列的高度 + 间隙 + 下面图片盒子的高度
7、触发resize事件
- 将整个设置样式的部分封装成一个函数,在
onload
里面注册一个resize
事件,只要页面一发生改变,就触发样式部分的代码。 - 实时改变
pageWidth
的宽度,这样瀑布流就会是一个响应式的效果了
8、懒加载效果
- 目前我们用的是
30
张图片,假如一个页面中有几百张图片的时候,我们不可能等到它都加载完再显示,所有这里引入一个懒加载的概念,我们规定第30
张为显示的最后一张图片,当滚动条滚动到30
张的时候,应该加载下一批图片。 - 即页面可视区高度+滚动条卷去的高度 = 第
30
图片的offsetTop
;的时候加载下面的图片。
完整代码
1 | <!-- 样式部分 --> |
雪碧图实现动画
本质上是通过keyframes设置起始状态,然后通过animation里的steps来定义有多少帧数,animation-fill-mode是决定动画后的效果,还有delay是多少秒后开始执行动画等等。
@font-face
1 | @font-face { |
less几个特性
- @变量
- .变量名可以将公共属性抽取出来作为一个公共类
- .函数名(params) 参数 一般用作把几种兼容的写在一起
- 父子元素可以写成.father{一些属性.son{}}
- 先建一个one.less,在第二个里面@import “one”
rpx
rpx移动端 vm pc端
移动端字体最小12px,显示单位最小1px,再小要scale/transform
float和margin同时时候不生效
可以用clear属性清除浮动
line-height
当行高大于文字高度时,设置line-height等于容器高度可以上下自动居中
移动端垂直不居中要line-height:normal
IOS 滑动问题 -webkit-overflow-scrolling : touch 卡住不动问题
webkit-overflow-scrolling:touch
属性的下一层子元素上, 将height
加1%或1px。从而主动触发scrollbar
。
1 | <div id="app" style="-webkit-overflow-scrolling: touch; "> |
移动端适配:页面放大缩小
通过 meta
元标签标准中有个 中 viewport
属性,用来控制页面的缩放,一般用于移动端。核心user-scalable=no
,通过这个属性来阻止缩放行为的。
1 | <meta content="width=device-width,initial-scale=1,user-scalable=no" name="viewport"> |
JS
原型链
继承
this指向问题
xhr、axios、fetch
xhr
1 | xhr = new XMLHttpRequest() |
axios 封装xhr
1 | axios.get(url) |
适合大量http请求,需要错误处理或http拦截,支持node和浏览器
fetch
可以await
返回400、500时候不会reject
现代浏览器支持,但返回的要转格式
1 | fetch(url,{method:'post',headers:{balabala}}) |
await&Promise
题目一:
1 | Promise.resolve(1) .then(2) .then(Promise.resolve(3)) .then(console.log) |
解析
Promise.resolve方法的参数如果是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的Promise对象,状态为resolved,Promise.resolve方法的参数,会同时传给回调函数。
then方法接受的参数是函数,而如果传递的并非是一个函数,它实际上会将其解释为then(null),这就会导致前一个Promise的结果会传递下面。
答案 1
题目二:
1 | async function async1() { console.log("async1 start"); await async2(); console.log("async1 end");}async function async2() { console.log("async2");}console.log("script start");setTimeout(function() { console.log("setTimeout");}, 0);async1();new Promise(function(resolve) { console.log("promise1"); resolve();}).then(function() { console.log("promise2");});console.log("script end");//输出script startasync1 startasync2promise1script endasync1 endpromise2setTimeout |
题目三:
1 | const first = () => (new Promise((resolve, reject) => { console.log(3); let p = new Promise((resolve, reject) => { console.log(7); setTimeout(() => { console.log(5); resolve(6); }, 0) resolve(1); }); resolve(2); p.then((arg) => { console.log(arg); });}));first().then((arg) => { console.log(arg);});console.log(4); |
答案 374125
题目4
1 | function arr(){ setTimeout(function(){ console.log('1'); },0) async function async1(){ console.log('4'); await async2(); console.log('6'); } async function async2(){ console.log('5'); } async1(); new Promise(function(resolve,reject){ console.log('2'); resolve(); }).then(function(e2){ console.log('h'); }) console.log('3'); } |
答案45236h1
监听浏览器缩放事件(done)
在F12出现控制台隐藏后页面上会原先控制台所在部分会出现空白
1 | window.addEventListener('resize',setView)const setView = ()=>{ Render.setSize(Body.current.offsetWidth,Body.current.offsetHeight) } |
关闭的时候记得销毁
1 | window.removeEventListener('resize',setView) |
setInterval返回值
setInterval返回一个控制事件的id 类型Number,以此作为基础可以编写一个加载的loading组件
防抖和节流
对于函数防抖,有以下几种应用场景:
给按钮加函数防抖防止表单多次提交。
对于输入框连续输入进行AJAX验证时,用函数防抖能有效减少请求次数。
判断scroll是否滑到底部,滚动事件+函数防抖
总的来说,适合多次事件一次响应的情况
代码:
1 | function debounce(fn,wait){ let timer = null return function(){ const that = this const args = arguments if(timer){ clearTimeout(timer) timer = null } }} |
之所以返回一个函数,因为防抖本身更像是一个函数修饰,所以就做了一次函数柯里化。里面也用到了闭包,闭包的变量是timer。
注:参考文章详解柯里化
1 | // 实现一个add方法,使计算结果能够满足如下预期:add(1)(2)(3) = 6;add(1, 2, 3)(4) = 10;add(1)(2)(3)(4)(5) = 15;function add() { // 第一次执行时,创建一个新的数组,包含所有 arguments 对象中的元素。 let _args = Array.prototype.slice.call(arguments); // 在内部声明一个函数,利用闭包的特性保存_args并收集所有的参数值 let _adder = function() { _args.push(...arguments); return _adder; }; // 利用toString隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回 _adder.toString = function () { return _args.reduce(function (a, b) { return a + b; }); } return _adder;}add(1)(2)(3) // 6add(1, 2, 3)(4) // 10add(1)(2)(3)(4)(5) // 15add(2, 6)(1) // 9 |
这里又涉及到自执行函数
对于函数节流,有如下几个场景:
游戏中的刷新率
DOM元素拖拽
Canvas画笔功能
总的来说,适合大量事件按时间做平均分配触发。
页面生命周期
小程序
onLoad
页面加载时触发,且只发生一次,有些数据实时性要求不高可以onlaod里面触发对应的请求
onShow
页面初次渲染之后触发(只是初次,下一次页面渲染就没他什么事),只触发一次。你发送请求其实也可以把它当做onload毕竟也只是一次,但是你涉及到一些渲染的东西要注意了,设置页面标题之类的要在他之后再用。
onReady
定义是页面显示,切入前台触发,用我的话来讲就是这个页面出现一次,他就被调用一次包括你前进后退到这个页面。
网页
onReady
表示文档结构已经加载完成(不包含图片等非文字媒体文件)。
在dom加载完成后就可以直接对dom进行操作,比如一张图片只要标签完成,不用等这个图片加载完成,就可以设置图片的宽高的属性或样式等。
onLoad
指示页面包含图片等文件在内的所有元素都加载完成。
是在整个document文档(包括了加载图片等其他信息)加载完成后就可以直接对dom进行操作,比如一张图片要等这个图标加载完成之后才能设置图片的宽高的属性或样式等。
TS
?:
在接口里写?:代表这一项不是必填,?:的意思指的是参数自动加上undefined
1 | function getval(x: number, y?: number) { return x + (y || 0);}getval(1, 2);getval(1);getval(1, undefined);getval(1, null); // error, 'null' is not assignable to 'number | undefined' |
?.
a?.b 当a有属性b时才会去读取
a?.b 相当于 a && a.b ? a.b : undefined
??
?? 和 || 的意思有点相似,但是又有点区别,??相较||比较严谨, 当值等于0的时候||就把他给排除了,但是?? 不会
1 | console.log(null || 5) //5console.log(null ?? 5) //5console.log(undefined || 5) //5console.log(undefined ?? 5) //5console.log(0 || 5) //5console.log(0 ?? 5) //0 |
上面两个配合起来可以写成
null!
y=null!或者y=undefined!
对应前面?.后的属性不存在,但是又想返回undefined时使用。
类型转换技巧
1 | // 强制转换为Boolean 用 !!var bool = !!"c";console.log(typeof bool); // boolean |
interface和type的异同
相同点:
都可以描述一个对象/函数,都允许进行扩展
不同点:
1.type生命基本类型别名、联合类型、元组等
2.typeof获取实例的对象
3.interface可以声明合并
哪里用interface?
1.有关与后台的接口,愿意用
2.第三方的和开发的sdk,例如vue
3.前端的库 如sky.min.js sky.d.ts
4.正常开发任务 type更方便更直接
extends和implements的区别
1 | extends可以理解为全盘继承了父类的功能implements可以理解为为这个类附加一些额外的功能注意一个interface可以extends多个其他interface。 |
每周问答
github地址
Vue
slot
1 | <template> |
1 | 子组件: |
git
git graph 查看推git的进度图 安装完>git graph
git branch –set-upstream-to=origin/
在当前分支下 git reset –hard 想以别的分支名 以别的分支为标准合并到本分支
在当前分支下git push –force 强制推本分支到最新
git push origin master:master 前面是本地分支名,后面是远端分支名
git remote update 查看更新了哪些
git pull 先在主分支上
git rebase origin/feat/ui-optimize rebase 远端
git rebase master rebase 远端的master
有意思的一段代码
1 | (!(~+[])+{})[--[~+""][+[]]*[~+[]] + ~~!+[]]+({}+[])[[~!+[]]*~+[]] |
- 本文作者: Raphael_Li
- 本文链接: https://lifei-2019.github.io/all/
- 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!