如何在不支持它的浏览器中忽略requestAnimationFrame

时间:2014-10-10 10:53:02

标签: javascript requestanimationframe

假设我们有一个功能/模块,可以增强网站。所以它并不是必需的,它使用requestAnimationFrame,它是not supported in older browsers,如IE8 / 9。我可以填充requestAnimationFrame,但由于它只是一个增强功能,旧浏览器应该忽略它。这个模块的代码或多或少看起来像这样:

;(function( window, document, undefined ) {
    'use strict';

    // Example Module
    // @constructor
    function Module( el, options ) {            
        // ...
    }

    Module.prototype = {
        init: function() {
            // If requestAnimationFrame is not supported, no alert should pop up        
            alert("init");
        },

        method: function() {
            // If requestAnimationFrame is not supported, no alert should pop up
            alert("start");
        }
    };

    window.Module = Module;

})( window, document );

然后我可以创建一个新实例

var instance = new Module(document.getElementById('test'));

并与之“互动”

instance.init();
instance.method();

此代码的问题是在IE9中弹出错误,因为IE9不知道像requestAnimationFrame这样的“更新”功能。我可以在

中添加if语句
if ( window.requestAnimationFrame ) {
    var instance = new Module(document.getElementById('test'));
}

我到处使用它。但是,在模块中的某个位置检查requestAnimationFrame支持要容易得多。如果不支持则不应该发生任何事情,旧浏览器应该忽略它。所以我尝试了像

这样的事情
// @constructor
function Module( el, options ) {            
    if ( !window.requestAnimationFrame ) {
        return false;
    }
    //...
}

但这并不妨碍旧浏览器执行所有方法,如“.init()”或“.method()”(在本例中)。我是否真的必须在每个方法中加上if语句,还是我还能做什么?

4 个答案:

答案 0 :(得分:3)

我不确定为什么,当你已经弄清楚逻辑时,你选择将它作为评论来实现。只需用代码替换注释,就可以了:

Module.prototype = {
    init: function() {
        if(typeof requestAnimationFrame === 'undefined') return;        
        alert("init");
    }
};

或者,如果您愿意,可以查看window.requestAnimationFrame


补充答案:

如何避免编写许多ifs

您可以将if语句封装在您自己的控制结构中。像往常一样在javascript中,我们使用函数来实现新的'syntax':

function restricted (f) {
    return function () {
        if(typeof requestAnimationFrame === 'undefined') return;
        return f.apply(this,arguments);
    }
}

现在,您可以使用restricted(function...代替function来定义方法:

Module.prototype = {
    init: restricted(function() {
        alert("init");
    }),

    method: restricted(function() {
        alert("start");
    })
};

答案 1 :(得分:2)

" polyfill" RAF只是setTimeout。你可以在网上找到几十个例子,通常是

window.requestAnimationFrame = window.requestAnimationFrame || 
    window.webkitRequestAnimationFrame ||
    ... || 
    function (callback) {
        setTimeout(callback, 1000 / 60);
    };

setTimeout与RAF做同样的事情,只是在较低的分辨率下,并没有通过引擎的渲染过程进行优化。 (英国皇家空军还将一个hirez时间戳传递给回调。)

最重要的是,没有理由担心RAF无法使用,如果不可用则如何退回。回到setTimeout

如果你真的想要没有它,如果它不可用,那么只需将以下行放在你的模块顶部

var RAF = window.requestAnimationFrame || ... || function() { };

换句话说,将其定义为null(无操作)函数。然后在方法中使用RAF变量。

答案 2 :(得分:1)

你绝对应该填充它!它将使您的代码更简洁,它不仅仅是浏览器的“增强”,但在这种情况下,还可以增强您编写和构建自己的代码的方式。你肯定不想去那些用if块写两次方法的路径。 Paul Irish为RequestAnimationFrame制作了一个很棒的Polyfill:http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/

此建议也适用于其他浏览器功能,而不仅仅是RequestAnimationFrame,对于任何功能都有很好的填充功能,例如github.com/es-shims/es5-shim

答案 3 :(得分:0)

不确定但这会有效吗?

if ( window.requestAnimationFrame ){
     Module.prototype = {
        init: function() {
            // If requestAnimationFrame is not supported, no alert should pop up        
            alert("init");
        },

        method: function() {
            // If requestAnimationFrame is not supported, no alert should pop up
            alert("start");
        }
    };
}
else{
  Module.prototype = {
    init: function() {
    },

    method: function() {
    }
   };
}

然后所有浏览器调用init和方法,但如果没有支持,方法将不会执行任何操作。所以你只需要在模块中进行更改。