Please help me understand the "while" loop in this JavaScript snippet
I have seen a snippet like this for detecting IE in JavaScript using conditional comments.
var ie = (function(){
var undef, v = 3, div = document.createElement('div');
// the while loop is used without an associated block: {}
// so, only the condition within the () is executed.
// semicolons arent allowed within the condition,
// so a comma is used to stand in for one
// basically allowing the two separate statements
// to be evaluated sequentially.
while (
div.innerHTML = '<!--[if gt IE '+(++v)+']><i></i><![endif]-->',
div.getElementsByTagName('i')[0]
);
// each time it's evaluated, v gets incremented and
// tossed into the DOM as a conditional comment
// the i element is then a child of the div.
// the return value of the getEBTN call is used as
// the final condition expression
// if there is an i element (the IE conditional
// succeeded), then getEBTN's return is truthy
// and the loop continues until there is no
// more i elements.
// In other words: ** MAGIC**
ret开发者_如何学Curn v > 4 ? v : undef;
}());
The above given is the documented (and slightly improved) version by Paul Irish on a snippet by James Padolsey. I am posting the commented version to let you know that I might need a simpler explanation if anybody may.
I would really like to know what happens inside the while loop. I don't understand that.
(Assuming I haven't bungled this up horribly) the while
loop is equivalent to the following:
var elt;
do
{
v++;
div.innerHTML = '<!--[if gt IE ' + v + ']><i></i><![endif]-->'
elt = div.getElementsByTagName('i')[0];
} (while elt);
does mdc or any good ones cover this while(stmt1, stmt2) thing.
Here's what MDC says about while
:
while (condition) statement
condition
An expression evaluated before each pass through the loop. If this condition evaluates totrue
,statement
is executed. When condition evaluates tofalse
, execution continues with the statement after thewhile
loop.
We can find out exactly what an expression is in JavaScript from MDC:
An expression is any valid set of literals, variables, operators, and expressions that evaluates to a single value; the value can be a number, a string, or a logical value.
Conceptually, there are two types of expressions: those that assign a value to a variable, and those that simply have a value. For example, the expression
x = 7
is an expression that assigns x the value seven. This expression itself evaluates to seven. Such expressions use assignment operators. On the other hand, the expression3 + 4
simply evaluates to seven; it does not perform an assignment. The operators used in such expressions are referred to simply as operators.
If you're feeling brave, you can also check out the ECMA-262 language specification, specifically the following sections:
- 11 Expressions, especially 11.14 Comma Operator (
,
) - 12.6.2 The
while
Statement
Sorry I can't provide direct links as it's all inside of a PDF.
v
stores the IE version number. It is initialised to 3 so the loop creates strings like the following upon each iteration:
// v = 3
<!--[if gt IE 4]><i></i><![endif]-->
// v = 4
<!--[if gt IE 5]><i></i><![endif]-->
If you are confused by this part:
+(++v)+
it simply means, in context, concatenate '<!--[if gt IE '
with the incremented value of v
and then concatenate the newly formed string with ']><i></i><![endif]-->'
The increment operator ++
acts to return the incremented value of v
, since it precedes v
. If it came after v
, the current value of v
would be returned before the increment happens. Mozilla does a better job of explaining than I do:
This operator increments (adds one to) its operand and returns a value. If used postfix, with operator after operand (for example, x++), then it returns the value before incrementing. If used prefix with operator before operand (for example, ++x), then it returns the value after incrementing.
thus the first conditional comment created is always 4. The loop continues until div.getElementsByTagName('i')[0]
does not yield any DOM element, evaluates to false
and forces the loop to exit.
This
<div><!--[if gt IE 6]><i></i><![endif]--></div>
effectively produces a DOM that looks something like
<div><i></i></div>
in versions of IE > 6. But in earlier versions, and browsers that aren't IE at all, it produces
<div></div>
So you put in that "if gt IE version" HTML and depending on whether the i
element is part of the DOM, you can figure out whether you're on a version of IE that's greater than v
. When you get to a value of v
where the i
element exists, you're done!
精彩评论