実現したい機能
- 親のチェックボックスにチェックが入ったら、子のチェックボックスにもチェックを入れる
- 親のチェックボックスでチェックが外れたら、子のチェックボックスからもチェックが外れる
- 子のチェックボックスでチェックが入ったり、外れたりしても親のチェックボックスは反応しない
サンプルページ
Github
コード
HTML
<ul>
<li class="checkbox">
<input type="checkbox" name="parent">親チェックボックス
<ul>
<li class="checkbox"><input type="checkbox" name="child1">子チェックボックス1</li>
<li class="checkbox"><input type="checkbox" name="child2">子チェックボックス2</li>
<li class="checkbox"><input type="checkbox" name="child3">子チェックボックス3</li>
</ul>
</li>
</ul>
JavaScript
$(function (){
$('input[name^="parent"]').change(function() {
if ($(this).is(':checked')) {
$(this).parents('.checkbox').find('input:checkbox').prop('checked', true);
}else{
$(this).parents('.checkbox').find('input:checkbox').prop('checked', false);
}
});
});
解説
コードの解説
前提として、親のチェックボックスである<input type="checkbox" name="parent">
の状態が変化した時、check.js
が発火する。
<input type="checkbox" name="parent">
の状態がchecked
になった際、次の処理が行われる。
$(this).parents('.checkbox').find('input:checkbox').prop('checked', true);
このコードがそれぞれ何を指すのか分解してみる。
-
$(this)
:<input type="checkbox" name="parent">
の指定。 -
parents('.checkbox')
:<input type="checkbox" name="parent">
の親である<li class="checkbox">
の指定。 -
find('input:checkbox')
:<li class="checkbox">
の中にある<input type="checkbox">
を探す。 -
prop('checked', true)
:checked
入れる。
以上を踏まえて、文章にしてみると、
<input type="checkbox" name="parent">
の親である<li class="checkbox">
を探して、その中にある<input type="checkbox">
の状態をchecked
にする。
となる。
**.prop('checked', false)
**の場合は、checked
を外す処理が行われる。
仕組みの解説
このコードが何故親のチェックボックスに反応して、子のチェックボックスも反応できるようになるのかというと、親と子における<li>
タグと<input>
タグで同じclass
名を付けているから。
checked
にする動きで考えてみる。
$('input[name^="parent"]').change(function() {
if ($(this).is(':checked')) {
if
文のtrue
分岐に入る時点で、親のチェックボックスにはchecked
が入っている。
その状態で、
$(this).parents('.checkbox').find('input:checkbox').prop('checked', true);
このコードが動くと、親の状態とかは関係なく、jsは<li class="checkbox"><input type="checkbox">
の構成をしている部分をHTMLから探す。
その結果、<li class="checkbox"><input type="checkbox">
の構成をしていて、まだchecked
が入っていない、子のチェックボックスにchecked
が入り、親と子で同時にチェックが入る(ように見える)。
流れを簡潔にまとめると、以下のようになる。
- 親のチェックボックスにチェックが入り、
check.js
が発火 <li class="checkbox"><input type="checkbox">
に該当するHTMLタグの状態をchecked
にする- 親にはもう
checked
が入っているから見た目に変化はない。子はchecked
に変化