我正在使用webkitRequestAnimationFrame
,但我在对象内部使用它时遇到了麻烦。如果我传递this
关键字,它将使用window
,而我无法找到使用指定对象的方法。
示例:
Display.prototype.draw = function(){
this.cxt.clearRect(0, 0, this.canvas.width, this.canvas.height);
//Animation stuff here.
window.webkitRequestAnimationFrame(this.draw);
};
我也试过这个,但无济于事:
Display.prototype.draw = function(){
this.cxt.clearRect(0, 0, this.canvas.width, this.canvas.height);
//Animation stuff here.
var draw = this.draw;
window.webkitRequestAnimationFrame(draw);
};
答案 0 :(得分:78)
我正在尝试传递display.draw这是webkitRequestAnimationFram所在的函数。
webkitRequestAnimationFrame
可能会调用你传入的函数,如下所示:
function webkitRequestAnimationFrame(callback)
{
// stuff...
callback();
// other stuff...
}
此时,您已将draw
函数与其调用上下文分离(分离)。您需要将函数(draw
)绑定到其上下文(Display
的实例)。
您可以使用Function.bind
,但requires JavaScript 1.8 support(或只使用推荐的补丁)。
Display.prototype.draw = function()
{
// snip...
window.webkitRequestAnimationFrame(this.draw.bind(this));
};
答案 1 :(得分:19)
现在ES6 / 2015就在这里,如果你使用的是一个转换器,那么一个箭头函数有一个词汇this
绑定,而不是:
window.webkitRequestAnimationFrame(this.draw.bind(this));
你可以这样做:
window.webkitRequestAnimationFrame(() => this.draw());
有点干净。
我已经有效地使用了这个有效的XML脚本。
答案 2 :(得分:5)
我无法保证这是一个好主意,而且我是对的,但在每个requestAnimationFrame上运行.bind意味着在每次迭代时创建一个新函数。它对我来说听起来不对。
这就是为什么在我的项目中我缓存绑定函数以避免反模式。
简单示例:
var Game = function () {
this.counter = 0;
this.loop = function () {
console.log(this.counter++);
requestAnimationFrame(this.loop);
}.bind(this);
this.loop();
}
var gameOne = new Game();
如果你有一个带有原型继承的更复杂的项目,你仍然可以创建一个缓存函数"这个"绑定在对象的构造函数
中var Game = function () {
this.counter = 0;
this.loopBound = this.loop.bind(this);
this.loopBound();
}
Game.prototype.loop = function () {
console.log(this.counter++);
requestAnimationFrame(this.loopBound);
}
var gameOne = new Game();
思考? http://jsfiddle.net/3t9pboe8/(在控制台中查看)
答案 3 :(得分:3)
怎么样:
Display.prototype.draw = function(){
this.cxt.clearRect(0, 0, this.canvas.width, this.canvas.height);
//Animation stuff here.
window.webkitRequestAnimationFrame( $.proxy(function() {this.draw()}, this) );
};
...假设您使用jquery
答案 4 :(得分:0)
你不要使用“这个”。 保持简单。
var game = {
canvas:null,
context:null,
init:function(){
// init canvas, context, etc
},
update:function(){
//do something
game.render();
requestAnimationFrame(game.update, game.canvas);
},
};
答案 5 :(得分:0)
在bind
方法和箭头函数解决方案(由Jamaes World的答案提供)旁边,另一种(较旧的)解决方法可能是:
var self = this
window.webkitRequestAnimationFrame(
function() {
self.draw()
}
);
答案 6 :(得分:-2)
您还可以使用requestAnimationFrame shim使其适用于所有浏览器https://github.com/kof/animation-frame