Home > Enterprise >  How to alternate class between elements and go back to original when none of elements is selected
How to alternate class between elements and go back to original when none of elements is selected

Time:12-10

I'd like to request your help. Here's what I'm trying to do.

I have a grid of six items. I wanna make the first item actived by default and whenether the user moves the mouse over one of the five remaing grid items, the class will be remove from the first item and applied the the current selected item. Once there's no object with the cursor over it. The class will automatically be applied to the first element again.

const cards = document.querySelectorAll('.card');

function cardSelect() {
  cards.forEach(card => {
    card.addEventListener('mouseenter', () => {
      card.classList.add('active');
    });
    card.addEventListener('mouseleave', () => {
      card.classList.remove('active');
    });

    //If there's no actived element, then apply active class to the first item
    if (!card.classList.contains('active')) {
      cards[0].classList.add('active');
      //If there's any actived element, then remove the active class from the first item
    } else {
      cards[0].classList.remove('active');
    }
  })
}
cardSelect();
.grid {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(2, 200px);
  grid-template-areas: "item1 item2 item3" "item4 item5 item6";
}


/* line 1152, ../../PCX/sass/scss/style.scss */

.grid .card {
  color: #fff;
  font-size: 2rem;
  background-color: #0077ff;
  display: flex;
  align-items: center;
  justify-content: center;
}


/* line 1160, ../../PCX/sass/scss/style.scss */

.grid .card.active {
  background-color: #0000ee;
}


/* line 1164, ../../PCX/sass/scss/style.scss */

.grid .item1 {
  grid-area: item1;
}


/* line 1167, ../../PCX/sass/scss/style.scss */

.grid .item2 {
  grid-area: item2;
}


/* line 1170, ../../PCX/sass/scss/style.scss */

.grid .item3 {
  grid-area: item3;
}


/* line 1173, ../../PCX/sass/scss/style.scss */

.grid .item4 {
  grid-area: item4;
}


/* line 1176, ../../PCX/sass/scss/style.scss */

.grid .item5 {
  grid-area: item5;
}


/* line 1179, ../../PCX/sass/scss/style.scss */

.grid .item6 {
  grid-area: item6;
}
<div >
  <div >ITEM 1</div>
  <div >ITEM 2</div>
  <div >ITEM 3</div>
  <div >ITEM 4</div>
  <div >ITEM 5</div>
  <div >ITEM 6</div>
</div>

Could you guys give me a hand? It's a logic issue and lack of js knowledge.

CodePudding user response:

I think, whenever the cursor enter or leaves a card, you can clear them all (which I put in a function).

If it enters a card, add the active class to this card.

If it leaves a card, set the active class to the first card.

const cards = document.querySelectorAll('.card');
cards[0].classList.add('active');

function clearAll() {
  cards.forEach(card => card.classList.remove('active'));
}

cards.forEach(card => {
    card.addEventListener('mouseenter', () => {
      clearAll();
      card.classList.add('active');
    });
    card.addEventListener('mouseleave', () => {
      clearAll()
      cards[0].classList.add('active');
    });
})
.grid {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(2, 200px);
  grid-template-areas: "item1 item2 item3" "item4 item5 item6";
}


/* line 1152, ../../PCX/sass/scss/style.scss */

.grid .card {
  color: #fff;
  font-size: 2rem;
  background-color: #0077ff;
  display: flex;
  align-items: center;
  justify-content: center;
}


/* line 1160, ../../PCX/sass/scss/style.scss */

.grid .card.active {
  background-color: #0000ee;
}


/* line 1164, ../../PCX/sass/scss/style.scss */

.grid .item1 {
  grid-area: item1;
}


/* line 1167, ../../PCX/sass/scss/style.scss */

.grid .item2 {
  grid-area: item2;
}


/* line 1170, ../../PCX/sass/scss/style.scss */

.grid .item3 {
  grid-area: item3;
}


/* line 1173, ../../PCX/sass/scss/style.scss */

.grid .item4 {
  grid-area: item4;
}


/* line 1176, ../../PCX/sass/scss/style.scss */

.grid .item5 {
  grid-area: item5;
}


/* line 1179, ../../PCX/sass/scss/style.scss */

.grid .item6 {
  grid-area: item6;
}
<div >
  <div >ITEM 1</div>
  <div >ITEM 2</div>
  <div >ITEM 3</div>
  <div >ITEM 4</div>
  <div >ITEM 5</div>
  <div >ITEM 6</div>
</div>

CodePudding user response:

The good news is you don't need JavaScript to do this - CSS will do the trick (see code comment)

/* no js needed */
.grid {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(2, 200px);
  /* 
    You don't need grid areas for this layout :-) 
  */
}


/* 
  The trick 
  if you are not hovering the grid .grid:not(:hover) 
  then set the active color on .item1.card

  if you are hovering a card .card:hover set the active 
  color on that
  
  when you are hovering a card you are also hovering the 
  grid why the item1.card will turn back to normal...
  unless you hover it – then it uses the .card:hover rule    
 
  I hope it made sense :-)

*/
.grid:not(:hover) .item1.card,
.card:hover {
  background-color: #0000ee;
}  


.card {
  color: #fff;
  font-size: 2rem;
  background-color: #0077ff;
  display: flex;
  align-items: center;
  justify-content: center;
}
<div >
  <div >ITEM 1</div>
  <div >ITEM 2</div>
  <div >ITEM 3</div>
  <div >ITEM 4</div>
  <div >ITEM 5</div>
  <div >ITEM 6</div>
</div>

  • Related