1

I have nested carousels and i need to select only the buttons from each carousel ( and not the ones in nested carousels )

So I need the reverse that .closest does..

This is how I'm trying

const container = document.querySelector('#selector');
document.querySelector('span').innerHTML = container.querySelectorAll(':not(.carrousel-container) .carousel_container__button').length
<div class="carrousel-container" id="selector">
   <button class="carousel_container__button">The only one i want</button>
   
   <div class="carrousel-container">
     <button class="carousel_container__button">other carousel button</button>
   </div>
   <div class="carrousel-container">
     <button class="carousel_container__button">other carousel button</button>
   </div>
</div>

<p>Found items: <span></span></p>

But I always get 3 and i need to select just the first one.

Why is the :not() not enough?

Note that I can't use > button because the content is very different in each

Toni Michel Caubet
  • 19,333
  • 56
  • 202
  • 378
  • 2
    Use immediate child selector i.e `':scope > .carousel_container__button'` – Satpal Jul 09 '20 at 10:49
  • I'm afraid there is no standard CSS selector for your case. You will have to filter your result yourself. For example, get all buttons and then check if the closest carousel-container is the container you started your search from. – cloned Jul 09 '20 at 11:03
  • What does it mean that "the content is very different in each"? How different? How do you expect us to find a selector for you when you say "I want to find a random element in a random structure"? What's fixed? On which basis can we try to build something? Satpal's comment is the most straightforward solution to what you shown, David's solution also does that, still you claim they won't match your real case... Explain that real case to us. – Kaiido Jul 09 '20 at 11:49
  • but thanks about the `:scope` thing ^^ – Toni Michel Caubet Jul 09 '20 at 22:46

3 Answers3

0

<div class="carrousel-container" id="selector">
   <button class="carousel_container__button">The only on i want</button>
   
   <div class="carrousel-container">
     <button class="carousel_container__button">other carousel button</button>
   </div>
   <div class="carrousel-container">
     <button class="carousel_container__button">other carousel button</button>
   </div>
</div>

<p>Found items: <span></span></p>
<script>
const container = document.querySelector('#selector');
document.querySelector('span').innerHTML = container.querySelectorAll('#selector.carrousel-container > *.carousel_container__button').length
</script>

how is that? with "#selector.carrousel-container > *.carousel_container__button" instead.

David Peer
  • 150
  • 1
  • 1
  • 12
0

There is no standard selector to achieve what you want, you have to build the logic yourself. Something like this, with === you can check if two DOM Nodes are the same.

You can directly do something at the point with the button or you can, for example, append it to an array to use it at a later point or in combination with other functions. Depends on what you want to do in the end.

const container = document.querySelector('#selector');

let buttons = container.querySelectorAll('.carousel_container__button');

buttons.forEach( (button) => {
  if (button.closest('.carrousel-container') === container) {
    console.log(button); // here we have the correct button, do with it what you want. 
  }
});


document.querySelector('span').innerHTML = container.querySelectorAll(':not(.carrousel-container) .carousel_container__button').length
<div class="carrousel-container" id="selector">
   <button class="carousel_container__button">The only one i want</button>
   
   <div class="carrousel-container">
     <button class="carousel_container__button">other carousel button</button>
   </div>
   <div class="carrousel-container">
     <button class="carousel_container__button">other carousel button</button>
   </div>
</div>

<p>Found items: <span></span></p>
cloned
  • 6,346
  • 4
  • 26
  • 38
0

You can simply use document.querySelectorAll('#selector > *') and then compare elements you could have used because it's a selector it assumes you should know which element next you want to select luje "#selector > button" but since you aim for a generic selection you can use this method

const container = document.querySelectorAll('#selector > *')
counter=1
Array.from(container).reduce((el,sec)=>{
  if(el.tagName==sec.tagName){
counter++;
return sec}
else return false})
document.querySelector('span').innerHTML = counter
<div class="carrousel-container" id="selector">
  <button class="carousel_container__button">The only one i want</button>
  
  <div class="carrousel-container">
    <button class="carousel_container__button">other carousel button</button>
  </div>
  <div class="carrousel-container">
    <button class="carousel_container__button">other carousel button</button>
  </div>
</div>

<p>Found items: <span></span></p>
Sven.hig
  • 4,449
  • 2
  • 8
  • 18