input の value とは何か
input 要素の value は「現在の入力値」を表す文字列です。type に関わらず、基本は文字列として読み書きします。ここが重要です:type=”number” でも value は文字列。計算したいときは Number(…) や parseFloat(…) で明示的に数値へ変換します。チェックボックスやラジオは“選択状態”(checked)と“文字列の value”が別物なので、使い分けが鍵です。
値の読み書きの基本(現在値・初期値・イベント)
いまの値を読む/書く
<input id="age" type="number" placeholder="年齢">
<script>
console.log(age.value); // 例: "23"(文字列)
age.value = "24"; // プログラムで書き換え
</script>
HTMLここが重要です:placeholder は表示上のヒントであり、value には入りません。プログラムから書き換えた値は、次の submit や FormData 取得に反映されます。
初期値(defaultValue)と現在値の違い
<input id="name" value="太郎">
<script>
console.log(name.defaultValue); // "太郎"(HTMLで書かれた初期値)
console.log(name.value); // ユーザー操作やJSで変わる“現在値”
</script>
HTMLここが重要です:defaultValue は初期表示を再現したいときに参照・復元に使えます。リセット(form.reset())は defaultValue に戻します。
いつ反応するか(input と change)
<input id="email" type="email">
<script>
email.addEventListener("input", () => console.log("入力途中:", email.value));
email.addEventListener("change", () => console.log("確定後:", email.value));
</script>
HTMLここが重要です:input は“タイピング中”に逐次、change は“確定後”(フォーカスが外れた等)に発火。ライブ検証は input、最終チェックや送信前確認は change が向いています。
type ごとの value の扱い(文字列が原則、例外の理解)
テキスト・数値・パスワードなど(文字列で扱う)
<input id="price" type="number" min="0" step="0.01">
<script>
const n = parseFloat(price.value || "0"); // 空文字対策
if (Number.isNaN(n)) { /* エラー扱い */ }
</script>
HTMLここが重要です:空文字は Number(…) で NaN。未入力の扱いを必ず決めておき、デフォルト値や検証メッセージを用意します。HTML の min/max/step はブラウザ検証の補助ですが、ロジック側でも検証を行うと安心です。
チェックボックスとラジオ(checked と value の役割)
<input id="agree" type="checkbox" value="yes">
<label><input name="color" type="radio" value="red">赤</label>
<label><input name="color" type="radio" value="blue">青</label>
<script>
console.log(agree.checked); // true/false(選択状態)
console.log(agree.value); // "yes"(選択時に送る文字列)
// ラジオは“グループの選択値”を見る
const group = document.querySelectorAll('input[name="color"]');
const selected = [...group].find(r => r.checked)?.value || "";
</script>
HTMLここが重要です:状態は checked、送る文字列は value。checkbox が未チェックなら FormData にキー自体が入りません(既定の value は “on”)。ラジオは“同じ name の中で一つ”だけが checked になります。
ファイル入力(value は使わない)
<input id="avatar" type="file" accept="image/*">
<script>
const file = avatar.files[0]; // File オブジェクトで扱う
if (file) console.log(file.name, file.size);
</script>
HTMLここが重要です:file の value はパス風文字列ですが使いません。実データは files の File オブジェクトで扱い、アップロードは FormData に append します。
日付・時刻のフォーマット
<input id="d" type="date">
<input id="t" type="time" step="1">
<script>
console.log(d.value); // "2025-12-14" のようなISO風文字列
console.log(t.value); // "13:45:07" など、step に応じたフォーマット
</script>
HTMLここが重要です:date/time は標準化された文字列で返ります。サーバー送信や比較がしやすい一方、ロケール表示と値フォーマットは別なので混同しない。
値の整形と入力体験(トリミング・正規化・IME配慮)
前後の空白を消して扱う(送信前整形)
<input id="username">
<script>
function normalized(v) {
return v.trim(); // 必要なら全角半角の正規化も
}
const clean = normalized(username.value);
</script>
HTMLここが重要です:送信・検索の前に trim するだけで“意図しない空白”による不一致を減らせます。必要なら全角スペースや濁点の正規化も検討。
フォーマット表示と値の分離
<input id="money" inputmode="numeric">
<script>
money.addEventListener("input", () => {
const raw = money.value.replace(/[^\d.]/g, "");
money.value = raw; // 値は常に“生”を維持
// 見た目のフォーマットは別の表示要素で
});
</script>
HTMLここが重要です:値を“生”で保持し、フォーマット(カンマ区切り等)は別要素で表示すると、カーソル飛びや IME との競合が減ります。どうしても中でフォーマットする場合は selectionStart/End を保持・復元してカーソルを守ります。
IME 合成中の扱い(composition への配慮)
<input id="jp">
<script>
let composing = false;
jp.addEventListener("compositionstart", () => composing = true);
jp.addEventListener("compositionend", () => composing = false);
jp.addEventListener("input", () => {
if (composing) return; // 合成中は検証や整形を遅らせる
// 検証・整形処理
});
</script>
HTMLここが重要です:日本語入力中(composition)の途中で強い整形やエラー表示をかけると体験が悪化します。確定後に処理する設計が安全です。
値の取得・送信の定番パターン(FormData と検証)
FormData で“送信相当”の値を一括取得
<form id="f">
<input name="email" value="a@example.com">
<input name="agree" type="checkbox"> <!-- 未チェックならキーが無い -->
</form>
<script>
const data = new FormData(f);
console.log(data.get("email")); // "a@example.com"
console.log(data.has("agree")); // true/false(チェックの有無)
console.log([...data.entries()]); // すべての [name, value]
</script>
HTMLここが重要です:FormData は実際の送信内容を再現します。checkbox は未チェックだと“キーなし”。必須判定は has()/get() で行うと正確です。
ブラウザ組み込みの検証と組み合わせる
<input id="mail" type="email" required>
<script>
mail.addEventListener("blur", () => {
if (!mail.checkValidity()) {
mail.classList.add("error");
} else {
mail.classList.remove("error");
}
});
</script>
HTMLここが重要です:HTML の required/type 属性で基本検証は賄えます。ロジック側は“確定後(blur)に優しく検証”し、入力中はヒント表示に留めると体験が良くなります。
よくある落とし穴と回避策
number の value を数値だと思い込む
value は文字列。ここが重要です:計算は必ず Number/parseFloat へ明示変換。空文字→NaN の扱いを決める。
checkbox の value を“状態”と誤解
状態は checked、文字列は value。未チェックは FormData に値が載らない。ここが重要です:has()/get() で存在判定する。
ラジオの選択値を単一 input から拾おうとして空振り
ラジオは“同じ name の集合”で扱う。ここが重要です:querySelectorAll でグループ化して checked の value を取るか、form.elements[“name”].value を使う。
入力途中に強制整形してカーソルが暴れる
整形は合成完了後(compositionend)や blur 時に行う。ここが重要です:どうしてもライブ整形するなら selectionStart/End を保存してから復元。
placeholder を値だと思って送信する
placeholder はヒントであり value ではない。ここが重要です:未入力の扱い(必須・デフォルト値)を設計で明確に。
まとめ
input の value は「現在の入力値」を表す文字列で、type に関係なく文字列として扱うのが原則です。計算時は明示的に数値化し、checkbox/radio は checked(状態)と value(送る文字列)を使い分けます。値の取得は value/form.elements/FormData を目的別に使い分け、検証はブラウザ組み込みと blur/input のタイミングで優しく行う。IME 合成やカーソル位置の配慮、trim/正規化で体験を整えると、初心者でも“壊れにくくて読みやすい”フォーム値処理が書けます。
