javascript,分配requestAnimationFrame& cancelAnimationFrame到对象的属性

时间:2017-06-27 08:09:36

标签: javascript this requestanimationframe native-methods

//
// version 1
//
var requestAnimFram = (function(){
    return window.requestAnimationFrame    ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame    ||
        window.oRequestAnimationFrame      ||
        window.msRequsetAnimationFrame     ||
        function(callback){
            window.setTimeout(callback, 1000 / 60);
        }
})();

//version 1 usage
function main(){
    //main loop
    ...
    requestAnimFram(main);
}
main();

//
// version 2
//
var animFram = {
    req: window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.oRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        function(callback){
            window.setTimeout(callback, 1000 / 60);
        },
    ccl: window.cancelAnimationFrame ||
        window.mozCancelAnimationFrame,
    myReq: 0
};

//version 2 usage
function main(){
    ...
    aniFram.myReq = aniFram.req(main);
}
main();

function stop(){
    aniFram.ccl(myReq);
}

在我探索一些示例代码时,我找到了requestAnimationFrame。版本1是由它雕刻而成,它工作正常。在搜索了一段时间之后,我发现cancelAnimationFrame也想要使用它们。所以我做了一个虚拟页面进行测试。版本2是由它雕刻而成。

问题在于,它不会循环。所以,我有两个问题。

  1. 以这种方式使用requestAnimationFrame是否不可能?如果是这样,为什么呢?

  2. 如果有可能 - 但我是以错误的方式做的,我该如何实现呢?

1 个答案:

答案 0 :(得分:0)

这是重复的("Uncaught TypeError: Illegal invocation" in Chrome)。但是我仍然会更详细地回答我自己的问题,因为这样可以帮助其他人以不同的方式理解这个问题。

  
      
  1. 以这种方式使用requestAnimationFrame是不可能的?如果是这样,为什么会这样呢?
  2.   

这是不可能的。

  
      
  1. 如果可能 - 但我以错误的方式做到了,我该如何实现呢?
  2.   

使用 public ActionResult Index() { Test model = new Test(); return View(model); } [HttpPost] public ActionResult Index(Test model) { return View(model); } 以及call()bind()方法可以轻松解决此问题。

apply()

注意这里的相似之处是所有3种方法都有某种额外的参数' window'。它们都有相同的原因://Using call() //Attach call method during invocation aniFram.req.call(window, main); //Using bind() //Attach bind method during the object initialization aniFram = { req: requestAnimationFrame.bind(window) ... } aniFram.req(main); //Using apply() //Attach apply method during invocation aniFram.req.apply(window, [main]); requestAnimationFrame对象的方法,需要window的上下文。

window是一个对象。它有一个引用aniFram的方法reqwindow.requestAnimationFrameaniFram.req(main),而不是window.requestAnimationFrame的上下文中调用aniFram。这就是为什么它不起作用的原因。让我们考虑另一个示例代码:

示例代码

window

这与您的代码版本2的情况完全相同。您调用引用var obj1 = { target: 'Jake', hitman: function(){ this.target = 'RIP'; } }; var obj2 = { //assigns obj1.hitman to obj2.hitman hitman: obj1.hitman }; obj2.hitman(); console.log(obj1.target); //outputs 'Jake' ///////////////////////////////////////// //call() method obj2.hitman.call(obj1); console.log(obj1.target); //outputs 'RIP' //apply() method obj2.hitman.apply(obj1); console.log(obj1.target); //outputs 'RIP' //bind() method var obj2 = { hitman: obj1.hitman.bind(obj1) }; obj2.hitman(); console.log(obj1.target); //outputs 'RIP' 的{​​{1}}期望更改obj2.hitman()的值,但它不执行任何操作。因为obj1.hitman执行的是obj1.target语句。由于它是在obj1.hitman的上下文中执行的,因此该语句变为this.target = 'RIP'。 obj2中没有obj2属性。

call,apply,bind

这些方法启动的地方。没有它们,Javascript引擎自动确定上下文(当前对象。即aniFram,obj2)。通过将这些方法附加到代码中,现在您可以决定它将在哪个上下文中执行(即窗口,obj1)。

这也称为别名函数。 (If Javascript has first-class functions, why doesn't this work?