又是久违的总结。
最近在做的项目是一个动画,用 Canvas 实现,用的库是 Pixi,做一个射击抽奖小游戏。做动画还是有些门道的,比如做云的动画,要考虑云什么时候走到界面边缘要销毁,再生成一片新的云,还有云出现的位置要稍微随机,不能每一次都出现在一个地方。
在做射击人物部分的时候,以为要做人的碰撞检测,结果Pixi可以在每个动画上绑定事件,只要监听事件即可。碰到一个坑就是两个绑定事件的动画不能叠加在一起,否则只有层级最高的那个动画元素事件会触发。
知识总结
实现复制功能
IE 下可以直接调 api setData("text", text)
,有个坑是如果复制的内容是 undefined
的话会报错。Chrome 下没有这个API。Chrome 下实现复制的方法是:在页面创建一个 <textarea>标签,将要复制的内容复制给 <textarea> 的 value
属性,获取到 <textarea> 后调用它的 selection 方法,将文本选中,然后使用 execCommand('copy', false, false)
实现复制。
封装操作 Cookie 的方法
研究了下组里 SDK 中操作 Cookie 的方法。dealCookie(name, value, opt...)
实现大致如下:首先判断参数有几个,如果只有一个,说明只是想获取 Cookie,先将保存的 Cookie 取出,使用 split
将Cookie以 ';' 分隔转为一个数组。
遍历每个数组,首先利用正则/^\+s|+s$/g
去掉首尾的空格,将数组切割到name.length
的长度并与${name}=
做比较,如果相等,将这个数组取出,在返回的时候,返回之前,需要做一个decodeURIComponent
,因为有的浏览器 Cookie 值不支持中文,需要编码后才能存储,所以取出来的时候需要做一个 decodeURIComponent
,重复写一次是为了记住这个操作API。
如果传参大于一个,说明需要做的是存储 Cookie 的操作,
对于 Cookie 的 path
的处理,如果没传,默认使用 /
作为保存路径;
对于 domain
,如果没传,默认使用 location.host
;
secure
默认为空字符串 '',secure
的作用是,如果为true
,则该 Cookie 只有在使用 https 时才会发送到服务端。
比较复杂的是对 expires
的处理,因为旧浏览器不支持直接传天数,只支持 UTC 格式的时间,所以对传入数字要做处理:实例化一个 Date
——date,使用 date = date().setTime(date.getTime() * 24*60*60*1000)
得到一定天数之后的时间戳。 让 expires
等于 date.toUTCString()
。
传两个参数还有一个情况,就是 value
传 null
时,意味着要删除 Cookie ,则直接将 expires 赋为 -1 。
如何监听 CSS transition 的停止
有一个 transitionend 事件,会在 transition 结束后调用。如果改变的属性有多个,transition 就会触发多次。
input 所有事件的调用顺序
mousedown -> focus -> mouseup -> click
keydown -> keyup -> input(h5 新事件,<input type="text"> 不会触发 change事件) -> change -> blue)
webpack 热更新原理简单描述
使用 websocket,在页面插入 websocket,同时监听自定义事件,在本地开启服务器,css,js 就是服务器上的静态文件,每次文件有变化,都跟文件的上一个 mtime
属性比较,如果不一样,说明文件发生变化,触发事件,把变化的内容告知浏览器,浏览器通过直接插入一个新 css,或者覆盖原来 css 样式的方法修改 CSS,实现热更新。
柯里化简述
利用闭包,先执行一次 currying
,将参数存储起来,最后调用的时候再使用全部的参数调用。
function currying(fn) {
let allArgs = [ ];
return function next() {
if (arguments.length > 0) {
let arg = Array.prototype.slice.call(arguments);
allArgs.push(arg);
return next;
} else {
fn.apply(null, allArgs);
}
}
}
这种适合 add(2,3)(6,5)()
调用,如果要add(2,3)(6,5)
,可以改写 next 的 valueOf
,利用函数打印会调用 valueOf
的特性,在 valueOf
里执行函数 next
。
零碎知识
- <img> 的默认
display
是inline
,行内可替换元素; - arguments 转为数组:
Arrary.prototype.slice.call(arguments)
- 多益面试题,在《你不知道的JS》中有提到
3.toString()
会报错,因为第一个点会被认为是 3 的小数点,所以应该3..toString()
对后端的理解
上周周末用 egg 实现了 RESTful 接口,RESTful 说白了就是一个接口只负责获取/修改一项数据,不像有的接口一个接口就返回了一个页面所有需要的数据。而前后端分离,就是向后端获取的不是 html 文件,而是一个个 json 数据,前端拿到数据后自己决定如何渲染。在开发的过程中,为了还原真实的数据返回,用爬虫去豆瓣抓了 200 个最新的电影数据,保存在一个 json 文件中,然后利用 json 文件的数据,自动创建 sql 脚本,放到 mysql 执行,一个有 200 条数据的表就创建完成。
另外,为了解决跨域问题使用了两种方案,一种是后端使用 cors,将本地 url 添加进白名单,assess-control-arrow-origin
就会是我们本地的 url ,就能直接从不同域的服务端获取数据,这样还无法传输 Cookie,要使用 cors 传输 Cookie,还需要将access-controll-arrow-Credentials: true
,ajax设置withCredentials
为true
。
新的算法知识
重新撸了一遍动态规划的跳台阶,利用迭代而不是用递归。让 n1 = n2,n2 = total,总的次数就是 n1 + n2,一个斐波那切数列。
还有过了一遍“找出第 k 小个数”,就是利用顶堆,简化版的堆排序,在找到了 k 个数后停止即可。
做项目的总结
接触一个新项目,接口文档,交互逻辑不确定是不是完整的时候,要在脑海里完整过一遍这个项目每个交互过程,模拟整个交互,看看哪些交互文档没有提及,哪些接口可能要用到,但是文档上没有,尽量不要边开发边要接口,否则可能出现在开发一个逻辑,结果接口后端还没做,或者文档没有补齐,就要等其他组的同事做完才能继续开发这样十分没有效率。