0

My intent here is to select the last element that has both the message and theirs classes and a data-msgid attribute:

var theirLastMessage = document.querySelector('#container .message.theirs[data-msgid]:last-child');
console.log(theirLastMessage);
<div id="container">
  <div class="message mine" data-msgid="1"></div>
  <div class="message theirs" data-msgid="2"></div>
  <div class="message mine" data-msgid="3"></div>
  <div class="message theirs" data-msgid="4"></div>
  <div class="message mine" data-msgid="5"></div>
</div>

However, querySelector is returning null, when I want it to be returning the div with data-msgid=4 in this example. Why doesn't this work and how can I get the element I'm looking for?

I'm not sure if my post title is accurate, I don't have my head wrapped around the problem.

Jason C
  • 38,729
  • 14
  • 126
  • 182
  • 2
    There *is* no `:last-child` with both of those classes on. – jonrsharpe Sep 12 '20 at 13:48
  • @jonrsharpe ... `
    ` is the last child with both of those classes isn't it?
    – Jason C Sep 12 '20 at 13:49
  • 2
    You have misunderstood what `:last-child` does, it only matches the *actual last child of the parent*, `
    `. If you want to get the last *of your selected subset*, try `querySelectorAll` and then getting the `.length - 1`th element from it.
    – jonrsharpe Sep 12 '20 at 13:51
  • @jonrsharpe Oh. That's... annoying. All right, thanks. If there's a huge number of matching elements should I expect a performance hit? (Haven't tested yet) – Jason C Sep 12 '20 at 13:52
  • @jonrsharpe The answers there are disappointing but yeah close enough; thanks. – Jason C Sep 12 '20 at 13:54
  • 1
    I was going to answer what John said. Your best approach is to use this, I guess. Otherwise, if you're using jQuery, that has a built-in .last() method: `theirs = document.querySelectorAll('#container .message.theirs[data-msgid]'); console.log(theirs[theirs.length - 1]);` – CssProblem Sep 12 '20 at 13:56

0 Answers0