jQueryのhasClass()やtoggleClass()を生JavaScriptで実装する脱jQuery

今回は hasClass()toggleClass() を生JavaScriptで実装してみます。モダンブラウザ向けとレガシーブラウザ向けの両方を考慮して実装していきます。

hasClass()


var hasClass = function(node, className) {
  if (node.classList) {
    return node.classList.contains(className.trim());
  }
  return new RegExp('(^| )' + className + '( |$)', 'g').test(node.className.trim());
};

jQueryの仕様に準じて hasClass() は複数クラス指定できないようにしています。classList があるなら使って、なければ正規表現を使います。trim()IE8以下非対応なので必要に応じて自作します。

使い方


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

var has = hasClass(document.querySelector('div'), 'b');
// => true

toggleClass()


var toggleClass = function(node, className) {
  var classNames = className.trim().split(/\s+/),
      nodeClass = (node.getAttribute('class') || '').trim(),
      nodeClassNames = nodeClass.split(/\s+/),
      i = classNames.length;
  
  while (i--) {
    var index = nodeClassNames.indexOf(classNames[i]);
    
    if (~index) {
      classNames.splice(i, 1);
      nodeClassNames.splice(index, 1);
    }
  }
  
  nodeClassNames = nodeClassNames.concat(classNames);
  
  node.setAttribute('class', nodeClassNames.join(' '));
};

classList.toggle() を使う方法もありますが、IE9以下Android4.3以下に対応していないことと、IE10/11では複数クラスを toggle できないので setAttribute() で実装しています。

使い方


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

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

スペース区切りで複数クラスを指定することができます。