requestAnimationFrame(请求动画帧)
导读: 前端要实现动画效果目前可以用CSS3、定时器、jquery等。
- 定时器动画时间并不准确,甚至当设置的时间过小时,就会出现掉帧的现象(动画是一帧一帧的图片)
- 屏幕刷新率:屏幕上每秒钟能够显示的图片数目。目前主流设备屏幕刷新率为60Hz,部分高端设备达到120Hz.
- 以60Hz刷新率为例,则每张图片显示时间为 1000ms/60 =16.6666667,就是约每16ms才会刷新一次屏幕显示,当把定时器动画设为10ms时,过了10ms的时间,动画开始移动,到屏幕并没有刷新,此时就会掉帧,即此帧图片并没有显示出来。
- 而requestAnimationFrame是根据屏幕刷新率同步执行的,在页面刷新的前一刻执行一次,就是说假如是60Hz的屏幕,就16ms刷新一次,如果是120Hz就自动8ms刷新一次。不会出现掉帧的现象!
除此之外,requestAnimationFrame还有以下两个优势:
CPU节能:使用setTimeout实现的动画,当页面被隐藏或最小化时,setTimeout 仍然在后台执行动画任务,由于此时页面处于不可见或不可用状态,刷新动画是没有意义的,完全是浪费CPU资源。而requestAnimationFrame则完全不同,当页面处理未激活的状态下,该页面的屏幕刷新任务也会被系统暂停,因此跟着系统步伐走的requestAnimationFrame也会停止渲染,当页面被激活时,动画就从上次停留的地方继续执行,有效节省了CPU开销。
函数节流: 在高频率事件(resize,scroll等)中,为了防止在一个刷新间隔内发生多次函数执行,使用requestAnimationFrame可保证每个刷新间隔内,函数只被执行一次,这样既能保证流畅性,也能更好的节省函数执行的开销。一个刷新间隔内函数执行多次时没有意义的,因为显示器每16.7ms刷新一次,多次绘制并不会在屏幕上体现出来。
由于requestAnimationFrame是H5新增,兼容性并不太好,封装一个兼容性代码:
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function(callback){
window.setTimeout(callback,1000/16);
}
})();
//封装取消请求动画帧
window.cancelAnimFrame = (function(){
return window.cancelAnimationFrame ||
window.webkitCancelAnimationFrame ||
window.mozCancelAnimationFrame ||
function(id){
window.clearTimeout(id);
}
})();
history(历史记录)
将历史记录一条条的存放在栈中
history.back() // 回翻一页
history。forward() //前进一页
hisrory,go(n) //跳转指定页数
管理历史记录
- 主要应用于SPA:单页面应用;只有一个页面,使用ajax进行数据交互,这样就无法前进后退,但可以利用history保存状态,达到前进后退的效果。
- 修改历史记录:
history.pushState(state,title,url); //添加一条历史记录
history.replaceState(state,title,url); // 替换当前的历史记录
//state:与指定网址相关的状态对象
//title:新页面的标题,但被所有浏览器忽略
//url:新的网址(必须同域),浏览器地址栏会显示此值
- 上述两个方法能改变历史记录,但不会刷新界面,实际开发中url并不会传一个网址,而是拼接一个标记参数。在单页面应用时,使用此特性可实现页面前进后退!!!。
- popstate事件:历史记录发生改变时触发(不包括2中的两个方法)。会自动获取状态对象state
- hashchange事件:页面地址栏的hash值发生改变时触发。用于构建单页面应用。
worker(异步操作)
js是单线程执行的,若计算量特别大,耗时就特别长,就会卡顿到计算出结果。
worker就是解决 把一个任务单独拿出来异步执行,不影响主线程的执行,最终将执行结果给主线程。
worker文件必须要和主文件同源。
- 使用:
var worker = new Worker('worker.js');
worker.postMessage(10);//将数据传给worker文件
worker.onmessage = function(e){ //监听得到worker文件发来的数据
console.log(e.data);
}
// 以下是worker.js文件的内容
onmessage = function(e){ //接受主文件的消息
var a = e.data*10;
postMessage(a);//将结果给主文件
}
- 结束worker 应当避免使用close()方式结束
worker.terminate();//主线程主动结束worker 写在主进程
close(); //worker.js文件主动结束worker 写在worker.js文件
- 其他特性
可以通过improtScripts('aa.js','bb.js');
来引入一些文件。但不能用此引入jquery库,因为worker只是window的子集,不能获取到window/document,所以只能引入一些计算类的库