0

Is it possible with js select specific elements that don't contain a specific part of the class like for example:

// This line seems to be an invalid query parameter, so I am curious if it's actually feasible to achieve that?
const queryResult = document.querySelectorAll(`ul:not('.*__list')`);

const queryResult = document.querySelectorAll(`ul`);
console.log(queryResult)
<div>
  <ul>
    <li>item</li>
    <li>item</li>
    <li>item</li>
    <li>item</li>
    <button>button</button>
  </ul>
  <ul class="abstractPrefix__list">
    <li>
      <button class="abstractPrefix__button">button</button>
    </li>
  </ul>
</div>

2 Answers 2

2

If you are sure that the class attribute always ends with __list, then you can use the attribute selector [class$='__list'].

const queryResult = document.querySelectorAll(`ul:not([class$='__list'])`);
console.log(queryResult)
<div>
  <ul>
    <li>item</li>
    <li>item</li>
    <li>item</li>
    <li>item</li>
    <button>button</button>
  </ul>
  <ul class="abstractPrefix__list">
    <li>
      <button class="abstractPrefix__button">button</button>
    </li>
  </ul>
</div>

However, this selector will fail if your class list looks like this: class="abstractPrefix__list my_random_class", since it will no longer match the CSS attribute selector stated above. In this case, you will need a JS-based solution:

const queryResult = Array.from(document.querySelectorAll('ul')).filter(el => {
  const classes = Array.from(el.classList);
  for (let cl of classes) {
    if (cl.match(/__list$/gi)) {
      return false;
    }
    
    continue;
  }
  
  return true;
});
console.log(queryResult)
<div>
  <ul>
    <li>item</li>
    <li>item</li>
    <li>item</li>
    <li>item</li>
    <button>button</button>
  </ul>
  <ul class="abstractPrefix__list my_random_class">
    <li>
      <button class="abstractPrefix__button">button</button>
    </li>
  </ul>
</div>

Sign up to request clarification or add additional context in comments.

Comments

1

Documentation:

https://drafts.csswg.org/selectors/#overview

Inside this page, read this:

E[foo*="bar"] an E element whose foo attribute value contains the substring bar

E:not(s1, s2, …) an E element that does not match either compound selector s1 or compound selector s2

So you have to use something similar to this:

document.querySelectorAll('ul:not([class*="__list"])')

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.