またまたモダン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)。
コメント