Posted at

jQueryの.removeClass()で「特定の文字列で始まるclass」をすべて削除する

More than 3 years have passed since last update.

jQuery の .removeClass() メソッドでは、「引数に関数を指定する」ことで柔軟なclass削除が実現できます。


「特定の文字列で始まるclass」を一括削除

「ユーザー操作に応じて画面表示を変更する」際など、要素の状態をあらわす "is-active"、"is-visible"、"is-fixed"、"is-closed" といった「特定の文字列で始まるclass」を複数利用する場合があると思います。

例えばこれらの "is-***" というclassのみを一括で削除したい場合、正規表現を利用した以下の方法で実現できます。


HTML

<div id="sample" class="block element is-active is-visible is-fixed">***</div>

<script>
// 'is-' で始まるclassをすべて削除
$('#sample').removeClass(function(index, className) {
return (className.match(/\bis-\S+/g) || []).join(' ');
});

// 結果: <div id="sample" class="block element">***</div>
</script>



もう少し詳しい説明


関数の戻り値が削除対象classとなる

.removeClass() メソッドの引数に関数が指定された場合、その関数の戻り値(returnされた値)と一致するclassが削除対象となります。

このことは、以下のコードの実行結果から確認できます。


HTML

<div id="sample" class="block element is-active is-visible is-fixed">***</div>

<script>
// 'is-active' を削除
$('#sample').removeClass(function() {
return 'is-active';
});

// 結果: <div id="sample" class="block element is-visible is-fixed">***</div>
</script>


つまり

「関数をうまく利用して、削除したいclassをきちんとreturnできれば、複雑な処理も実現できそう」

ということになりますね。


関数で利用できる2つの引数

この関数では2つの引数を利用することができ、


  • 1つめの引数には「対象要素のインデックス番号」

  • 2つめの引数には「対象要素の現在のclass属性値」

が入ります。

元のコードに戻り、

console.log() で確認してみましょう。


HTML

<div id="sample" class="block element is-active is-visible is-fixed">***</div>

<script>
// 'is-' で始まるclassをすべて削除
$('#sample').removeClass(function(index, className) {

console.log(index); // 0
console.log(className); // 'block element is-active is-visible is-fixed'

return (className.match(/\bis-\S+/g) || []).join(' ');
});

// 結果: <div id="sample" class="block element">***</div>
</script>


$('#sample') のインデックス番号「0」と、

現在のclass属性値「'block element is-active is-visible is-fixed'」が出力されることを確認できました。


正規表現を利用したマッチング

続いて、return されている値の部分に注目します。

(className.match(/\bis-\S+/g) || []).join(' ')

ここでの処理の流れとしては、


  1. 現在のclass属性値の文字列('block element is-active is-visible is-fixed')に対して.match() メソッドを実行し、正規表現(/\bis-\S+/)にマッチする値すべてを配列として取得

  2. 上記の配列に対して.join() メソッドを実行し、半角スペース区切りで結合して文字列に変換

となります。

正規表現の部分では「特殊文字」の使い方がポイントになります。

今回使用する特殊文字は以下です。

\b:単語の区切りにマッチ

\S:ホワイトスペース以外の1文字にマッチ

+:直前の文字の1回以上の繰り返しにマッチ

つまり /\bis-\S+/ は

「{単語の区切り}is-{ホワイトスペース以外の1文字以上}」

にマッチすることになります。

末尾のgは「グローバル検索フラグ」です。

これが無い場合は最初のマッチ('is-active')の時点で検索処理が終了してしまうため、

忘れずに付けるようにしましょう。


例外(エラー)処理も重要

.match() メソッドの直後に現れる

|| []

は何を意味するのでしょうか。

これは、「正規表現にマッチするclassが1つも存在しなかった場合」に

後続の.join() メソッドでエラーが発生してしまうのを防ぐための処理です。

以下の例のように、"is-" で始まるclassを1つも持たない要素を対象とした場合、3つめの console.log() でエラーが発生することが確認できます。


HTML

<div id="sample" class="block element">***</div>

<script>
// 'is-' で始まるclassをすべて削除
$('#sample').removeClass(function(index, className) {

console.log(className); // 'block element'
console.log(className.match(/\bis-\S+/g)); // null
console.log((className.match(/\bis-\S+/g)).join(' ')); // Uncaught TypeError: Cannot read property 'join' of null

});
</script>


null に対して.join() メソッドなんて使えないよ、ということですね。

|| []

を追記することで、マッチするclassが無かった場合には空の配列が生成され、

.join() メソッド呼び出し時のエラーを回避できます。


まとめ

ここまでの内容をふまえ、

コードを小さな単位に分解して console.log() してみましょう。

処理の流れがより理解できるかと思います。


HTML

<div id="sample" class="block element is-active is-visible is-fixed">***</div>

<script>
// 'is-' で始まるclassをすべて削除
$('#sample').removeClass(function(index, className) {

console.log(className); // 'block element is-active is-visible is-fixed'
console.log(className.match(/\bis-\S+/g)); // ['is-active', 'is-visible', 'is-fixed']
console.log((className.match(/\bis-\S+/g) || []).join(' ')); // 'is-active is-visible is-fixed'

return (className.match(/\bis-\S+/g) || []).join(' ');
// つまり
// return 'is-active is-visible is-fixed';
});

// 結果: <div id="sample" class="block element">***</div>
</script>


期待通りに 'is-active is-visible is-fixed' が return され、

「"is-***" というclassのみを一括で削除」が実現できました。


.addClass() は?

何となく想像はつくかと思いますが、

.addClass() メソッドでも同様に、引数に関数を指定することができます。


HTML

<ul id="sampleList">

<li>***</li>
<li>***</li>
</ul>

<script>
// 'li' に連番でclassを追加
$('#sampleList li').addClass(function(index, className) {
return 'item-' + index;
});

// 結果:
// <ul id="sampleList">
// <li class="item-0">***</li>
// <li class="item-1">***</li>
// </ul>
</script>



参考リンク

より詳しい内容については公式リファレンスを参照してください。

.removeClass() | jQuery API Documentation

.addClass() | jQuery API Documentation