'h1:nth-child(5)' selects 3rd and not 5th child

Viewed 77

To the best of my knowledge these are all the H1 tags in index.html.

<h1 class='header'>Hello, world (1)</h1>
<h1 class='header'>Hello, world (2)</h1>
<h1 class='header'>Hello, world (3)</h1>
<h1 class='header'>Hello, world (4)</h1>
<h1 class='header'>Hello, world (5)</h1>
<h1 class='header'>Hello, world (6)</h1>

<h1 class='header' id='header-3'>Hello, world (Header 3)(1)</h1>
<h1 class='header' id='header-3'>Hello, world (Header 3)(2)</h1>

I checked the console logs and they implied I had 8 H1 elements.

 var $header = $(".header")        
 console.log("header length")
 console.log($header.length)

When I wrote this $('h1:nth-child(5)').text("Ironman") I expected it to adjust the 5th H1 element. Whereas it actually adjusts the 4th.

When I wrote this $('h1:nth-child(4)').text("Thanos") I expected it to adjust the 4th element. Whereas it actually adjusts the 3rd.

According to w3schools (https://www.w3schools.com/jquery/sel_nthchild.asp) the first element has the index number 1.

Could anyone provide clarification as to what is going on?

Update

Here is all my code (apologies for the messy way it pasted into StackOverflow).

<!DOCTYPE html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">

     <style>
    /*body {
      background-color: red;
    }*/
    h1 {
      color: green;
    }

    #header-3 {

    }
    .description {
      width: 250px;
      height: 300px;
    }
  </style>


  </head>
  <body>

<script src='https://code.jquery.com/jquery-3.2.1.min.js'></script>

    <h1 class='header' id='header-3'>Hello, world (Header 3)(1)</h1>
    <h1 class='header' id='header-3'>Hello, world (Header 3)(2)</h1>
   

 
   <script type="text/javascript">
      $(document).ready(function(){

    
        var $header = $(".header")        
        console.log("header length")
        console.log($header.length)
        

        setTimeout(function(){
            $('body').css("background-color", "blue")
            $('h1').css("color", "purple")
            $('h1').text("Batman")
            $('h1:nth-child(5)').text("Ironman")
            $('#header-3').text("Captain America")
            $(".header").css("background-color", "green").css("padding", "30px")
        }, 6500) // in ms
     

        setTimeout(function(){
            $('body').css("background-color", "yellow")
            $('h1').css("color", "purple")
            $('h1:nth-child(1)').text("Wolverine")
            $('h1:nth-child(2)').text("Magneto")
            $('h1:nth-child(4)').text("Thanos")
            $(".header").css("background-color", "green").css("padding", "30px")
        }, 8500) // in ms
      
 })

   </script>




    <p class='description'>Another Paragraph</p>
    <p class='description'>It turns out self-driving cars aren’t dissimilar from self-driving humans: 
Today, a generation removed from the seminal 2004 Darpa challenge in which the 

“The hype got ahead of the reality, but honestly, it’s gone way faster than I would have ever believed,” says 

automaker still hopes to fulfill that vision by 2021.

Nuro, which rounded up $1 billion from SoftBank, said the cash being deposited in the self-driving landscape has provided a critical slug of optimism. “It doesn’t change our plan or our mission,

</p>




 
   <script type="text/javascript">
      $(document).ready(function(){


        var $description = $(".description")
  

       
        console.log($description.css("height"))
       
        console.log($description.height())


       
       
      
 })

   </script>



   <!-- Optional JavaScript -->
    <!--  Popper.js first, then Bootstrap JS -->

    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script>
  </body>
</html>

Update 2

Thank you j08691 for your answer.

1 Answers

The issue with your example is in your implementation. As the docs for jQuery's :nth-child say (emphasis mine):

The :nth-child(n) pseudo-class is easily confused with the .eq( n ) call, even though the two can result in dramatically different matched elements. With :nth-child(n), all children are counted, regardless of what they are, and the specified element is selected only if it matches the selector attached to the pseudo-class.

In other words, :nth-child doesn't care what the nth element is, it counts everything, and in your example the script element is a child of the body, so it's being counted. If you move it to the end of the page, it works as you expect

$('h1:nth-child(4)').text("Ironman");
<h1 class='header'>Hello, world (1)</h1>
<h1 class='header'>Hello, world (2)</h1>
<h1 class='header'>Hello, world (3)</h1>
<h1 class='header'>Hello, world (4)</h1>
<h1 class='header'>Hello, world (5)</h1>
<h1 class='header'>Hello, world (6)</h1>

<h1 class='header' id='header-3'>Hello, world (Header 3)(1)</h1>
<h1 class='header'>Hello, world (Header 3)(2)</h1>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

One alternative that would do what you would expect and leave the script element as first is :nth-of-type:

$('h1:nth-of-type(4)').text("Ironman");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1 class='header'>Hello, world (1)</h1>
<h1 class='header'>Hello, world (2)</h1>
<h1 class='header'>Hello, world (3)</h1>
<h1 class='header'>Hello, world (4)</h1>
<h1 class='header'>Hello, world (5)</h1>
<h1 class='header'>Hello, world (6)</h1>

<h1 class='header' id='header-3'>Hello, world (Header 3)(1)</h1>
<h1 class='header'>Hello, world (Header 3)(2)</h1>

Related