Richard Bustos
Richard Bustos

Reputation: 2998

Adding a class to an element with a specific class

I'm looking for a way to add a class to a certain element with another class.

<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li class="hide">Item 4</li>
  <li class="hide">Item 5</li>
<ul>

JS/Jquery

if($('li').hasClass('hide')) {
  $('li').removeClass('hide').addClass('slide-down');
}

The problem is that the class slide-down gets added to all li elements.

Is there a way to only target the li elements that have the hide class removed?

Upvotes: 2

Views: 80

Answers (3)

iH8
iH8

Reputation: 28628

Plain javascript for the ones with querySelectorAll and classList support:

var items = document.querySelectorAll('li.hide');
for (var i = 0; i < items.length; i++) {
    items[i].classList.remove('hide');
    items[i].classList.add('slide-down');
}

Without querySelectorAll:

var items = document.getElementsByTagName('li');
for (var i = 0; i < items.length; i++) {
    if (items[i].classList.contains('hide')) {
        items[i].classList.remove('hide');
        items[i].classList.add('slide-down');
    }
}

Without querySelectorAll and classList:

var items = document.getElementsByTagName('li');
for (var i = 0; i < items.length; i++) {
    if (new RegExp(/(?:^|\s)hide(?!\S)/g).test(items[i].className)) {
        items[i].className = items[i].className.replace(/(?:^|\s)hide(?!\S)/g , '');
        items[i].className += ' ' + 'slide-down';
    }
}

Upvotes: 0

Federico
Federico

Reputation: 3920

In vanilla JS:

var liHide = document.querySelectorAll('li.hide');
var i;
var length = liHide.length;

for (i=0;i<length;i++) {
    liHide[i].className = 'slide-down';
}

Note that, for some reason, querySelectorAll doesn't get updated automatically like document.getElementsByClassName. The same code wouldn't work if we would have used that method for querying the DOM:

var liHide = document.getElementsByClassName('hide');
var i;
var length = liHide.length;

for (i=0;i<length;i++) {
    liHide[i].className = 'slide-down'; //<-- this won't update the 2nd element
}

This would have only changed the first element, since liHide[1] becomes liHide[0], because <li class="hide">Item 4</li> is no longer part of HTML Collection.

Upvotes: 0

sled
sled

Reputation: 14625

Mh maybe it's due to the typo in your HTML: class"hide" (you are missing the equal sign).

Also you got a logical error in your code:

  1. if($('li').hasClass('hide')) the condition will yield true if any <li> element in your document has the hide class.
  2. $('li').removeClass('hide').addClass('slide-down'); the first segment $('li') will actually select ALL <li> elements in your document and remove the class hide from them and add the slide-down to ALL <li> elements in your document.

Here's how I'd do it:

$('li.hide').removeClass('hide').addClass('slide-down');

Note that jQuery is about chaining, i.e selecting subsets and applying functions to these subsets.

What this line does is:

  1. $('li.hide') selects all <li> elements in your document which have the hide class - this becomse your "working subset" now.
  2. .removeClass('hide') removes the hide class from this subset we got in the first step and returns the same subset again.
  3. .addClass('slide-down') adds the slide-down class to all <li> in the selected subset returned from step 2, which is the same as from step 1.

JS fiddle: https://jsfiddle.net/q0nzaa7t/

Upvotes: 4

Related Questions