LoginSignup
99
84

More than 5 years have passed since last update.

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

Posted at

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

99
84
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
99
84