- ベストアンサー
大量のチェックボックス状態取得について
- 大量のチェックボックス状態取得について質問させてください。処理速度を考慮しながら、全体のチェックボックスの状態を取得し、未チェックの物を非表示する方法について教えてください。
- 現在はjQueryを使用し、$ (ul.Parents li.child)で全体をラップし、for文のループで1件ずつcheckedを参照し、.hide()を実行しています。しかし、処理速度が遅いため、他の方法で速く処理できる方法を教えてください。
- 大量のチェックボックスの状態を効率的に取得し、未チェックのものを非表示にする方法について質問です。現在はjQueryを使用し、ループを回す度にチェックボックスの状態を参照し、非表示にしていますが、処理速度が遅いです。もっと速い方法があれば教えてください。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
No.4 の方のキャッシュを利用するのは良い考えと思います。 ただ、querySelectorAll() にしろ jQuery にしろ、その戻り値は「生きていません」。つまり、文書状態に応じてアップデートするのは自分の責任、ということになります。 キャッシュを使うなら「生きた」リストを使うと良い。getElements... の名前を持つメソッドが返す「生きた」リストは、文書状態に応じて自動的にアップデートされます。 var ChildrenCache = document.getElementsByClassName('child'); もちろん、load イベントを待つ必要もありません。文書木の構築に合わせて、勝手に追加されるからです。その分、普通の配列のように扱うと怪我をします。注意して下さい。
その他の回答 (4)
- JaneDue
- ベストアンサー率75% (263/350)
リストはあらかじめ取得しておけば早くなるかと。 ▼window.onloadや#hoge1 の出力後あたりで var elems = $("#hoge1 ul.Parents li.child input:[type='checkbox']"); ▼処理部分で var n= elems.length; for(var i=0; i < n;i++){ if(!elems[i].checked){elems[i].parentNode.style.display="none";} } jQuery1文なら $("#hoge1 input:checkbox:not(:checked)").parent("li.child").hide(); とか、実際の構造に応じて $("#hoge1 ul.Parents > li.child > input:checkbox:not(:checked)").parent("li.child").hide(); とか。
補足
ご回答ありがとうございます。 キャッシュを使用する方式も盲点でした。 試してみます!!
- Chaire
- ベストアンサー率60% (79/130)
No.2 補足より。 > getElementById > formに入れる事で どちらでも構いませんよ。両方とも最速候補です。 function process (controls) { var c; var i; for (i = 0; c = controls[i]; i++) { if (c.type !== 'checkbox') continue; switch (c.name) { case 'AAA' :case 'BBB' :case 'CCC' :case 'DDD' : c.parentNode.style.display = c.checked ? '' : 'none'; } } } process(document.getElementById('hoge1').getElementsByTagName('input')); // process(document.forms[0].elements); まあ、form.elements を使う方は「"#hoge1" の内部」という条件を無視していますけどね。実を言うと、querySelectorAll() はネイティブメソッドの中では遅い方です。しかし、"#hoge1 *.Parents > *.child > input'"というセレクタによって、"#hoge1" の存在と、input の親である ".child" の存在が自然に保証されます。上に書いた process() 関数は単純ですが、"#hoge1" が存在しているか、c.parentNode が ".child" であるか、については無視していることに注意して下さい。 ちなみに、document.getElementsByName() を使うべきではありません。フォームを飛び越えますし、meta、param、map などまで拾う可能性があります。今回はどの道、使わないでしょうが。 > 子孫セレクタを排除 子の ">"、隣接の "+" などを使って下さい。子孫の深さがそれほどでもなければ子孫セレクタの方が速い場合もありますが。 --- セレクタを「右から左」に評価するのは、リストから候補をふるい分けるときです。処理速度はリストに含まれるノード数に比例します。 [a, b, c, d].filter(selectors) ===> [a, c] セレクタを「左から右」に評価するのは、リストの変化をステップごとに追いかけるときです。ステップ数と中間リストの要素数に応じて、処理速度が相乗的に増えます。 [a].map(step1) ===> [b, b, b].map(step2) ===> [c, c, c, c, c] jQuery は「左から右」方式です。つまりセレクタが短く、中間リストの要素数が少なければ速く処理できます。しかしセレクタが長かったり、中間リストの要素数が多ければ処理速度がガクっと落ちます。
- Chaire
- ベストアンサー率60% (79/130)
jQuery を使う時点で速度は度外視だと思いますが……。 まだ草案が出たばかりですが、Selectors Level 4 なら次の CSS だけで済む話です。 /* チェックの入っていない input を持つ li.child を非表示にする */ #hoge1 *.Parents > ?*.child > input:not(:checked) { display: none; } これを現在の実装だけで行うよう「変換」すれば良い。 Array.prototype.forEach.call( // チェックの入っていない input を取得 document.querySelectorAll( '#hoge1 *.Parents > *.child > input:not(:checked)' ), function (input) { // その input の親である li.child を非表示にする input.parentNode.style.display = 'none'; }); jQuery を使うときも同じです。:checked は標準の疑似クラスですから、jQuery の独自拡張よりも率先して使って下さい。 ※jQuery は内部的に querySelectorAll() を試し、その後で独自エンジンを走らせます。速度を考慮するなら、独自エンジンを走らせる回数を減らすべきです。もしどうしても独自エンジンを走らせざるをえないなら、jQuery の特性上、子孫セレクタを極力排除して下さい。 それと、フォーム部品を使う時は form の中に入れた方がスクリプト操作の面で有利ですよ。
補足
ご回答ありがとうございます。 「Selectors Level 4」の存在を初めて知りました。 「Selectors API 」はかなり便利そうですね 。 書き忘れで申し訳ないのですが、IE7も視野に入れているため、 別の場面で是非手を出してみようと思います。 >※jQuery は内部的に querySelectorAll() を試し、その後で独自エンジンを走らせます。速度を考慮するなら、独自エンジンを走らせる回数を減らすべきです。 jQueryはそのような仕組みになっていたのですね。 今後、知識が着いてきたらjQueryの内部を見てみます。 勉強になりました。 >jQuery の特性上、子孫セレクタを極力排除して下さい。 子孫セレクタを排除といいますのは、 $ (ul.Parents li.child)ではなく、$ (ul.Parents)を使用する。と言う事なのでしょうか。 (ブラウザは、右から左にセレクタを解釈しながら描画する事と関係があったり?) >フォーム部品を使う時は form の中に入れた方がスクリプト操作の面で有利ですよ。 こちらも記載忘れで申し訳ないです。 最終的にはformに入れ、submit後、PHPで処理を行う予定です。 jQueryを使用しない場合はgetElementByIdをクラス名指定で取得後、 displayをnoneするつもりだったのですが、formに入れる事でもっと効率のいい方法があるのでしょうか? 質問の連続で大変申し訳ないのですが、よろしくお願い致します。
- kosukejlampnet
- ベストアンサー率44% (126/282)
$(":checkbox:unchecked").hide(); この一行でいけるんじゃないかな?
補足
ご回答ありがとうございます。 「unchecked」 このような指定は初めて知りました。 勉強になります。 是非試してみます。
補足
ご回答ありがとうございます。 度重なる質問にも丁寧に解説していただき、とても勉強になりました。 今回はChaire様に教えていただいたgetElementByIdを使用して対応し、 子孫セレクタの排除にも気を配ってみようとおもいます。 今回このようなサービスを初めて利用したのですが、 有識者の皆様に詳しく回答していただきとても助かりました。