upss1988
upss1988

Reputation: 173

Toggle color on click

I have a list with <a href> and I'm trying to set the color on click.

<a id="mls-category-terms" class="621">Test 1</a>
<a id="mls-category-terms" class="622">Test 2</a>
<a id="mls-category-terms" class="639">Test 3</a>
<a id="mls-category-terms" class="641">Test 4</a>

I've achieved that with the following code:

const homeCategoryList = document.querySelectorAll('#mls-category-terms');
for (let i = 0; i < homeCategoryList.length; i++) {
    homeCategoryList[i].addEventListener('click', () => homeCategoryList[i].setAttribute('style', 'background: #3d5b9a;color: #fff;'));
}

This works, but in this way when I click on another link the color shows up on that link too, but it stays on the previous link as well.

So, the perfect result will be when the user clicks on one link it gets a different color, but if click on another link from that list the previous one will be reset and the last clicked one will get the color.

Here is the image of the current result: https://prnt.sc/12sr23w

Hope that makes sense. I'm quite a newbie in JavaScript.

Upvotes: 0

Views: 190

Answers (4)

LaytonGB
LaytonGB

Reputation: 1404

This can actually be done with the CSS :focus pseudo-class:

.mls-category-terms:link {color:#000}
.mls-category-terms:visited {color:#000}
.mls-category-terms:hover {color:#FF00FF}
.mls-category-terms:active {color:#0000FF}
.mls-category-terms:focus {
  background: #3d5b9a;
  color: #fff;
}
<a class="mls-category-terms 621" href="#">Test 1</a>
<a class="mls-category-terms 622" href="#">Test 2</a>
<a class="mls-category-terms 639" href="#">Test 3</a>
<a class="mls-category-terms 641" href="#">Test 4</a>

This was my preferred method, but as secan's comment below shows, because the :focus pseudo class loses focus regardless of what other element is clicked. Hence, using an .active class and Javascript would be best for the majority of use-cases.

Note also that the mls-category-terms id has been turned into a class.

Upvotes: 1

secan
secan

Reputation: 2669

As mentioned in the comment, IDs should be unique therefore mls-category-terms should be a CSS class. Once you fixed that, you can do:

const links = document.querySelectorAll('.mls-category-terms');

links.forEach(link => {
  link.addEventListener('click', () => {
    links.forEach(l => l.classList.remove('active')); // remove the 'active' class from all links
    link.classList.add('active'); // add the 'active' class only to the clicked one
  })
});
.mls-category-terms.active {
  background-color: #3d5b9a;
  color: #fff;
}
<a id="link1" class="mls-category-terms 621">Test 1</a>
<a id="link2" class="mls-category-terms 622">Test 2</a>
<a id="link3" class="mls-category-terms 639">Test 3</a>
<a id="link4" class="mls-category-terms 641">Test 4</a>

Upvotes: 3

malarres
malarres

Reputation: 2946

You need to keep track of the previous one that got a style and remove it accordingly:

const homeCategoryList = document.querySelectorAll('#mls-category-terms');
let PREV=0;
for (let i = 0; i < homeCategoryList.length; i++) {
    homeCategoryList[i].addEventListener('click', () => {
      homeCategoryList[PREV].removeAttribute('style');
      homeCategoryList[i].setAttribute('style', 'background: #3d5b9a;color: #fff;')
      PREV=i;
    });
}
<a id="mls-category-terms" class="621">Test 1</a>
<a id="mls-category-terms" class="622">Test 2</a>
<a id="mls-category-terms" class="639">Test 3</a>
<a id="mls-category-terms" class="641">Test 4</a>

Upvotes: 1

LaytonGB
LaytonGB

Reputation: 1404

Each click removes the styles that were previously set before adding styles to the newly clicked element.

const homeCategoryList = document.querySelectorAll('#mls-category-terms');
homeCategoryList.forEach(h => h.addEventListener('click', () => toggleColor(h)));

function toggleColor(e) {
  homeCategoryList.forEach(f => f.setAttribute('style', 'background:;color:;'));
  e.setAttribute('style', 'background: #3d5b9a;color: #fff;');
}
<a id="mls-category-terms" class="621">Test 1</a>
<a id="mls-category-terms" class="622">Test 2</a>
<a id="mls-category-terms" class="639">Test 3</a>
<a id="mls-category-terms" class="641">Test 4</a>

Upvotes: 1

Related Questions