@demonly
2017-10-13T12:34:53.000000Z
字数 2043
阅读 1158
JavaScript
以往常常使用 setTimeout 以及 setInterval 方法来制作 JavaScript 动画,但是这种方式制作的动画经常会由于计时器的特性而带来一些问题。简单地说一下,计时器动画有以下几个问题。
使用 requestAnimationFrame 方法来定义动画就不会出现以上这些问题。
requestAnimationFrame() 方法接收一个参数,即要执行的回调函数。这个回调函数会默认地传入一个参数,即从打开页面到回调函数被触发时的时间长度,单位为毫秒,精确度为10微秒。这个方法返回一个唯一的 handle 值,handle值 作为这个回调函数唯一的标识符,可以通过将这个标识符传给 cancleAnimationFrame() 方法来取消这个回调函数。
requestAnimationFrame() 方法接受一个回调函数,同时随机生成一个唯一的 handle 值作为标识符。回调函数和 handle 值共同组成一个元组 <handle, callback>
,然后将这个元组推入动画帧请求回调函数队列中。
当页面可见时,如果动画帧请求回调函数队列中有元组,那么浏览器就会清空队列并且执行这些回调函数。
另外,每一个元组有一个 canceled 标识符,如果为 false,那么这个回调函数就不会在清空队列后被执行。cancleAnimationFrame() 方法的原理就是将这个标识符设置为 false。
var startTime;
function sayHi(time){
if(!startTime){
startTime = time;
}
time -= startTime;
console.log("Hi");
if (time <= 2000) {
requestAnimationFrame(sayHi);
}
}
requestAnimationFrame(sayHi);
使用 Web Worker 可以创建一个子线程,在后台运行 JavaScript 脚本,而不会影响到前台页面的性能。在网页 JavaScript 中如果存在有大计算量的计算可以将其放到后台处理,等处理完毕再将结果返回到页面中,但是子线程中不可以访问 DOM 。目前的主流浏览器都支持 Web Worker ,IE 除外。
在使用 Web Worker 之前先要确定浏览器的支持情况。
if(typeof Worker !== 'undefined') {
//浏览器支持 Web Worker
} else {
//浏览器不支持 Web Worker
}
创建 Web Worker 的方式是调用 Worker 构造函数,这个构造函数接收一个参数,要执行的JS文件。
var worker = new Worker("worker.js");
这个JS文件必须和网页来自同一个域,否则会被污染而报错。
如果需要接收来自 worker 的信息,需要为 worker 对象绑定 message 事件,当 worker 调用自身的 postMessage() 方法向主线程传递数据的时候就会触发该事件,传递的数据被保存在事件对象的data属性中。可以通过调用 worker.postMessage()方法来向子线程传递数据。
worker.addEventListener("message", function(e) {
console.log(e.data)
}, false);
对于子线程,同样需要绑定 onmessage 事件来接收来自主线程的数据,当主线程调用 worker 对象的 postMessage() 方法时会触发这个事件,数据的内容同样保存在事件对象的 data 属性中。可以通过 postMessage() 方法向主线程传递数据。
onmessage = function(e) {
console.log(e.data);
postMessage(e.data);
}
worker 也可以使用 JavaScript 中的计时器。
需要终止 worker,可以调用 worker 的 terminate()方法。Worker 也可以调用自己的 self.close() 方法来关闭自己。这些指令会立即终止线程,不会让它完成操作或者清理工作。
worker内可以正常访问 navigator 对象。
importScript() 函数可以引入外部 JS 文件。可以接受任意个 URI ,引入这些脚本。