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は「入力が変わった瞬間に毎回」発火し、onchangeは「入力が確定(多くはフォーカスが外れた後)してから」発火します。
oninput と onchange の違い(発火タイミング/使い分け)<input type="text"> と <textarea> のサンプルコード(console.logで発火確認)フォーム入力の挙動で迷いがちな初学者〜中級者(実務で入力補助・検証を作る人)向けです。
oninputは、テキストボックス、テキストエリア、または他の入力可能な要素において、ユーザーによる入力値の変更がある度に発生するイベントです。
oninputは「入力が変わるたびに毎回」発火し、onchangeは「入力が確定してから(多くはフォーカスが外れた後に)」発火します。リアルタイムの検証・プレビュー・サジェストはoninput、確定後に一回だけ処理したい保存・送信前チェックはonchangeが基本です。
発火タイミングを最短で確認:同じ入力欄に input(=oninput)と change(=onchange)を両方付けると差が一発で分かります。
HTML
<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は、物理キーの操作に依存するため、IME(日本語入力システム)の利用時など複雑な入力やペースト、コンテキストメニュー操作では意図した挙動にならないことがあります。oninputはこれらの問題を回避し、より包括的に入力の変化をキャッチできます。
HTML要素に直接oninput属性を記述する方法です。簡単な入力検証や表示の更新に利用されます。
HTML
<p>名前を入力してください:</p>
<input type="text" id="nameInput" oninput="handleInput()" placeholder="例:山田太郎">
<p>入力中の内容: <span id="output"></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> も 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
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とonkeyupを併用するケースもあります。例えば、入力補完中の暫定テキストと確定後のテキストを分けて扱いたい場合などです。
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エリアに転送され、たとえばその後の処理(サーバーへの送信、検証、検索実行など)を行うタイミングとして利用できます。oninputで変化を追いながらも、最終的な入力の確定タイミングをkeyupで捉えることで、特に日本語などの複雑な入力システムを利用する場合にも、思わぬ中間状態で処理を実行してしまうのを避ける工夫ができます。このように、oninputとonkeyupを組み合わせることで、ユーザー体験に即した柔軟な入力処理が実現できます。
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;
}
検索キーワードを入力してください:
サジェスト結果:
func)と遅延時間(delay:ここでは300ミリ秒)を受け取ります。funcが呼び出されます。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 を使い、数字以外の文字をすべて削除しています。slice(0, 3) で最初の3桁を取り出し、その後にハイフン、そして残りの数字(最大4桁分)を結合して新たな文字列として設定しています。このサンプルコードをもとに、実際のプロジェクトで郵便番号の入力をより使いやすくするための工夫が可能です。
先述のとおり、頻繁に発火するoninputイベントは、特にサーバーとの通信や計算量の大きい処理の場合、パフォーマンスに影響を与える可能性があります。
入力内容の解析や大規模なデータ処理が必要な場合、Web Workersを利用してバックグラウンドで処理を行い、UIスレッドのブロックを避けるという方法もあります。
日本語入力など、IMEを利用する際はcompositionstart、compositionupdate、compositionendイベントが発生します。
oninputイベントは、これらのイベントと連動するため、変換途中のテキストに反応することがあります。
※ 変換完了後のみの処理が必要な場合は、compositionendイベントで確定後の処理を行うなどの工夫が必要です。
入力が頻繁に変更されるため、処理が無駄に多重に実行される可能性がある。
→ 対策 : DebounceやThrottle処理の実装で負荷を軽減する。
スマートフォンやタブレットでは、物理キーボードが使われないため、oninputの発火タイミングや挙動がデスクトップと若干異なる場合があります。
→ 対策 : 複数のデバイスでテストを行い、ユーザー体験の均一性を確認する。
oninputイベントを利用してリアルタイムにコンテンツを更新する場合、スクリーンリーダーなど支援技術との連携を考慮し、必要に応じてaria属性などで補足情報を提供することが重要です。
oninputイベントは、モダンなブラウザでは広くサポートされています。ただし、古いブラウザ(特にIE9以前)では動作が異なる、もしくは対応していない場合があります。
→ 対策 :
onpropertychange(旧IE用)など、ブラウザ固有のイベントハンドリングを実装する。JavaScriptのoninputイベントは、入力内容のリアルタイムな変化を捉え、ユーザーインターフェイスの動的な反応を実現するために非常に強力なツールです。
oninput、入力確定後に一回だけ処理したい(保存・送信前の確定チェックなど)ならonchangeが基本です。