14

I am nearly there, just a little unsure as to my code setup, I basically want to remove a class on click, and add it back again onclick, then remove onclick, then add onclick. And so on! Here's what I have, it's nearly there, but if there is a nicer way to do this then please help! Thank you.

document.getElementById('myButton').onclick = function() {
    myButton.className = myButton.className.replace(/(?:^|\s)active(?!\S)/g, '') ? 'active': jbar.className.replace(/(?:^|\s)active(?!\S)/g, '') ;
}

Any help much appreciated!

5 Answers 5

80

I am really surprised nobody mentioned classList here. So just to be complete: Alternative solution would be to use classList method toggle().

Your case would then simply be:

document.getElementById('myButton').onclick = function() {
    this.classList.toggle('active');
}

e.classList.toggle() has good support (except for, ehm, IE, It's there since IE10). Click here for complete browser compatibility.

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

2 Comments

Why is this not marked as the right answer? Shorter and cleaner than the other answer.
In 2021, this is definitely the correct answer. Everyone, please use classList.toggle(...)!
14

If you want to use a ternary operator, use this:

document.getElementById('myButton').onclick = function() {

    var className = ' ' + myButton.className + ' ';

    this.className = ~className.indexOf(' active ') ?
                         className.replace(' active ', ' ') :
                         this.className + ' active';
}

For clarity, I'd use a regular if/else:

document.getElementById('myButton').onclick = function() {

    var className = ' ' + myButton.className + ' ';

    if ( ~className.indexOf(' active ') ) {
        this.className = className.replace(' active ', ' ');
    } else {
        this.className += ' active';
    }              
}

Here's the fiddle: http://jsfiddle.net/ttEGY/

8 Comments

Brill! Thank you very much. Howcome you didn't need the RegEx?
@Toddo - Because I wrapped it in spaces, I can just search for an exact string match. Old trick I learnt from the jQuery source.
Clever, much cleaner than RegEx. Can I trouble you for one extra piece of advice? If I wanted to remove the class from two different divs, at once? How would that be done without writing it twice. Assuming the id is #myButton1 and #myButton2 both containing the class to toggle.
@Toddo - You can't. You should abstract this functionality into a function, and call it for both elements separately.
How would you run the function then on each item? or do you mean setup an onclick for each of them?
|
2

If JQuery is okay for you it really is as simple as

$(myButton).toggleClass('active')

http://jsfiddle.net/bikeshedder/eRJB4/

1 Comment

Thanks, but jQuery is not what I want to use. Cheers anyway :)
0

Suggest common realization of toggleClass method:

function toggleClass(element, tClass) {
    tClass = tClass.replace(/\s/g, "");

    var classes =  element.className;
    element.className = classes.indexOf(tClass) !== -1 
        ? classes.replace(" " + tClass, "")
        : classes + " " + tClass;
}

using:

var element = document.getElementById('myId');
toggleClass(element, 'active');

Comments

0

Implementation using Array methods:

const toggleClass = (element, className) => {
  let classNames = element.className.split(' ');
  let index = classNames.indexOf(className);
  if (index === -1) {
    classNames.push(className);
  } else {
    classNames.splice(index, 1);
  }
  element.className = classNames.filter(item => item !== '').join(' ');
}

Usage:

let body = document.getElementsByTagName('body')[0];
toggleClass(body, 'ready');

Plunker

Comments

Your Answer

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