Reputation: 10250
i was just going through the code of modenizer , because i need to implement a little feature detection in my small online application . so the check i need is for cssTransform3d
I.E to check for 3dTranforms ,if its available in the browser.
tests['csstransforms3d'] = function() {
var ret = !!testPropsAll('perspective');
if ( ret && 'webkitPerspective' in docElement.style ) {
injectElementWithStyles('@media (transform-3d),(-webkit-transform-3d){
#modernizr{left:9px;position:absolute;height:3px;}
}',
function( node, rule ) {
ret = node.offsetLeft === 9 && node.offsetHeight === 3;
});
}
return ret;
};
now check the callback function inside injectElementWithStyles
, there are two params being passed , node
and rule
, who is passing these parameters ? i see nowhere in the global variable declaration that these variables are being declared.
The injectElementWithStles function is as follows ::
injectElementWithStyles = function( rule, callback, nodes, testnames ) {
var style, ret, node, docOverflow,
div = document.createElement('div'),
body = document.body,
fakeBody = body || document.createElement('body');
if ( parseInt(nodes, 10) ) {
while ( nodes-- ) {
node = document.createElement('div');
node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
div.appendChild(node);
}
}
style = ['­','<style id="s', mod, '">', rule, '</style>'].join('');
div.id = mod;
(body ? div : fakeBody).innerHTML += style;
fakeBody.appendChild(div);
if ( !body ) {
fakeBody.style.background = '';
fakeBody.style.overflow = 'hidden';
docOverflow = docElement.style.overflow;
docElement.style.overflow = 'hidden';
docElement.appendChild(fakeBody);
}
ret = callback(div, rule);
if ( !body ) {
fakeBody.parentNode.removeChild(fakeBody);
docElement.style.overflow = docOverflow;
} else {
div.parentNode.removeChild(div);
}
return !!ret;
},
now i am relatively new to js , yet i have tried making sense of both these functions , as far as i know a variable or parameter needs to be initialized/declared before being passed ,but i don't see either node
or rule
being declared , can somebody explain what is happening and what values do these variables take ?
Thank you.
Alex-z.
Upvotes: 0
Views: 75
Reputation: 9290
So, let me try to explain.
Signature for the injectElementWithStyles
is rule, callback, nodes, testnames
which means that those are the parameters it's expecting.
When that function is called, it's passing just rule
and callback
:
injectElementWithStyles(
'@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}', function( node, rule ) {
ret = node.offsetLeft === 9 && node.offsetHeight === 3;
});
So, bear in mind that the function is the second parameter to the injectElementWithStyles
function. Note that the function being passed (the one that confuses you) is not being invoked just yet, it's being passed as a parameter to the injectElementWithStyles
.
Within that function, the callback is called like this:
ret = callback(div, rule);
Which, as you see, matches the signature of the callback passed: That is, div
is node
and rule
is... well... rule
.
Is in that moment that the execution flow goes to the troubling function and node
will have the value of div
(declared in that function) and rule
will hold the value of rule
(declared in that function too)
Hope this clarifies!
Now, you may want to look at Modernizr.addTest
which accepts a rule name and a function to be evaluated that must return true or false. So, in your app, let's say you want to test if you're in production:
Modernizr.addTest('production', function () {
return window.isProduction;
});
That will add the class production
to the HTML element if window.isProduction
is true
and no-production
otherwise.
Upvotes: 1