Skip to content Skip to sidebar Skip to footer

Check If Current Element Is Even Or Odd

Is there an easy way to check whether the current element in a nodeList is an even/odd child of its parent. For example, if have a list of links.
  • Odd

    Solution 1:

    This question is similar to Get an element's nth-child number in pure JavaScript

    How can I check whether the current node is even/odd in relation to its parent?

    The problem with simply incrementing i on every iteration, as all the other answers are doing, is that this calculation makes no relation to the parent node whatsoever. If you notice, none of the existing answers make use of link.parentNode at all!

    Since the calculation isn't aware of the context of the parent node, it basically assumes there is exactly one ul element and all li elements are children of that one ul in order to work correctly. The moment you have nested ul elements or even just multiple ul elements in the same document, it will break.

    Note that the problem is not with the % line. In fact, that is exactly how you determine if an integer is even or odd. The problem is that the index isn't being calculated in relation to the parent node.

    For example, if I modify your list to include a nested ul with exactly one li:

    <ul>
     <li>Odd
      <ul>
       <li>Odd</li>
      </ul>
     </li>
     <li>Even</li>
     <li>Odd</li>
     <li>Even</li>
     <li>Odd</li>
    </ul>
    

    The output will be all wrong once it counts the inner li (the second line):

    [12:07:25.505] odd
    [12:07:25.505] even
    [12:07:25.505] odd
    [12:07:25.505] even
    [12:07:25.506] odd
    [12:07:25.506] even
    

    I wrote a script in an answer to the similar question I linked to above. Here's a quote:

    One way to achieve this that is more foolproof is to loop through the child nodes of each element's parent node, incrementing a counter for each child node that is an element node (since :nth-child() only counts element nodes):

    And here's the script, adapted for your use case:

    var links = document.querySelectorAll("ul li");
    
    for (var i = 0; i < links.length; i++) {
       var link = links[i];
       var parent = link.parentNode;
       var child = parent.firstChild;
       var index = 0;
    
       while (true) {
          if (child.nodeType === Node.ELEMENT_NODE) {
             index++;
          }
    
          if (child === link || !child.nextSibling) {
             break;
          }
    
          child = child.nextSibling;
       }
    
       if (index % 2 == 0) {
          console.log("even");
       }
       else {
          console.log("odd");
       }
    }
    

    Now the output will be correct:

    [12:35:22.273] odd
    [12:35:22.273] odd
    [12:35:22.273] even
    [12:35:22.273] odd
    [12:35:22.273] even
    [12:35:22.273] odd
    

    Again, the second line represents the inner li, which in the modified HTML is the first (and therefore odd) child of its parent ul.

    Solution 2:

    Just check whether i+1 is even or odd

    for (i = 0; i < links.length; i++) {
       var link = links[i];
       var parent = link.parentNode;
    
       if ((i+1)%2 == 0) {
          console.log("even");
       }
       else {
          console.log("odd");
       }
    }
    

    Solution 3:

    Use modulo operator:

    if ((i+1)%2==0) {
          console.log("even");
       }
       else {
          console.log("odd");
       }
    

Post a Comment for "Check If Current Element Is Even Or Odd"