jQueryでチェックボックスにより動作する仕組みを作っています。
解決済
回答 2
投稿
- 評価
- クリップ 1
- VIEW 2,108
前提・実現したいこと
jQueryでチェックボックスにより動作する仕組みを作っています。
「checkbox01」というIDを持った
チェックボックスと、「checkbox02」というIDを持ったチェックボックスをどちらもチェックした時に限り
「xxx」というclassを持った要素を非表示にするという仕組みにしたいと思っています。しかしその動作が実現しません。
該当のソースコード
$('#checkbox01' + '#checkbox02').change(function(){
if($(this).attr('checked')) {
$('.xxx').css("display","none");
}
});
試したこと
「'a'+'b'」のADN条件を与えたが動作が実現しません
Webで同条件の解決法を探したが見つけられませんでした
補足情報(言語/FW/ツール等のバージョンなど)
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+2
$
関数の引数にはCSSセレクタ風の文字列を指定するのですが、提示されたコードではJavaScriptレベルで文字列結合されているため、'#checkbox01' + '#checkbox02'
は'#checkbox01#checkbox02'
と同じ文字列としてjQueryに渡されます。
これは、「idがcheckbox01であり、かつ、idがcheckbox02である要素」という要素を取得する条件になってしまいます。しかし、そんな要素は存在しないため、このコードは動作しません。
複数の要素を取得したい場合は,
で区切ります。例えば、以下のように記述することになります。
var checkboxElems = $('#checkbox01, #checkbox02');
なお、,
の後ろにスペースを含めていますが、これは見やすさのためであり、以下のように省略することが可能です。
var checkboxElems = $('#checkbox01,#checkbox02');
参考:Multiple Selector (“selector1, selector2, selectorN”) | jQuery API Documentation
さて、これで動きそうではありますが、正しくは動きません。
何故なら、.change()
の中のthis
はクリックされた(厳密にはチェックされた/解除された)要素のみが渡され、他のチェックボックスは渡されないためです。
つまり、checkbox01のチェックボックスがチェックされたら、checkbox01のチェックボックスがthis
に格納され、checkbox02は格納されません。
「全てチェック」されなくてはならないのに、チェックされたチェックボックスだけをチェックされたか判定してしまいます。
これを回避するためには、$('#checkbox01, #checkbox02')
で取得した要素群が全てチェックされているか判定しなくてはなりません。
判定するやり方として複数の方法が考えられますが、ここでは全てのチェックボックスのうち「チェックされた」ものを取得し、その数がチェックボックス全ての数と一致するかどうか判定することにします。
チェックされたチェックボックスの数が、(チェックの有無を問わない)全てのチェックボックスの数と同じであれば、全てチェックされたと判定できます。
.filter()
のセレクタに、「チェックされた」条件となるセレクタを指定し、「チェックされた」要素を全て取得します。
var checkedCheckboxElems = checkboxElems.filter(':checked');
そして、数が一致するか判定します。
要素の数はlength
プロパティから取得できます。
checkedCheckboxElems.length === checkboxElems.length
参考:.filter() | jQuery 1.9 日本語リファレンス | js STUDIO
参考:jQueryでチェックボックスのチェック状態を調べる方法 - 大人になったら肺呼吸
参考:jQueryのセレクタで指定したもの以外を選択する・させる方法 :not() | 9ineBB
この判定結果を、.toggle()
に渡して表示/非表示を切り替え得られるようにします。
ただし、.toggle()
は引数の値がtrue
の場合に表示し、false
の場合に非表示にしてしまいます。
先ほどの判定では、全てチェックされた(非表示にしたい)場合にtrue
、全てチェックされていない(表示したい)場合にfalse
となってしまうため、!
演算子を使ってtrue
とfalse
を逆にする必要があります。
※ちなみにtrue
/false
とは、JavaScriptのBooleanという値の事を意味しています。
// クラスxxxの付いた要素群
var xxxClassElems = $('.xxx');
// 表示/非表示を切り替え
// 変数の値と表示の有無が逆なため、`!`演算子を使用
xxxClassElems.toggle(!isAllChecked);
参考:【jQuery】要素の表示・非表示について (show, hide, toggle) - TASK NOTES
参考:論理演算子 - JavaScript | MDN
以上の点を考慮した、適切に動作するコードが以下になります。
/* チェックボックスの要素群。複数の条件は、カンマ(,)で区切ります */
var checkboxElems = $('#checkbox01, #checkbox02');
/* クラスxxxの付いた要素群。予め取得し、変数に入れておくことで、パフォーマンスが向上します */
var xxxClassElems = $('.xxx');
checkboxElems.change(function() {
/*
* チェックボックスの要素群から、チェックされた要素を全て取得します
*/
var checkedCheckboxElems = checkboxElems.filter(':checked');
/*
* チェックされたチェックボックスの数が、チェックボックスの数と一致するかどうか判定し、その結果を変数に格納します
* 数が一致 = 全てチェックされている
* 数が不一致 = どれかがチェックされていない
*/
var isAllChecked = checkedCheckboxElems.length === checkboxElems.length;
/*
* 全てチェックされていれば、クラスxxxの付いた要素を表示せず、
* 全てチェックされていなければ表示します。
*/
xxxClassElems.toggle(!isAllChecked);
});
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
checkベストアンサー
0
こんな感じにしてみました。
動作パフォーマンスとか汎用性とかはともかく、
一応お望みの挙動にはなるかと。
$('input[type="checkbox"]').change(function(){
hideContents();
});
function hideContents(){
var check01 = $("#checkbox01").is(":checked");
var check02 = $("#checkbox02").is(":checked");
if(check01 && check02) {
$(".xxx").hide();
}
}
補足:
特定のcheckboxがチェックされているかどうかを
セレクタ.attr('checked')
で取得しようとしていますが、これは上手く動作しないようです。
なので、こちらのサイトを参考にして
セレクタ.is(":checked")
でtrue
or false
を取得しています。
後は#checkobx01
と#checkbox02
のそれぞれがtrueかfalseかを変数に格納しておき、
&&条件で判定したのち、対象の要素を非表示にする命令を与えてみました。
他にも良い方法があるかもしれませんが、参考までに……
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.34%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2016/04/12 18:10