【问题标题】:How to ignore requestAnimationFrame in browsers which don't support it如何在不支持的浏览器中忽略 requestAnimationFrame
【发布时间】:2014-10-10 10:53:01
【问题描述】:

假设我们有一个功能/模块,可以增强网站。所以它不是真的必要,它使用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 语句吗,或者我还能做些什么吗?

【问题讨论】:

  • 这些答案对你有用吗?
  • @torazaburo 有点,接受了对我最有用的。尚未在接受的答案中看到“附加答案”部分。对不起。

标签: javascript requestanimationframe


【解决方案1】:

我不知道为什么,当您已经弄清楚逻辑后,您选择将其作为注释来实现。只需用代码替换 cmets 即可:

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

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


补充答案:

如何避免写很多ifs

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

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");
    })
};

【讨论】:

  • 我只是有一种更简单的方法,而不必在每个方法中编写相同的 if 语句。
  • 当然,这是 javascript。 if 语句是一个控制结构。将其抽象出来并创建您自己的控制结构。
【解决方案2】:

RAF 的“polyfill”只是setTimeout。你可以在网上找到几十个例子,通常是这样的

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

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

底线是没有理由担心 RAF 不可用以及如果不可用如何回退。回退到setTimeout

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

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

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

【讨论】:

    【解决方案3】:

    你绝对应该 polyfill 它!它将使您的代码更加简洁,它不仅仅是对浏览器的“增强”,而且在这种情况下,它还增强了您编写和构建自己的代码的方式。您绝对不想走您使用 if 块编写两次方法的路线。 Paul Irish 为 RequestAnimationFrame 做了一个很棒的 Polyfill:http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/

    这个建议也适用于其他浏览器功能,不仅仅是 RequestAnimationFrame,任何功能都有很棒的 polyfill,例如github.com/es-shims/es5-shim

    【讨论】:

    • 你可能是对的,但是为 IE10+ 编写比仍然支持 IE8 更容易和更快。不仅仅是 requestAnimationFrame,还有 IE8 的所有这些小变通方法。
    【解决方案4】:

    不确定,但这会起作用吗:?

    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 和方法,但如果不支持,方法将不会执行任何操作。所以你只需要在模块中进行更改。

    【讨论】:

    • 我认为它应该可以工作,但是我必须将每个方法编写两次。
    • @demrks 是的,你必须这样做。另一种选择是将if ( window.requestAnimationFrame ) 放在每个函数、init 和方法的请求处。你已经提到了这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-27
    • 1970-01-01
    • 2010-12-27
    • 2022-11-14
    • 2011-12-02
    • 1970-01-01
    相关资源
    最近更新 更多