0
\$\begingroup\$

I am attempting to do something that seems pretty simple, but I'm not sure if it as performant as it could be. I'm looking to cycle through a set of elements and toggle a class to only show a single item at a time, looping back to the first item at the end.

$(document).ready(() => {
  const toggleButton = $('.btn-toggle');
  toggleButton.on('click', function toggleButtonClick() {
    const currentItem = $(this).parent('.itemtoggle')
      .find('li:not(.d-none)').toggleClass('d-none');
    let nextItem = currentItem.next();
    if (nextItem.length === 0) {
      nextItem = currentItem.parent('.items').find('li');
    }
    nextItem.first().toggleClass('d-none');
  })
  .parent('.itemtoggle')
  .find('li')
  .toggleClass('d-none')
  .first()
  .toggleClass('d-none');
});

Full code example on Codepen

Right now it is written using jQuery. Is there a better way to do this, in jQuery, Vanilla JS, or other?

\$\endgroup\$
1
\$\begingroup\$

You are doing a lot of DOM traversal. I'll show you the updated code and explain it.

HTML

<div class="itemtoggle">
  <ul class="items">
    <li>Item 1</li>
    <li class="d-none">Item 2</li>
    <li class="d-none">Item 3</li>
    <li class="d-none">Item 4</li>
  </ul>
  <button type="button" class="btn-toggle">Toggle Next</button>
</div>

CSS

.d-none {
  display: none;
}

JAVASCRIPT

$(document).ready(() => {
  const toggleButton = $('.btn-toggle');
  const items = document.querySelectorAll('.items > li');
  let index = 0;
  toggleButton.on('click', () => {
     $(items[index]).toggleClass('d-none');
     index = index + 1;
     if(index === items.length){
       index = 0;
     }
     $(items[index]).toggleClass('d-none');
  });
});

I updated the HTML so that the li's after the first have display none. In your previous code this was the initial state, so its better to set it in the HTML than using JavaScript to do it.

What i have done in JavaScript is that i store all <li> and an associated index, then when you press Toggle Next, i just toggle the <li> at the current index, and increment index by 1, if index === items.length, then it must mean we are out of bounds, because items[4] would be undefined, so we have to reset it to 0.

After increment, we toggle d-none on the new index.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.