Friday, April 8, 2011

jQuery nth-child counts wrong in IE ??

I came across an interesting problem today, we are using a nth-child selector in jQuery.

$(".tag_even tr:nth-child(2n)").addClass('even');

Somehow a person code something wrong in the table, he inserted a <div> as one of the <tr>.

Because the selector in jQuery target at "tr", so the div should be ignored.  It make senses, right?

This assumption is true for FF / Chrome and Safari, but IE still count the "div" in? What the hack??

It is because IE wrap the table each children elements with a "nodeIndex", and jQuery when in IE, it uses "nodeIndex" for counting the nodes, no matter it is a "tr" or not.  The below is how jQuery implement the nth-child selector, and please look at the "bold" part that it is using "nodeIndex".


                CHILD: function(elem, match){ 
                // ... 
                        case 'nth': 
                                        var first = match[2], last = match[3]; 
                                        if ( first == 1 && last == 0 ) { 
                                                return true; 
                                        } 
                                        var doneName = match[0], 
                                                parent = elem.parentNode; 
                                        if ( parent && (parent.sizcache !== doneName || ! 
elem.nodeIndex) ) { 
                                                var count = 0; 
                                                for ( node = parent.firstChild; node; node = node.nextSibling ) { 
                                                        if ( node.nodeType === 1 ) { 
                                                                node.nodeIndex = ++count; 
                                                        } 
                                                } 
                                                parent.sizcache = doneName; 
                                        } 
                                        var diff = elem.nodeIndex - last; 
                                        if ( first == 0 ) { 
                                                return diff == 0; 
                                        } else { 
                                                return ( diff % first == 0 && diff / first >= 0 ); 
                                        } 
                        } 
                // ... 
                }, 


No comments:

Post a Comment