jQueryのaddClass()やremoveClass()を生JavaScriptで実装する脱jQuery

生JavaScriptでクラスの追加と削除を実装してみます。モダンブラウザ向けとレガシーブラウザ向けの両方の場合を考えていきます。

classList

IE10以上で動作すればいいなら classList を使うのが簡単で扱いやすいです。


// クラス追加
document.querySelector('div').classList.add('foo');

// クラス削除
document.querySelector('div').classList.remove('foo');

非常にいいAPIですが、問題があります。


// 複数クラス追加
document.querySelector('div').classList.add('foo', 'bar');

// 複数クラス削除
document.querySelector('div').classList.remove('foo', 'bar');

引数をいくつでもとることができて複数クラスの制御ができますが、残念なことにIE10/11Android4.3以前では複数クラスの追加や削除ができません。そこで、このAPIを使うのはやめて、setAttribute() で実装することにしました。

addClass()


var addClass = function(node, className) {
  var classNames = className.trim().split(/\s+/),
      nodeClass = (node.getAttribute('class') || '').trim(),
      nodeClassNames = nodeClass.split(/\s+/),
      i = classNames.length,
      classNameStr;
  
  while (i--) {
    // 同名クラスがすでにあれば除く
    if (~nodeClassNames.indexOf(classNames[i])) {
      classNames.splice(i, 1);
    }
  }
  
  classNameStr = classNames.join(' ');
  
  if (nodeClass.length) {
    // すでにクラスがあるときはハイフンでつなぐ
    if (classNameStr.length) {
      node.setAttribute('class', nodeClass + ' ' + classNameStr);
    } else {
      node.setAttribute('class', nodeClass);
    }
  } else {
    node.setAttribute('class', classNameStr);
  }
};

仕組みとしてはクラス名を空白で分割し、配列で処理していく感じです。trim() は前後の空白の除いてくれる便利な関数ですが、IE8では動作しないので自作する必要があります。

使い方


<div class="b a"></div>

addClass(document.querySelector('.b'), 'c');
// => <div class="b a c"></div>

クラス名の末尾に追加されます。


<div class="b a"></div>

addClass(document.querySelector('.b'), 'a c d');
// => <div class="b a c d"></div>

スペース区切りで複数指定できます。すでにあるクラスは無視されます。

removeClass()


var removeClass = function(node, className) {
  var classNames = className.trim().split(/\s+/),
      nodeClass = (node.getAttribute('class') || '').trim(),
      nodeClassNames = nodeClass.split(/\s+/),
      i = nodeClassNames.length;
  
  while (i--) {
    // 指定したクラスがあれば削除
    if (~classNames.indexOf(nodeClassNames[i])) {
      nodeClassNames.splice(i, 1);
    }
  }
  
  node.setAttribute('class', nodeClassNames.join(' '));
};

使い方


<div class="b a"></div>

addClass(document.querySelector('.b'), 'a');
// => <div class="b"></div>

クラス名を指定すればクラスを削除できます。


<div class="b a"></div>

addClass(document.querySelector('.b'), 'a b d');
// => <div class=""></div>

クラスを複数指定でき、一気に削除することもできます。存在しないクラス名を指定すると無視します。