jQuery's “:last-child” selector won't resp

2019-02-23 17:36发布

问题:

I have this simple HTML :

<body>
  <a>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
  </a>
</body>

The divs are children of <a>.

From jQuery :

:last-child Selector — Selects all elements that are the last child of their parent.

Ok , Running this code :

 $("div:last-child" ).css('background-color','red')

Will yield :

Ok , let's remove <a> so that divs will be direct children of the Body

<body>

    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>

</body>

Result : Nothing is painted. (http://jsbin.com/kamepu/4)

Question

Those divs are children of Body. why it is not working ?

NB I know I can use last. but that's not my question.

回答1:

If you look at the DOM, JS Bin inserts some script elements before the closing </body> tag, which prevents any of the divs from matching div:last-child. Remember that although script elements are (usually) not rendered, they do exist in the DOM just like any other HTML element, and as a result will affect selector matching.

The last div is in fact the last of its type, even if it isn't the very last child of body; you can verify this by switching to :last-of-type and it will match.

As mentioned in the comments, Stack Snippets does this as well:

div:last-child { text-decoration: underline; }
div:last-of-type { color: red; }
<body>
  <div>Red but no underline</div>
</body>



回答2:

:last-child returs true is the very last child is of this type (div in this case).

JSBin links scripts at the bottom of the page (before </body>), so :last-child can works with script element only.

Solution is to move scripts into head section using document.ready or after </body>.