実現したい機能
- 親のチェックボックスにチェックが入ったら、子のチェックボックスにもチェックを入れる
- 親のチェックボックスでチェックが外れたら、子のチェックボックスからもチェックが外れる
- 子のチェックボックスでチェックが入ったり、外れたりしても親のチェックボックスは反応しない
サンプルページ
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に変化