JavaScript
この記事では、入力欄の内容が変わるたびに処理を実行するoninputイベントと、onchangeとの違いを説明します。
The JavaScript oninput event is an event that instantly responds whenever a user changes the content of an input field and processes those changes in real time.
oninput
oninputは「入力が変わった瞬間に毎回」発火し、onchangeは「入力が確定(多くはフォーカスが外れた後)してから」発火します。
oninputとonchangeの違い(発火タイミング/使い分け)<input type="text">と<textarea>のサンプルコード(console.logで発火確認)- リアルタイム処理(バリデーション/プレビュー/検索サジェスト)の実装パターン
フォーム入力の挙動で迷いがちな初学者〜中級者(実務で入力補助・検証を作る人)向けです。
oninput / onchange の違い(発火タイミングと使い分け)
- oninput
- 入力が変わるたびに毎回発火(入力中にリアルタイム反映)。
- 用途:バリデーション、ライブプレビュー、サジェスト、文字数カウント。
- onchange
- 入力が確定してから発火(多くはフォーカスが外れた後)。
- 用途:確定後の保存、送信前チェック、確定値での処理。
- Table Of Contents
oninputイベントとは?
基本概念
定義
oninputは、テキストボックス、テキストエリア、または他の入力可能な要素において、ユーザーによる入力値の変更がある度に発生するイベントです。
特徴
- リアルタイムの反応
- ユーザーが文字を入力するたびにイベントがトリガーされるため、入力内容のチェックや補完機能、動的な検索結果表示など、リアルタイム性が要求される処理に適しています。
- 多様な入力ソースに対応
- キーボード入力だけでなく、ペースト操作やドラッグ&ドロップによる値の変更も対象となります。
他のイベントとの違い
onchangeとの違い
oninputは「入力が変わるたびに毎回」発火し、onchangeは「入力が確定してから(多くはフォーカスが外れた後に)」発火します。リアルタイムの検証・プレビュー・サジェストはoninput、確定後に一回だけ処理したい保存・送信前チェックはonchangeが基本です。
発火タイミングを最短で確認:同じ入力欄に input(=oninput)と change(=onchange)を両方付けると差が一発で分かります。
HTML
<label for="timingCheck">入力値:</label>
<input type="text" id="timingCheck" placeholder="入力してからフォーカスを外す">
JavaScript
const el = document.getElementById('timingCheck');
el.addEventListener('input', () => {
console.log('input(oninput):', el.value);
});
el.addEventListener('change', () => {
console.log('change(onchange):', el.value);
});
発火ログ(ページ上でも確認できます)
keyup, keydownとの違い
キーボードイベントであるkeyupやkeydownは、物理キーの操作に依存するため、IME(日本語入力システム)の利用時など複雑な入力やペースト、コンテキストメニュー操作では意図した挙動にならないことがあります。oninputはこれらの問題を回避し、より包括的に入力の変化をキャッチできます。
基本的な使い方
HTMLでの利用
HTML要素に直接oninput属性を記述する方法です。簡単な入力検証や表示の更新に利用されます。
HTML
<label for="nameInput">名前を入力してください:</label>
<input type="text" id="nameInput" oninput="handleInput()" placeholder="例:山田太郎">
<p>入力中の内容: <span id="output" role="status" aria-live="polite" aria-atomic="true"></span></p>
<script>
<!-- JavaScript code here -->
</script>
JavaScript
function handleInput() {
// 入力された値を取得して表示する
var inputValue = document.getElementById('nameInput').value;
console.log('oninput:', inputValue);
document.getElementById('output').textContent = inputValue;
}
CSS
#nameInput {
margin-left: 1.2em;
}
入力中の内容:
textareaでの利用(複数行)
<textarea> も oninput で「入力中に毎回」反応します。メモ欄の文字数カウントやライブプレビューで定番です。
HTML
<textarea id="memoArea" rows="4" cols="30" placeholder="メモを入力"></textarea>
<p>文字数: <span id="memoLen">0</span></p>
JavaScript
const memoArea = document.getElementById('memoArea');
const memoLen = document.getElementById('memoLen');
memoArea.addEventListener('input', () => {
console.log('textarea oninput:', memoArea.value);
memoLen.textContent = String(memoArea.value.length);
});
文字数: 0
JavaScriptからイベントリスナーを登録する方法
HTMLに直接記述するのではなく、JavaScriptでイベントリスナーを追加する方法もあります。
この方法は、コードの分離と再利用性、保守性の向上に役立ちます。
HTML
<p>メールアドレスを入力してください:</p>
<input type="email" id="emailInput" placeholder="例:[email protected]">
<p>入力中のメール: <span id="emailOutput"></span></p>
<script>
<!-- JavaScript code here -->
</script>
JavaScript
const emailInput = document.getElementById('emailInput');
const emailOutput = document.getElementById('emailOutput');
emailInput.addEventListener('input', function() {
// 入力変更時にメールアドレスをリアルタイムで表示
emailOutput.textContent = emailInput.value;
});
CSS
#emailInput {
margin-left: 1.2em;
}
入力中のメール:
oninputイベントの内部動作と詳細
発火タイミングの詳細
入力操作
ユーザーがキーボードからテキストを入力、削除、ペースト、ドラッグ&ドロップ操作を行うと、即座に発火します。
IMEとの連携
日本語などの多バイト文字入力の場合、変換途中の状態もイベントが発火します。これにより、リアルタイムの自動補完やプレビュー機能の実装が可能ですが、場合によっては予期せぬ挙動となることもあるため注意が必要です。
他イベントとの連携
onkeyupとの併用
入力内容の最終的な確定を検知するために、oninputとonkeyupを併用するケースもあります。例えば、入力補完中の暫定テキストと確定後のテキストを分けて扱いたい場合などです。
- oninputイベント
- ユーザーが入力欄に文字を入力、削除、ペーストなどで変化があるたびに発火し、リアルタイムに内容を反映できます。たとえば、入力内容をそのまま別の表示エリアに出力することで、動的なフィードバックを実現します。
- onkeyupイベント
- キーが離された瞬間に発火するため、特定のキー(例: Enterキー)の操作を検知したり、変換(IME)などの確定後の入力に対して処理を実施する場合に利用します。入力途中での変化に反応する
oninputとは異なり、キー操作が完了した段階での確定情報として活用できます。
使用例:ライブプレビューと確定処理の併用
以下のサンプルコードは、テキスト入力フィールドに対してリアルタイムでプレビューを表示しながら、Enterキーが放されたときに「確定」処理を実施する例です。
HTML
<p>テキスト入力後、<kbd>Enter</kbd>キーを押す</p>
<input type="text" id="textInput" placeholder="文字を入力してください">
<div class="output">
<p>リアルタイムプレビュー : <span id="livePreview"></span></p>
<p>確定した内容 : <span id="finalOutput"></span></p>
</div>
<script>
<!-- JavaScript code here -->
</script>
JavaScript
const textInput = document.getElementById('textInput');
const livePreview = document.getElementById('livePreview');
const finalOutput = document.getElementById('finalOutput');
// oninputで入力された内容をリアルタイムにプレビュー表示
textInput.addEventListener('input', () => {
livePreview.textContent = textInput.value;
});
// onkeyupでEnterキーが放された場合に確定処理
textInput.addEventListener('keyup', (event) => {
if (event.key === 'Enter') {
// Enterキーが離されたとき、入力内容を確定として処理
finalOutput.textContent = textInput.value;
// ここでサーバーへの送信や他の処理を実行してもよい
console.log('入力確定:', textInput.value);
}
});
テキスト入力後、Enterキーを押す
リアルタイムプレビュー :
確定した内容 :
このコードのポイント
- リアルタイム更新
oninputイベントで入力欄の内容が変更されるたびに、livePreviewエリアが更新されるため、ユーザーは自分の入力内容を即座に確認できます。- キー操作による確定処理
onkeyupイベントでEnterキーが検知された際、入力内容がfinalOutputエリアに転送され、たとえばその後の処理(サーバーへの送信、検証、検索実行など)を行うタイミングとして利用できます。- IME対応の注意
- 入力中は
oninputで変化を追いながらも、最終的な入力の確定タイミングをkeyupで捉えることで、特に日本語などの複雑な入力システムを利用する場合にも、思わぬ中間状態で処理を実行してしまうのを避ける工夫ができます。
このように、oninputとonkeyupを組み合わせることで、ユーザー体験に即した柔軟な入力処理が実現できます。
debounce処理
Debounce処理は、ユーザーが入力欄に対して高速かつ連続して操作を行った場合に、一定時間操作が停止してから処理を実行することで、不必要な処理の実行を防ぐ手法です。これにより、たとえばサーバーへのリクエストや高負荷な計算処理を最小限に抑え、パフォーマンス向上とリソースの節約が実現されます。
以下は、oninputイベントと組み合わせたDebounce処理の具体的な使用例です。
HTML
<p>検索キーワードを入力してください:</p>
<input type="text" id="searchInput" placeholder="例:JavaScript">
<div class="result">
<p>サジェスト結果: <span id="suggestion"></span></p>
</div>
<script>
<!-- JavaScript code here -->
</script>
JavaScript
// debounce関数を定義(処理の実行を一定時間遅延させる)
function debounce(func, delay) {
let timeoutId;
return function(...args) {
// 既存のタイマーがあればクリア
if (timeoutId) {
clearTimeout(timeoutId);
}
// delay後にfuncを実行
timeoutId = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}
// サジェスト処理の例(ここではコンソールログと画面上のテキスト更新を実施)
function fetchSuggestion(query) {
// 実際の実装では、ここでサーバーにリクエストを送ることが考えられます。
console.log('サジェスト処理実行:', query);
document.getElementById('suggestion').textContent = '「' + query + '」のサジェスト結果';
}
// debounceを用いてfetchSuggestionの呼び出しを制御
const debouncedFetchSuggestion = debounce(fetchSuggestion, 300);
// oninputイベントにdebounce処理を組み合わせる
document.getElementById('searchInput').addEventListener('input', function() {
debouncedFetchSuggestion(this.value);
});
CSS
#searchInput {
margin-left: 1.2em;
}
サジェスト結果:
コード解説
- debounce関数
- 引数として実行したい関数(
func)と遅延時間(delay:ここでは300ミリ秒)を受け取ります。 - 入力操作が続いている間は、タイマーをクリアし続け、入力が一旦停止してから300ミリ秒後に
funcが呼び出されます。 - fetchSuggestion関数
- ユーザーの入力に基づいた処理をここで実施します。
- 例として、コンソールにメッセージを出力し、HTML内のサジェスト結果表示エリアにテキストを更新しています。
- イベントリスナー
- 入力欄(
searchInput)のoninputイベントに対して、debounce処理済みのfetchSuggestion(debouncedFetchSuggestion)を呼び出します。 - これにより、ユーザーが連続して文字を入力している間は
fetchSuggestionが実行されず、入力が止まった時点で処理が実行されます。
この実例では、ユーザーが文字を入力するとリアルタイムには反映せず、300ミリ秒の間隔を置いて処理が実行されるため、サーバー負荷や不要な計算を大幅に軽減でき、より効率的なシステムが構築できます。
高度な利用法と実践テクニック
入力補完とエラーチェック
oninputイベントを利用することで、入力内容の検証(バリデーション)や、ユーザーが入力中に候補となる補完リストを提示する機能を実装できます。
例として、郵便番号入力時に自動でハイフンを挿入するサンプルコードです。ユーザーが入力した値から数字以外を除外し、数字が4桁以上の場合に3桁目の後にハイフンを追加する処理を実装しています。
HTML
<p>郵便番号を入力してください</p>
<input type="text" id="zipcode" placeholder="例 : 1234567">
<p>入力された郵便番号 : <span id="display"></span></p>
JavaScript
// 郵便番号入力欄の要素を取得
const zipcodeInput = document.getElementById('zipcode');
const displaySpan = document.getElementById('display');
// 入力イベントリスナーを登録
zipcodeInput.addEventListener('input', function() {
// 入力値から数字以外の文字を削除
let value = this.value.replace(/[^0-9]/g, '');
// 数字が4桁以上の場合、3桁目の後にハイフンを挿入
if (value.length > 3) {
value = value.slice(0, 3) + '-' + value.slice(3, 7);
}
// 加工後の値を入力欄に反映
this.value = value;
// 入力結果を画面上に表示
displaySpan.textContent = value;
});
入力された郵便番号 :
コードのポイント
- 入力値のクレンジング
- 正規表現
/[^0-9]/gを使い、数字以外の文字をすべて削除しています。 - ハイフンの挿入
- 数字が4桁以上ある場合、
slice(0, 3)で最初の3桁を取り出し、その後にハイフン、そして残りの数字(最大4桁分)を結合して新たな文字列として設定しています。 - リアルタイム更新
- ユーザーが入力するたびに即座にハイフン付きの形式に整形し、また画面上に反映することで、正しいフォーマットかどうかを即座に確認できます。
このサンプルコードをもとに、実際のプロジェクトで郵便番号の入力をより使いやすくするための工夫が可能です。
イベントの制御とパフォーマンス
デバウンス/スロットリング
先述のとおり、頻繁に発火するoninputイベントは、特にサーバーとの通信や計算量の大きい処理の場合、パフォーマンスに影響を与える可能性があります。
- Debounce
- ユーザーの入力が一定期間停止したときにのみ処理を実行する。
- Throttle
- 一定時間ごとにのみ処理を実行する。
Web Workersとの連携
入力内容の解析や大規模なデータ処理が必要な場合、Web Workersを利用してバックグラウンドで処理を行い、UIスレッドのブロックを避けるという方法もあります。
IMEと特殊文字入力への対処
コンポジションイベント
日本語入力など、IMEを利用する際はcompositionstart、compositionupdate、compositionendイベントが発生します。
oninputイベントは、これらのイベントと連動するため、変換途中のテキストに反応することがあります。
※ 変換完了後のみの処理が必要な場合は、compositionendイベントで確定後の処理を行うなどの工夫が必要です。
注意点とよくある問題点
イベントの過剰発火
処理の重複
入力が頻繁に変更されるため、処理が無駄に多重に実行される可能性がある。
→ 対策 : DebounceやThrottle処理の実装で負荷を軽減する。
モバイルブラウザとの互換性
入力方式の違い
スマートフォンやタブレットでは、物理キーボードが使われないため、oninputの発火タイミングや挙動がデスクトップと若干異なる場合があります。
→ 対策 : 複数のデバイスでテストを行い、ユーザー体験の均一性を確認する。
アクセシビリティの考慮
スクリーンリーダー
oninputイベントを利用してリアルタイムにコンテンツを更新する場合、スクリーンリーダーなど支援技術との連携を考慮し、必要に応じてaria属性などで補足情報を提供することが重要です。
ブラウザ互換性
oninputイベントは、モダンなブラウザでは広くサポートされています。ただし、古いブラウザ(特にIE9以前)では動作が異なる、もしくは対応していない場合があります。
→ 対策 :
- 現在主流のブラウザでの互換性テストを実施する。
- ポリフィルやフォールバックの実装を検討する。
- 必要に応じて、
onpropertychange(旧IE用)など、ブラウザ固有のイベントハンドリングを実装する。
まとめ
JavaScriptのoninputイベントは、入力内容のリアルタイムな変化を捉え、ユーザーインターフェイスの動的な反応を実現するために非常に強力なツールです。
- 初心者は、基本的な使い方とHTMLに組み込んだシンプルな例から学ぶことで、インタラクティブなフォームの実装に慣れることができます。
- 中級者以上の開発者は、デバウンス・スロットリングなどのパフォーマンス最適化テクニック、IME対応、Web Workersとの連携など、より高度な実践的な手法を取り入れることで、洗練されたユーザー体験を提供できるようになります。
FAQ
- oninputはいつ使うべき?
- 入力中に「毎回」反応したいときです。例:入力補助、ライブプレビュー、検索サジェスト、文字数カウント、リアルタイムバリデーション。
- onchangeとの使い分け基準は?
- リアルタイムに反映したいなら
oninput、入力確定後に一回だけ処理したい(保存・送信前の確定チェックなど)ならonchangeが基本です。 - ブラウザ対応状況は?
- モダンブラウザでは広く動きますが、古いIE(特にIE9以前)では挙動差や未対応があります。互換性が必要なら実機テストとフォールバック(例:古い環境向けに別イベントを用意)を検討します。