2

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?

3 Answers 3

4

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/

Sign up to request clarification or add additional context in comments.

Comments

0

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.

1 Comment

document.getElementsByClassName returns an HTMLCollection, which behaves like a "live" array, whereas document.querySelectorAll returns a non-"live" NodeList.
0

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';
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.