2014-01-10 66 views
1

我正在查看following code from Paul Irish on the requestAnimationFrame shim layer。我想从另一种语言中生成这个js,所以我试图把我的头围绕到正在发生的事情上。 (你可以see it being used in an animation here)。解释请求动画帧垫片层

window.requestAnimFrame = (function(){    //1 
    return window.requestAnimationFrame  ||  //2 
      window.webkitRequestAnimationFrame ||  //3 
      window.mozRequestAnimationFrame ||  //4 
      function(callback){      //5 
      window.setTimeout(callback, 1000/60); //6 
      };           //7 
})();             //8 
                 //9 
(function animloop(){         //10 
    requestAnimFrame(animloop);       //11 
    render();           //12 
})();             //13 

我的问题是 - 第2-4行发生了什么?我们似乎正在获取函数句柄,并将它们连接到OR操作中 - 然后将OR操作的结果分配给第1行中的匿名函数 - 然后将其分配给var window.requestAnimFrame

编辑: 感谢所有有用的答案 - 我只是想确保我有这个正确的 - 是下面发生了什么事的精确表示?Here is the original)(Here is the version with the more explicit code。)

var myfunc = function() { 
    if (typeof(window.requestAnimationFrame) != "undefined") { 
     return window.requestAnimationFrame; 
    } else if (typeof(window.webkitRequestAnimationFrame) != "undefined") { 
     return window.webkitRequestAnimationFrame; 
    } else if (typeof(window.mozRequestAnimationFrame) != "undefined") { 
     return window.mozRequestAnimationFrame; 
    } else { 
     return function(callback) { 
      window.setTimeout(callback, 1000/60); 
     }; 
    } 
}; 
window.requestAnimFrame = myfunc; 
+0

是的,这是一个合理的解释。然而在JavaScript中,你通常使用伪造而不是显式检查未定义或null。 – Woody

回答

1

JavaScript的逻辑OR(这些都不是二进制的OR)将与“truthy”值的工作 - 例如考虑

window.foo = window.foo || function() {}; 

在这种情况下,因为window.foo不存在,我们将返回第二opearnd,如果那样 - 当时还是想要得到第一个操作数。 null或未定义的值是“falsey” - 尽管还有其他有价值的值 - 谷歌找出它们是什么。

你可以这样阅读:

分配财产requestAnimFrame给调用自身的函数的输出。这是一个奇怪的概念,但是由于JavaScript的范围规则,通常会使用这个概念,它会阻止该函数中的任何变量泄漏到全局范围中。这里要注意的重要一点是第7行最后的()调用第1行开始的函数表达式。

该函数返回window.requestAnimationFrame或window.webkitRequestAnimationFrame或window.mozRequestAnimationFrame或最后如果不是那些存在(因此是错误的)返回实现请求动画帧的函数作为超时 - 这是垫片。

最后你得到requestAnimFrame指向一个函数,它是或者已有的内置函数,具有标准名称或供应商的前缀名称或填充函数。

HTH。

0

第二线正在请求对普通浏览器的新帧。
第三行适用于Chrome,Safari等浏览器。
第四行适用于Mozilla Firefox。
所以它是每个浏览器的一个通用。

和其他人在解释为什么requestAnimationFrame()优于setInterval()setTimeout()

0

此代码正在有效地检查是否存在​​的现有浏览器实现,如果它没有找到一个名称,它将继续通过检查各个浏览器特定的实现来检查它们各自的属性名称。如果全部失败,则最终提供polyfill实施。

要看到这是如何工作的,考虑或操作者的逻辑:

  • 返回左手表达,如果“truthy”,否则返回右手表达。

因此,我们正在有效地遍历一个链,直到找到一个定义的表达式(而不是“falsey”)。请注意,函数是“真理”。

例如,试试这个在您的浏览器控制台:

false || 0 || 1 || "Yes"; // returns 1, the first truthy value 
true || 1 || false || 0; // returns true, the first truthy value 
false || 0 || "Yes"; // returns "Yes", the first truthy value 
false || false || 0; // returns 0, the last value since nothing was truthy 
false || 0 || function() {} || false || 1; // returns function() {} 
0

这只是返回第一个功能是不为空,所以基本上返回正确的功能为用户使用的浏览器。这不是一个二元或它只是一个条件OR运算符。