チェックボックスの値についての些細な話(jquery編)

この記事はだいぶ前に書かれたものなので情報が古いかもしれません
いつまで経っても覚えられないことってあるよね

この記事を三行にまとめると

jqueryでチェックボックスの値を取りたいんですけど
$(element).attr('checked')は取れたり取れなかったりする
.prop()を使うとだけ覚えとけばあとは何の問題もない
タイトルの通り、ほんとーに些細なお話なんですけど……でもそれを長々と書く。それがあかつきのお宿クオリティー。

僕は、チェックボックスのチェックがついてるか判定して何かしらの処理を行なうとき、その判定方法を、つまり値を取得する方法を、何でかいっつも忘れちゃうんですよ。そんなに難しい話ではないはずなんですけどね。自分の購入している漫画の最新巻がいつ出るかチェックするよりも、はるかに簡単なはずなんですけどね。

いや、でも考えたら僕、自分が集めてる漫画の最新巻が出る日も、全く覚えてないわ。ふらっと本屋に行ったりAmazonを徘徊してるときにうっかり発見しないと、いつまで経っても気づかない人だったわ。どのみちダメ男じゃんorz

僕がいつも忘れちゃうのは、jqueryを使って判定を行なう場合です。もうほんっとうに何度やっても覚えないんで、ここらでそろそろ、自分をこらしめておこうと思います。

こんにゃろ、こいつめ、いいかげん覚えやがれ、オラァ! いつまでも同じ過ちを繰り返してんj



javascriptで判定する場合

javascriptでっていうのは、jqueryとか使わずにチェック判定を行なうっていう意味なんですが、そっちは覚えてるんですよ。

<input type="checkbox" id="check" onchange="judge(this)" />

<script>
function judge(obj) {
  if(obj.checked) {
    alert('チェックがついています');
  }
}
</script>

例えばこれなら、チェックがついたときだけアラートが出ます。いったんチェックをはずしてもっかいつけたら、またアラートが出る。特に問題はないですね。

ただしこれだと、デフォルトでチェックがついてるときにはアラートが出ないですね。一度はずして再度つけたときに初めてアラートが出る。

そんなときは、ベージを読み込んだときに一度判定を行なうようにしとく?

<input type="checkbox" id="check" onchange="judge(this)" checked="checked" />

<script>
function judge(obj) {
  if(obj.checked) {
    alert('チェックがついています');
  }
}

var obj = document.getElementById('check');
judge(obj);
</script>



jqueryで判定する場合

じゃあちょっとjqueryに手伝ってもらって、同じような処理を書いてみましょう。

<input type="checkbox" id="check" checked="checked" />

<script>
$.fn.extend({
  judge: function() {
    if(this.checked) {
      alert('チェックがついています');
    }

    this.one('change', function(){
      $(this).judge();
    });
  }
});

$('#check').judge();
</script>

こういう書き方がベストかは分かりませんが、やってることは一緒です。ページ読み込み時に一度判定を行なって、さらにoneってのを使って、changeイベントで同じ判定処理を行なうようにしている。

でもこれだと、いつまで経ってもアラートが出ない。実際に「this.checked」をアラートしてみると常に「undefined」が返って来てしまう。



判定できるパターンはどれだ?

たぶん、僕がいつまで経っても覚えられない理由は、判定ができる場合とできない場合、両方ともいくつかパターンがあるせいじゃないかと。その辺が何かややこしくて、いつも混同してしまうのではないかと。そんな風に思う今日この頃です。

なので、判定できるパターンと判定できないパターンを、いくつか洗い出してみましょう。

//OKパターン
$(element).get(0).checked;
$(element).is(':checked');
$(element).prop('checked');

//NGパターン
$(element).checked;
$(element).attr('checked');

上の3つがOKなパターン。チェックがついてるとtrueが返ってくるし、そうじゃなければfalseが返ってくるから、処理を分けられる。

問題は下の2つ。特に「$(element).attr(‘checked’)」の方ね。正直、いっつもこれを最初に書いて「あれ? 判定できてねえ」ってなっちゃうのよ。



できるときもあるから困る

何がややこしいって、「$(element).attr(‘checked’)」は、チェックがついているか判定できるときもあるってのが、ややこしい。

まず一つは、ページ読み込み時。

changeイベントで判定するときは無理なんだけど、ページ読み込み時だけは、チェックがついてるかどうか判定できる。できちゃう。

<input type="checkbox" id="check1" checked="checked" />
<input type="checkbox" id="check2" />

<script>
alert($('#check1').attr('checked'));
alert($('#check2').attr('checked'));
</script>

//アラートの結果
#check1・・・checked
#check2・・・undefined

これだと、デフォルトでchecked属性がついてる方は、checkedが返ってくる。ついてない方はundefinedが返ってくる。そりゃそうだ。

でもこの場合、changeイベントでどんなにチェックを切り替えても、常にcheck1の方はcheckedが返ってくるし、check2の方はundefinedが返ってくるんですよ。だから結局は判定ができてないってことになる。チェックがついたら、あるいははずれたら何らかの処理を行なうってことができないわけですね。

あともう一つ。こっちが厄介。

正確なところはちょっと分からないんだけど、jqueryのバージョンが古いと、changeイベントでも判定ができる。できちゃう。

僕が試した限りだと、jqueryのバージョンが1.8.2の頃は、この判定方法でもチェックがつくとcheckedになるし、はずれるとundefinedになる。でもバージョン2.0.3の場合は、この方法で判定できない。さっき言ったように、ページ読み込み時は判定できるけど、changeイベントのときに判定できない。

たぶん、これなんでしょうね、僕がいつも間違えるのは。なまじ判定できるときもあるだけに「あれれ〜? 確かこの方法で判定できたはずなのに、できないぞ〜?」ってなってるような気がする。






ってなことで、チェックボックスの値取得に関する、些細なのに冗長なお話でしたっと。

ちなみに3つのOKパターンの中だと「.prop()」を使って取得するのが推奨されているようです。だから極力propで判定するのが良いんじゃないでしょうか。僕も今後は「チェックボックスにはpropだ」とだけ覚えて生きていくことにします。「うるせー! 俺は『$(element).get(0).checked』を使うぜ!!」ってかぶくのも良いとは思うけど、この程度のことでお上に逆らってもね……何かあれだしね。

どうせかぶくんなら、もっと別のところでかぶきたいね。「漫画は最終巻まで出そろってから一気に大人買いじゃー!!」とか。別にかぶいてねーか、それは。いや、でもこち亀クラスなら……。
 もしかしたら何か関連しているかも? 
 質問や感想などお気軽にコメントしてください