Skip to content

Instantly share code, notes, and snippets.

Last active September 11, 2017 01:01
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
Towards A Modernized JavaScript Class Name Changer

Towards A Modernized JavaScript Class Name Changer

Previously we'd do something horrible with string matching when we wanted to change an HTML element's class name with JavaScript.

var changeClass = function (el, add, remove) {
  if (el) {

    if (!el.className) {
      el.className = '';
    // replace in existing class
    if (remove && remove.length) {
      for (var i = 0, n = remove.length; i < n; i = i + 1) {
        el.className.replace(new RegExp('(?:^|\\s)'+ remove[i] + '(?:\\s|$)', 'g'), ' ');
    // strip and minimize whitespace
    el.className = el.className.replace(s/^\s+|\s+$|\s+(?=\s)//g);

    // add new stuff to the back
    if (add && add.length) {
      for (var i = 0, n = add.length; i < n; i = i + 1) {
        el.className = el.className + ' ' + add[i];

Since classList Landed in Modern Browsers

// takes an element and two optional lists, one to add and one to remove
var changeClass = o => {
  if (o.el) {
    o.el.classList.add.apply(o.el.classList, o.add);  
    o.el.classList.remove.apply(o.el.classList, o.remove);

What's Going On Here?

All fuctions have call and apply methods built in at the Function.prototype level. Here we're using apply because we want to run through the array of arguments we sent in o.add and o.remove. Explained here:

Um ... "modern browsers?"

Pretty much anything you should care about. See CanIUse for details:

Some Results

<a id="foo" class="bar baz">Hit Me</a>
var foo = document.getElementById('foo');


changeClass({el: foo, 'add': ['baz']});


<a id="foo" class="bar baz">Hit Me</a>


changeClass({el: foo, 'remove': ['bar']});


<a id="foo" class="baz">Hit Me</a>

Do Nothing

changeClass({el: foo});


<a id="foo" class="baz">Hit Me</a>

This works because apply is smart enough to do nothing with null or undefined, and is the reason why we don't have to explictly test for the presence of add or remove arrays before firing it off.

foo.classList.add.apply(foo.classList, null);

Complex Maneuvers

changeClass({el: foo, 'add': ['woo', 'yay'], 'remove': ['baz']});


<a id="foo" class="woo yay">Hit Me</a>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment