入力欄の値を取る
このレッスンで分かること
- 入力欄の中身は
input.valueで読み取れますvalueは数字を打っても常に文字列で返ってきます- 打つたびに反応させるなら
input、確定してからでよいならchangeを使います
入力欄の値を取る とは
input や textarea に打ち込まれた文字を JavaScript から読み取り、画面に反映することです。
画面から情報を受け取る
ここまでのイベント処理は、押されたかどうかだけを見ていました。今回からは、見ている人が打ち込んだ内容そのものを扱います。お問い合わせフォームの名前欄、メールアドレス欄、メッセージ欄。ここに入った文字を読めるようになると、入力チェックも文字数の表示も、検索の絞り込みもつくれるようになります。
読み取りは驚くほど簡単です。要素を取ってきて .value を見るだけです。
const messageInput = document.querySelector("#message");
console.log(messageInput.value);textContent ではないところに注意してください。textContent はタグの中に書かれた文字を指します。入力欄に打った文字は HTML の中身ではなく、要素が持っている「いまの値」です。ここは value でしか取れません。input 要素は閉じタグを持たないので、そもそも中身という考え方が当てはまらない、と考えると腑に落ちやすいはずです。
| 取りたいもの | 使うもの | 例 |
|---|---|---|
| タグの中に書かれた文字 | textContent | h3 の見出し、p の本文 |
| 入力欄に打たれた文字 | value | input、textarea、select |
| チェックが入っているか | checked | チェックボックス、ラジオボタン |
value は必ず文字列
ここが最初のわなです。type="number" の入力欄に 5 と打っても、value は数値の 5 ではなく文字列の "5" です。
const price = document.querySelector("#price").value;
console.log(price + 1); // "51" になる
console.log(Number(price) + 1); // 6 になる第1章で見た文字列の連結が、そのまま起きています。足し算のつもりが横に並んでしまう、というのはフォームを扱い始めた人が必ず一度は通る道です。数として使うなら Number() で変換する、と決めておいてください。第2章で学んだ型変換が効いてくる場面です。
逆に、文字数を数えるなら文字列のままで都合がよく、value.length がそのまま使えます。今回の課題はこちらです。
何も打たれていない入力欄の
valueはnullでもundefinedでもなく、空文字列の""です。第2章で見たとおり""は falsy なので、if (!input.value)と書くだけで未入力の判定になります。この性質は次の次の回で使います。
input と change の違い
値が変わったことを知るためのイベントは 2 つあります。
| イベント | 発生するタイミング | 向いている用途 |
|---|---|---|
| input | 1 文字打つたび。消すたびにも起きる | 文字数の表示、その場での絞り込み |
| change | 入力を終えて欄から離れたとき | 重い処理、確定してからの検証 |
input は打鍵のたびに発生するので、反応がとても細かくなります。文字数カウンターや検索のインクリメンタル表示のように、打った瞬間に画面へ返したいものに向いています。
change は、値が変わったうえで欄からフォーカスが外れたときに 1 回だけ起きます。選択肢を選ぶ select や、サーバーに問い合わせるような重い処理では、こちらのほうが無駄がありません。
messageInput.addEventListener("input", function (event) {
messageCount.textContent = event.target.value.length + " 文字";
});前回の event がここでも使えます。event.target は出来事が起きた入力欄そのものなので、event.target.value で中身を読めます。外側の変数 messageInput を使っても同じ結果になりますが、event.target で書いておくと、同じ関数を複数の入力欄で使い回せるようになります。
読むだけでなく、書き込める
value は読み取り専用ではありません。代入すれば入力欄の中身を書き換えられます。
messageInput.value = ""; // 入力欄を空にする
messageInput.value = "はじめまして"; // 決まった文を入れる送信し終わったあとに入力欄を空に戻す、選ばれた候補を入力欄に流し込む、といった場面で使います。ただし、JavaScript から代入したときには input イベントは発生しません。人が打ったときだけ起きるイベントだからです。代入と同時に文字数の表示も直したいなら、表示を更新する処理を関数にまとめておいて、代入のあとで自分で呼びます。
function updateCount() {
messageCount.textContent = messageInput.value.length + " 文字";
}
messageInput.addEventListener("input", updateCount);第6章で学んだとおり、名前を付けた関数を渡しています。丸かっこを付けないところに気を付けてください。こうしておけば、初期表示のときにも updateCount() を 1 回呼ぶだけで数をそろえられます。
文字数は length で数える
文字列の長さは .length で取れます。配列の要素数と同じ書き方です。
"こんにちは".length; // 5
"".length; // 0日本語も英語も 1 文字は 1 として数えます。厳密には絵文字や一部の記号は 2 として数えられることがありますが、入門の範囲では気にしなくて大丈夫です。
文字数の表示は、見ている人にとってありがたい機能です。「200 文字まで」と書かれていても、いま何文字打ったのかが分からなければ、送信して怒られるまで気付けません。残り何文字かをその場に出しておけば、打ちながら調整できます。上限を超えたら色を変える、といった工夫も、前の回でやった classList と組み合わせれば書けます。
messageCount.textContent = "残り " + (200 - messageInput.value.length) + " 文字";引き算の結果を文字列に混ぜるときは、丸かっこで先に計算させます。付け忘れると左から順に連結されて、思わぬ表示になります。
今回書くこと
お問い合わせのメッセージ欄の下に、id="message-count" の段落を足します。最初は 0 文字 と書いておきます。JavaScript では #message に input イベントを登録し、打たれるたびに文字数を数えて段落を書き換えます。表示は 5 文字 のように、数のうしろに 文字 を付けた形にしてください。
よくある間違い
textContent で読もうとする
const text = document.querySelector("#message").textContent;入力欄の中身は textContent には入りません。何を打っても空のままです。value を使います。
文字列のまま計算する
const total = document.querySelector("#price").value + 100;"5" + 100 は "5100" です。Number() を通してから足します。
登録する相手を間違える
document.addEventListener("input", function (event) {
messageCount.textContent = event.target.value.length + " 文字";
});document に登録すると、名前欄やメール欄を打ったときにも動いてしまいます。今回は #message に直接登録します。
課題
- HTML の
#messageのすぐ下にid="message-count"class="form-hint"のpを足し、最初の表示を「0 文字」にする - JavaScript で
#messageにinputイベントを登録する - 処理の中で
value.lengthを使い、#message-countに「5 文字」の形で表示する - 文字を消したときも表示が減ること