入力欄の値を取る

このレッスンで分かること

  • 入力欄の中身は input.value で読み取れます
  • value は数字を打っても常に文字列で返ってきます
  • 打つたびに反応させるなら input、確定してからでよいなら change を使います

入力欄の値を取る とは

input や textarea に打ち込まれた文字を JavaScript から読み取り、画面に反映することです。

画面から情報を受け取る

ここまでのイベント処理は、押されたかどうかだけを見ていました。今回からは、見ている人が打ち込んだ内容そのものを扱います。お問い合わせフォームの名前欄、メールアドレス欄、メッセージ欄。ここに入った文字を読めるようになると、入力チェックも文字数の表示も、検索の絞り込みもつくれるようになります。

読み取りは驚くほど簡単です。要素を取ってきて .value を見るだけです。

const messageInput = document.querySelector("#message"); console.log(messageInput.value);

textContent ではないところに注意してください。textContent はタグの中に書かれた文字を指します。入力欄に打った文字は HTML の中身ではなく、要素が持っている「いまの値」です。ここは value でしか取れません。input 要素は閉じタグを持たないので、そもそも中身という考え方が当てはまらない、と考えると腑に落ちやすいはずです。

取りたいもの使うもの
タグの中に書かれた文字textContenth3 の見出し、p の本文
入力欄に打たれた文字valueinput、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 がそのまま使えます。今回の課題はこちらです。

何も打たれていない入力欄の valuenull でも undefined でもなく、空文字列の "" です。第2章で見たとおり "" は falsy なので、if (!input.value) と書くだけで未入力の判定になります。この性質は次の次の回で使います。

input と change の違い

値が変わったことを知るためのイベントは 2 つあります。

イベント発生するタイミング向いている用途
input1 文字打つたび。消すたびにも起きる文字数の表示、その場での絞り込み
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 では #messageinput イベントを登録し、打たれるたびに文字数を数えて段落を書き換えます。表示は 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 に直接登録します。

課題

  1. HTML の #message のすぐ下に id="message-count" class="form-hint"p を足し、最初の表示を「0 文字」にする
  2. JavaScript で #messageinput イベントを登録する
  3. 処理の中で value.length を使い、#message-count に「5 文字」の形で表示する
  4. 文字を消したときも表示が減ること

ヒント

index.html
style.css
script.js
プレビュー

できているか

  • #message-count の段落がある
  • #message-count がお問い合わせの中にある
  • 最初から「0 文字」と出ている
  • 5 文字打つと「5 文字」になる
  • 消すと 0 に戻る