Reputation: 1842
Let's say we have a feature / module, that enhances a website. So it is not really necessary and it uses requestAnimationFrame
, which is not supported in older browsers like IE8/9. I could polyfill requestAnimationFrame
, but since it's just an enhancement, older browsers should simply ignore it. The code for this module looks more or less like this:
;(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 );
I can then create a new instance
var instance = new Module(document.getElementById('test'));
and "interact" with it
instance.init();
instance.method();
The problem with this code is that in IE9 an error pops up because IE9 doesn't know "newer" functions like requestAnimationFrame
. I could just add an if
statement to
if ( window.requestAnimationFrame ) {
var instance = new Module(document.getElementById('test'));
}
and everywhere I use it. It would be much easier to check for requestAnimationFrame
support once somewhere in the module though. If it isn't supported nothing should happen, older browser should just ignore it. So I tried doing something like
// @constructor
function Module( el, options ) {
if ( !window.requestAnimationFrame ) {
return false;
}
//...
}
But that doesn't prevent older browsers from executing all methods like ".init()" or ".method()" (in this case). Do I really have to put this if
statement in every single method or is there anything else i can do?
Upvotes: 0
Views: 2972
Reputation:
The "polyfill" for RAF is just setTimeout
. You can find dozens of examples on the web, usually along the lines of
window.requestAnimationFrame = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
... ||
function (callback) {
setTimeout(callback, 1000 / 60);
};
setTimeout
does the same thing as RAF, just at a lower resolution and without being so optimized with the engine's rendering process. (RAF also passes a hirez timestamp to the callback.)
Bottom line is there's no reason to worry about RAF not being available and how to fall back if it's not. Just fall back to setTimeout
.
If you really want to go without it if it's not available, then just put the following line at the top of your module
var RAF = window.requestAnimationFrame || ... || function() { };
In other words, define it as a null (no-op) function. Then use RAF
variable inside your methods.
Upvotes: 2
Reputation: 113866
I'm not sure why, when you've already figured out the logic, you choose to implement it as a comment instead. Just replace the comments with code and you're good to go:
Module.prototype = {
init: function() {
if(typeof requestAnimationFrame === 'undefined') return;
alert("init");
}
};
Or you can check window.requestAnimationFrame
if you prefer.
ifs
You can encapsulate the if
statement in your own control structure. As usual in javascript, we use functions to implement new 'syntax':
function restricted (f) {
return function () {
if(typeof requestAnimationFrame === 'undefined') return;
return f.apply(this,arguments);
}
}
Now you can define your methods using restricted(function...
instead of function
:
Module.prototype = {
init: restricted(function() {
alert("init");
}),
method: restricted(function() {
alert("start");
})
};
Upvotes: 3
Reputation: 8503
You should definitely polyfill it! It will make your code more concise and it is not 'just an enhancement' for browsers, but in this case also an enhancement for the way you can write and structure your own code. You definitely don't want to go that route that you write methods twice with if blocks. Paul Irish made a great Polyfill for RequestAnimationFrame: http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
This advice also applies to other browser features, not just RequestAnimationFrame, there are great polyfills for about any feature, e.g. github.com/es-shims/es5-shim
Upvotes: 1
Reputation: 8584
Not sure but would this work:?
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() {
}
};
}
Then all browsers cal call init and method but methods won't execute anything if it's not suported. So you only have to make the change in the module.
Upvotes: 0