DOMおれおれAdvent Calendar 2015 – 05日目

2015-12-05

昔からウェブ関係でJSやってた人は、動的に要素のクラス名を操作するので苦労した覚えがあるかと思います。

// el = <div class="is-hidden"></div>

var rx = /(?:^|\s)is-hidden(?:$|\s)/;
var className = el.className;
var hidden = rx.test(className);
console.log(hidden);  // => true

そう、伝統の className プロパティです。 class 属性の中身が文字列で入ってます。これに足したり引いたりしてクラス名を付けたり外したりするわけです。付けるのは el.className += ' new-class-name'+= でやるだけでいいんですが、あくまで文字列操作になるので、以下の問題があります。

  • 空白 " " も考えないといけない
    • HTML側が class="foo" の状態で +='bar' すると、二つのクラスじゃなくて class="foobar" と一つの別のクラスになる。
  • 既に設定されている場合は同じのが二つになる
    • HTML側が class="foo bar" の状態で +=' foo' すると、 class="foo bar foo" となる。

削除の操作なんかもう目も当てられない。(言い過ぎ) とまあ色々面倒でして、jQueryのクラス関係は便利だったし、jQueryなしの場合は自前のスニペットを用意していたんじゃないかなーと思います。

さてさてそんな苦労も今は昔、 classList を使うと何の苦労もありません。

var el = document.createElement('div');  // => <div></div>
var classList = el.classList;

// 追加
classList.add('foo');
classList.add('bar');
classList.add('foo');
console.log(el.className);  // => "foo bar"

// 削除
classList.remove('bar');
console.log(el.className);  // => "foo"

// 切り替え
classList.toggle('bar');
console.log(el.className);  // => "foo bar"
classList.toggle('bar');
console.log(el.className);  // => "foo"

// 有無確認
console.log(classList.contains('foo'));  // => true
console.log(classList.contains('bar'));  // => false

はぁ~楽ちんじゃあ~~~……。

  • add()
  • remove()
  • toggle()
  • contains()

ちなみに有無確認は contains() であって has() ではありません。(おれがよく間違える。)

環境

IEは10から。9では使えません。まじかよ! Androidも3+だそうです。微妙なサポート具合だ。

代替コードがMDNに載っているので、jQueryを使えないが確実なクラス操作を行う必要がある場合、そちらを参考にどうぞ。

参考