Home  >  Q&A  >  body text

How can I update the only "active" item in the list?

Suppose you have 4 elements, only one of them can have the class name active. Active elements are updated several times per second (here is a dummy example).

A simple method is:

The problem is that if the selected element has not changed , we are removing the class name, and resetting it (potentially causing display glitches), which doesn't make sense.

Of course, we could add another rule to not remove if it is still a selected element, but the code would become less readable.

Question: Is there a standard mode that can solve this problem?

var i = 0;

setInterval(() => {
    i += 1;
    document.querySelectorAll('.active').forEach(item => item.classList.remove('active'));
    document.querySelector('#item' + Math.floor(i /4)).classList.add('active');
}, 500);
.active { color: red; }
<div id="item0" class="active">item 0</div>
<div id="item1">item 1</div>
<div id="item2">item 2</div>
<div id="item3">item 3</div>

P粉769045426P粉769045426180 days ago394

reply all(1)I'll reply

  • P粉807397973

    P粉8073979732024-04-03 15:01:32

    Summarize

    So it sounds like you're looking for a more elegant way to add and remove the active class of a set of elements. Instead of removing the active class from all elements and then adding it back to the currently active element (this could cause potential issues/visual glitches). And it seems like you are trying to avoid adding too much code to check if the active class needs to be removed/added (if the active element has not changed).

    Potential Solutions

    Personally, I don't think this is the best approach (using the ternary operator for code execution can be confusing), but I think the code is simple enough and quite readable overall.

    Basically, you can merge code to add or remove active classes. The add() function will only add a class if the element currently does not have that class, while the remove() function does the opposite (only removes the class if it exists). This means you can call the add() function on the active element without worrying about any visual glitches if the active element doesn't change.

    Using this logic, we just need to loop through all possible elements, and then using the ternary operator, we can check if an element is the currently active element. If so, call add() (This will have no effect if the active element has not changed), otherwise call remove().

    let i = 0,
        interval;
    
    interval = setInterval(() => {
      i += 1;
      document.querySelectorAll("[id^=item]").forEach(el => (el.id == `item${Math.floor(i / 4)}`) ? el.classList.add("active") : el.classList.remove("active"));
      if(i >= 24) clearInterval(interval);
    }, 500);
    .active { color: red; }
    <div id="item0" class="active">item 0</div>
    <div id="item1">item 1</div>
    <div id="item2">item 2</div>
    <div id="item3">item 3</div>
    <div id="item4">item 4</div>
    <div id="item5">item 5</div>
    <div id="item6">item 6</div>

    Precautions

    This assumes you can loop over all possible active elements. In this case, they all have an id starting with item. Without an identifier that could be used to loop through all possible active elements, more code would need to be added.

    reply
    0
  • Cancelreply