クラスの有無を複数条件で調べたい
JavaScriptで要素をいじっていると、クラス使って要素の判別をしたくなる時があります。
要素がクラスを持っているかを調べるときに便利なのがclassList
。classList
の仕様については説明に自信がないので割愛させていただきます。
// element = <p class="hoge"></p> だとします。
if(element.classList.contains("hoge")){
console.log("Element has 'huga'!");
}
で、これに加えて"fuga"クラスを持っている場合を判定したいんです私は。
単純にやると、以下のようになります。
if(element.classList.contains("hoge") || element.classList.contains("fuga")){
console.log("Element has 'hoge' or 'fuga'!");
}
// ちなみにこうやっても最初の1つしか見てくれない
if(element.classList.contains("hoge","fuga")){
console.log("Element has 'hoge' or 'fuga'!");
}
もっと増えた時ただただ長くなるだけだし、同じこと何回も書くのが個人的に好みではありません。
調べていると、引数指定を"hoge"&&"fuga"
とやれば複数指定できる!って記事見つけたんですけど、順番入れ替えて調べると最後の1つしか見てないようです。
解決法(力技)
まあ、脳筋の私ですのでスマートなやり方ではないです。className
を使いました。className
の仕様については説明に自信(以下略失礼)。
if(/(hoge|fuga)/.test(element.className.split(/\W/)){
console.log("Element has 'hoge' or 'fuga'!");
}
一応説明させていただきますと、Element.className
でクラスリストを文字列で取得し、正規表現を使用してスペースで分割した配列を、これまた正規表現でtest
しています。
このtest
時に複数のチェックしたいクラス名を指定しています。(test
って配列に対してもちゃんとチェックしてくれるんですね。)
追記
コメントにてご指摘頂きました。ありがとうございます。test
メソッドに配列を渡した場合、全部の要素に対してチェックしてくれるのではなく、配列を文字列化したものに対してチェックしているらしいです。確認不足でした。コメント欄に検証結果をいただいています。
それを受けまして、力技は変わらず2種類ほど対策と別の方法を記述いたします。
// これだと"true"判定される
/(hog|f)/.test(element.className.split(/\W/))
// true
// 単純に対策
/(^|,)(hoge|fuga)[,$]/.test(element.className.split(/\W/))
// true
/(^|,)(hog|f)[,$]/.test(element.className.split(/\W/))
// false
// 別の方法
element.className.split(/\W/).some(name => /^(hoge|fuga)$/.test(name))
// true
前者は、配列を文字列化していることに単純に対応したものです。カンマで分けられた部分に対してチェックをしています。
後者は、classNameを分けた配列にsome
でチェックをしています。まあ結局全部調べるというのを自分で書いているだけですし、正直OR条件で書いているのとそこまでもう変わらないんじゃ…という気持ちがあります。
私が気がついていない誤字・脱字、それは違うよボケェ!というところあれば私としても是非直したいので教えてください。