Ошибка кадра запроса анимации

Это вызывает ошибку (FF, Chrome и?):

восстановление JSFiddle

Engine.prototype.requestAnimationFrame = window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.oRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        function(/* function */ callback, /* DOMElement */ element){
            window.setTimeout(callback, 1000 / 60);
};

И полный контекст:

var Engine = function(model) {

        this.model = model;
    };

    Engine.prototype.start = function() {
        console.log("ready")
        this.requestAnimationFrame(function() {
            console.log("done");
        });
    };

    Engine.prototype.updateUi = function() {

        console.log("update ui");
        this.requestAnimationFrame(this.updateUi);
    };

    Engine.prototype.logRAF = function() {
        console.log(window.requestAnimationFrame ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame ||
            window.oRequestAnimationFrame ||
            window.msRequestAnimationFrame);
        return this;
    };

    Engine.prototype.requestAnimationFrame = window.requestAnimationFrame ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame ||
            window.oRequestAnimationFrame ||
            window.msRequestAnimationFrame ||
            function(/* function */ callback, /* DOMElement */ element){
                window.setTimeout(callback, 1000 / 60);
            };

var engine = new Engine();
engine.logRAF().start();

Ошибка следующая в FF - mozRequestAnimationFrame(): NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on WrappedNative prototype object

Ошибка следующая в Chrome - webkitRequestAnimationFrame(): Uncaught TypeError: Illegal invocation

на линии:

this.requestAnimationFrame...

Журнал читает распечатки готово, но не сделано

Если я использую только функцию вместо собственных методов RAF, она работает (выполнено регистрируется):

восстановление JSFiddle

Что происходит с RequestAnimationFrames?


person Peter Ajtai    schedule 28.12.2012    source источник


Ответы (2)


Когда вы вызываете функцию window, контекст(this) должен быть window, а не вашим объектом (экземпляром Engine). bind поможет вам решить эту проблему:

Engine.prototype.requestAnimationFrame = 
        (window.requestAnimationFrame && window.requestAnimationFrame.bind(window)) ||
        (window.webkitRequestAnimationFrame && window.webkitRequestAnimationFrame.bind(window)) ||
        //etc...

демонстрация

person Engineer    schedule 28.12.2012
comment
@PeterAjtai Рад, что помог. - person Engineer; 28.12.2012
comment
Вы также можете использовать (window.a || window.b || ...).bind(window). - person pimvdb; 28.12.2012
comment
@pimvdb - при условии, что доступен один из методов оконной функции RAF. Если он вернется к обычной функции, это произойдет из-за ошибки ... но да, есть некоторые сокращения, которые нужно сделать. - person Peter Ajtai; 28.12.2012
comment
Я не думаю, что это вызовет ошибку — резервная функция не использует this, поэтому использование .bind для нее недопустимо. - person pimvdb; 28.12.2012
comment
@pimvdb undefined.bind(window) is a error jsfiddle.net/pajtai/RL24r - так что просто нужно обернуть немного лучше: - person Peter Ajtai; 28.12.2012

requestAnimationFrame следует вызывать в контексте window: this.requestAnimationFrame.call(window, ...);, как указано здесь: Uncaught TypeError: Illegal вызов в Chrome

person Ivan Nikolchov    schedule 28.12.2012