入力欄の値を取る
このレッスンで分かること
- 入力欄に打たれた文字は
valueで読みます。textContentには入りませんvalueは数字を打っても常に文字列で返ってきます
打った文字が textContent に入っていない
ここまでのイベント処理は、押されたかどうかだけを見ていました。今回からは、見ている人が打ち込んだ内容そのものを扱います。ところが、いつもの調子で中身を読もうとすると空っぽが返ってきます。
JavaScript
const keyword = document.querySelector("#keyword");
console.log(keyword.textContent); // "" いつまでも空のままtextContent はタグの中に書かれた文字を指します。入力欄に打った文字は HTML の中身ではなく、要素が持っている「いまの値」です。input はそもそも閉じタグを持たないので、中身という考え方が当てはまりません。読むときは value を使います。
JavaScript
console.log(keyword.value); // 打たれた文字がそのまま出るvalue は読むだけでなく、代入して書き換えることもできます。送信し終わったあとに keyword.value = "" と入れれば、入力欄を空に戻せます。
数を打っても、返ってくるのは文字列
ここが最初のわなです。type="number" の欄に 5 と打っても、value は数値の 5 ではなく文字列の "5" です。
JavaScript
const price = document.querySelector("#price").value; // "5"
console.log(price + 1); // "51"
console.log(Number(price) + 1); // 6第1章で見た文字列の連結が、そのまま起きています。足し算のつもりが横に並ぶ、というのはフォームを触りはじめた人が必ず一度は通る道です。数として使うなら Number() を通す、と決めておいてください。
逆に、文字を数えるなら文字列のままが都合よく、.length がそのまま使えます。日本語も英語も 1 文字は 1 として数えます。
JavaScript
console.log("こんにちは".length); // 5
console.log("".length); // 0何も打たれていない入力欄の value は null でも undefined でもなく、空文字列の "" です。"" は falsy なので、if (!input.value) と書くだけで未入力の判定になります。
打つたびか、離れたときか
値が変わったことを知らせるイベントは 2 つあります。
| イベント | いつ起きるか | 向いているもの |
|---|---|---|
| input | 1 文字打つたび。消すたびにも起きる | 文字数の表示、その場での絞り込み |
| change | 入力を終えて欄から離れたとき | 重い処理、確定してからの検証 |
input は打鍵のたびに起きるので、反応がとても細かくなります。打った瞬間に画面へ返したいものはこちらです。change は値が変わったうえでフォーカスが外れたときに 1 回だけ起きるので、select の選択やサーバーへの問い合わせのような重い処理に向いています。
JavaScript
keyword.addEventListener("input", function (event) {
console.log(event.target.value);
});前回の event がここでも使えます。event.target は出来事が起きた入力欄そのものなので、event.target.value で中身を読めます。外側の変数を使っても同じ結果になりますが、event.target で書いておくと、同じ関数を複数の入力欄で使い回せます。
なお、JavaScript から value に代入したときは input イベントが起きません。人が打ったときだけ起きるイベントだからです。代入と同時に表示も直したいなら、表示を更新する処理を関数にまとめておいて、代入のあとで自分から呼びます。
よくある間違い
textContentで読もうとする — 何を打っても空のままです。入力欄はvalueでしか読めません- 文字列のまま計算する —
"5" + 100は"5100"です。数として足すならNumber()を先に通します documentにイベントを登録する — ページ内のどの入力欄を打っても動いてしまいます。登録する相手は、値を見たい入力欄そのものです
課題
- HTML の
#messageのすぐ下にid="message-count"class="form-hint"のpを足し、最初の表示を「0 文字」にする - JavaScript で
#messageにinputイベントを登録する - 処理の中で
value.lengthを使い、#message-countに「5 文字」の形で表示する - 文字を消したときも表示が減ること