jQueryを使わずにクラスの操作を行うclassListオブジェクトを調べてみた

またまたモダンWeb ―新しいWebプラットフォームの基盤技術を読んで知ったことのメモ。

あるDOM要素に指定のクラスがあるか確認したり、指定のクラスを追加したり削除したりするにはjQueryを使うと簡単にできますが、最近のブラウザのJavaScriptにはclassListというオブジェクトが導入してあるようで、このオブジェクトを使うことにより、クラスの操作が簡単にできるようです。
参考:element.classList – DOM | MDN

例えば、下記のようなHTMLがあるとします。

<div id="js-div" class="js-class test">classListでのクラス操作用</div>
<div id="jq-div" class="jq-class test">jQueryでのクラス操作用</div>

以下、IDが”js-div”のdiv要素はclassListでの操作用、IDが”jq-div”のdiv要素はjQueryでの操作用に使います。

指定のクラスがあるか確認する

// classListによる指定のクラスが含まれているかどうかの確認
console.log(document.getElementById('js-div').classList.contains('js-class')); //=> true
console.log(document.getElementById('js-div').classList.contains('jq-class')); //=> false
// jQueryによる指定のクラスが含まれているかどうかの確認
console.log($('#jq-div').hasClass('js-class')); //=> false
console.log($('#jq-div').hasClass('jq-class')); //=> true

指定のクラスがあるかどうかの確認には、containsメソッドを使う。

クラスの追加・削除を行う

// classListでの操作
// クラスの削除
document.getElementById('js-div').classList.remove('test');
console.log(document.getElementById('js-div').classList.contains('test')); //=> false
// クラスの追加
document.getElementById('js-div').classList.add('test');
console.log(document.getElementById('js-div').classList.contains('test')); //=> true

// jQueryでの操作
// クラスの削除
$('#jq-div').removeClass('test');
console.log($('#jq-div').hasClass('test')); //=> false
// クラスの追加
$('#jq-div').addClass('test');
console.log($('#jq-div').hasClass('test')); //=> true

// ちなみに、classListだとメソッドチェーンは使えない
//document.getElementById('js-div').classList.remove('test').add('test'); // これはエラー
// jQueryだとメソッドチェーンが使える
$('#jq-div').removeClass('test').addClass('test');

クラスの追加にはadd、クラスの削除にはremoveメソッドを使う。もしかしてjQueryみたいにメソッドチェーンができるんじゃ・・・と思って試してみましたが、ダメでした。

指定クラスの切り替えを行う

// classListでの操作
// クラスの削除
document.getElementById('js-div').classList.toggle('test');
console.log(document.getElementById('js-div').classList.contains('test')); //=> false
// クラスの追加
document.getElementById('js-div').classList.toggle('test');
console.log(document.getElementById('js-div').classList.contains('test')); //=> true

// jQueryでの操作
// クラスの削除
$('#jq-div').toggleClass('test');
console.log($('#jq-div').hasClass('test')); //=> false
// クラスの追加
$('#jq-div').toggleClass('test');
console.log($('#jq-div').hasClass('test')); //=> true

指定のクラスがあれば外し、なければ追加するような動作を実現するにはtoggleメソッドを使う。この機能は便利ですね。

なお、classList自体は配列のようになっており、classList[n]のように指定するとn+1番目のクラス名が手に入る。

console.log(document.getElementById('js-div').classList[0]); //=> "js-class"
console.log(document.getElementById('js-div').classList[1]); //=> "test"

配列のように使えるので、前に紹介したイテレーションメソッドも使える。

// 配列に"test"という要素があるか
console.log( Array.prototype.some.call(document.getElementById('js-div').classList, function(e){ return e==="test" }) ); //=>true

// 配列内の要素をカンマ区切りにした文字列を返す
console.log( Array.prototype.reduce.call(document.getElementById('js-div').classList, function(pre, cur){ return pre+','+cur }) ); //=> "js-class,test"

toStringメソッドを使うと、配列のようなカンマ区切りではなく、スペース区切りの値(classNameと同じ)が得られる。

console.log(document.getElementById('js-div').classList.toString()); //=> "js-class test"
console.log(document.getElementById('js-div').className); //=> "js-class test"

console.log(["js-class","test"].toString()); //=> "js-class,test"

ちなみに、HTML5では、class指定でのDOM取得方法として、getElementsByClassNameメソッドが追加されています。ただ、getElementsByClassNameメソッドが使えるブラウザでは大抵、querySelector(querySelectorAll)メソッドが使えると思うので、そちらを使ってみてもいいと思います。

console.log( document.getElementsByClassName('test')[0].classList.contains('js-class') ); //=> true
// 上記指定と同じ
console.log( document.querySelectorAll('.test')[0].classList.contains('js-class') ); //=> true

とはいっても、上記の例の場合はgetElementsByClassNameのほうが高速らしいんですけどね。何百回と試すわけではないのであれば、さほど実感できる違いではないと思います(参考:document.querySelector – Web API インターフェイス | MDN)。

コメント

タイトルとURLをコピーしました