skip to Main Content

I’m struggling to find a solution that allows me to update the following code to include additional classes. E.g. in addition to .section–bg1, I’d like to include .section–bg2. and .section–bg3.

For further context, here’s a Fiddle:

How can I include the red coloured background section (.section–bg2) in the JavaScript?

I’ve tried "el.classList.contains('section--bg1', 'section--bg2');" but that is not working. What am I missing?

// active section
if ( (sectionTop <= replaceItemBottom) && (sectionBottom > replaceItemTop)) {
  // check if current section has bg
  currentSection = el.classList.contains('section--bg1');

  // switch class depending on background image
  if ( currentSection ) { 
    replaceContainer[0].classList.remove('js-replace--reverse');
  } else {
    replaceContainer[0].classList.add('js-replace--reverse')
  }
}

4

Answers


  1. To include multiple classes in the el.classList.contains() check, you should use separate classList.contains() calls for each class you want to check. Here’s how you can modify your code to include both .section–bg1 and .section–bg2:

    // active section
    if (sectionTop <= replaceItemBottom && sectionBottom > replaceItemTop) {
      // check if current section has bg1 or bg2
      const hasBg1 = el.classList.contains('section--bg1');
      const hasBg2 = el.classList.contains('section--bg2');
      const hasBg3 = el.classList.contains('section--bg3');
    
      // switch class depending on background image
      if (hasBg1 || hasBg2 || hasBg3) {
        replaceContainer[0].classList.remove('js-replace--reverse');
      } else {
        replaceContainer[0].classList.add('js-replace--reverse');
      }
    }
    Login or Signup to reply.
  2. Use matches() to check whether an element contains ANY of classes:

    https://developer.mozilla.org/en-US/docs/Web/API/Element/matches

    console.log($div.matches('.class1,.class2'));
    console.log($div2.matches('.class1,.class2'));
    <div id="$div" class="class1"></div>
    <div id="$div2" class="class2"></div>

    Applying to your code, use also classList.toggle() to make the code shorter:

    // active section
    if ( (sectionTop <= replaceItemBottom) && (sectionBottom > replaceItemTop)) {
    
      // switch class depending on background image
      replaceContainer[0].classList.toggle('js-replace--reverse', !el.matches('.section--bg1,.section--bg2,.section--bg3'));
    
    Login or Signup to reply.
  3. The contains method only accepts a single token.

    You need to call the method twice with each different class and AND the conditions:

    if (
      el.classList.contains('section--bg1') &&
      el.classList.contains('section--bg2')
    ) {
      // ...
    }
    

    If you want to be fancy, you can write a convenience function:

    const containsAll = (arr, ...tokens) =>
      tokens.every(token => arr.contains(token));
    
    const containsOne = (arr, ...tokens) =>
      tokens.some(token => arr.contains(token));
    
    const foo = document.querySelector('#foo');
    
    console.log(containsAll(foo.classList, 'bar', 'baz'));
    
    console.log(containsOne(foo.classList, 'beep', 'boop', 'bar'));
    <div id="foo" class="bar baz"></div>
    Login or Signup to reply.
  4. You can’t do that using classList.contains, but maybe this alternative works for you:

    document.querySelectorAll(`div`)
      .forEach( el => 
        console.log(`${el.outerHTML} => ${
        [...el.classList].includes(`class1`, `class3`) }` ) );
    <div class="class1 class3">.class1 .class3</div>
    <div class="class2">.class2</div>
    <div>no class</div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search