requestAnimationFrame与此关键字

时间:2011-05-19 21:39:06

标签: javascript object animation this

我正在使用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);
};

7 个答案:

答案 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