- val()は「valueを取る関数」ではありません
- ネイティブのvalueは統一されていない
- val()が内部で行っている処理
- 値を設定するときの挙動
- なぜこれが必要だったのか
- よくある誤解
- 注意点:changeイベントとの関係
- val()とattrの違い
- 結局val()は何をしているのか
val()は「valueを取る関数」ではありません
jQueryでフォーム値を取得するとき、多くの人が最初に覚えるのがval()です。
$('#name').val();
一見すると「inputのvalueを取得しているだけ」に見えます。しかし実際には、val()は単なるショートカットではありません。結論から言うと、val()はフォーム要素ごとの違いを吸収するための統一インターフェースです。
input、textarea、select、checkbox、radioは、それぞれvalueの扱いが違います。jQueryのval()はそれを内部で判定し、同じ書き方で扱えるようにしています。
ネイティブのvalueは統一されていない
JavaScriptのDOMでもvalueは取得できます。
document.getElementById('name').value;
ただしこれはinputに限った話です。selectになると話が変わります。
document.getElementById('pref').value;
動きますが、実際に使われているのはselectedIndexとoptionのvalueの組み合わせです。ブラウザによっては挙動が異なっていました。
checkboxやradioはさらにややこしくなります。
- チェックされていないとvalueは意味を持たない
- 複数選択では配列になる
- radioはグループで判定する
つまり「フォーム値取得」は単純なプロパティ参照ではありませんでした。
val()が内部で行っている処理
jQueryのval()は要素の種類を判定します。
- input[type=text] → valueプロパティ
- textarea → valueプロパティ
- select → 選択optionのvalue
- checkbox → checked状態と組み合わせ
- radio → 同一nameの選択要素を検索
特にradioは象徴的です。
<input type="radio" name="gender" value="m"> <input type="radio" name="gender" value="f">
ネイティブではこう書きます。
document.querySelector('input[name=gender]:checked').value;
しかしjQueryは単に次です。
$('input[name=gender]:checked').val();
ここでやっているのはvalueの取得ではなく、選択状態の解釈です。
値を設定するときの挙動
取得だけでなく設定も重要です。
$('#name').val('Taro');
これはvalueプロパティを変更しています。しかしselectでは違います。
$('#pref').val('tokyo');
jQueryは内部でoptionを探し、selected状態を変更します。さらにcheckboxの配列指定も可能です。
$('input[name=hobby]').val(['music','movie']);
これは一致するvalueを持つcheckboxをチェック状態にします。単なるvalue代入ではありません。
なぜこれが必要だったのか
昔のブラウザでは、フォーム要素の扱いが統一されていませんでした。
- selectのvalueが取得できないブラウザ
- radioのchecked判定が不安定
- textareaの改行コード差異
jQueryはこれを吸収しました。つまりval()は便利メソッドではなく、ブラウザ差異の正規化レイヤーです。
よくある誤解
val()はテキスト入力専用と思われがちですが、実際はフォーム要素全体のAPIです。checkboxやselectでこそ意味があります。
逆に次の使い方は誤解を招きます。
$('#form').val();
form自体にはvalueがありません。jQueryはundefinedを返します。val()はフォーム全体の値をまとめて取得する関数ではありません。
注意点:changeイベントとの関係
val()で値を設定してもchangeイベントは発火しません。
$('#name').val('Taro');
これはユーザー操作ではないためです。必要なら明示的に発火します。
$('#name').val('Taro').trigger('change');
ここを理解していないと、入力監視ロジックが動かない原因になります。
val()とattrの違い
よくある間違いがこれです。
$('#name').attr('value','Taro');
これは初期値を書き換えますが、現在の入力値は変わりません。val()はプロパティ、attrは属性です。チェックボックスのcheckedと同じ構造です。
結局val()は何をしているのか
val()はvalue取得関数ではありません。
- 要素の種類判定
- 状態の解釈
- プロパティ操作
- ブラウザ差異吸収
これらをまとめたAPIです。フォーム操作がjQueryで簡単だった理由の一つがここにあります。
見た目は一行ですが、内部ではかなり多くの条件分岐が動いています。val()はフォーム入力という「人間の操作」を、JavaScriptから安全に扱うための窓口だったと言えます。