Step 1: Web Basics
04. イベントリスナー入門:
onclickを卒業して
ボタンに命を吹き込む
「ボタンが押されたら何かする」という処理は、Webアプリにおける対話の第一歩です。最初はHTMLの中に直接命令を書いていましたが、保守性の高い綺麗なコードを目指すなら「イベントリスナー」への移行が欠かせません。インフラエンジニアの視点で「関心の分離」を学んだ記録です。
1. HTMLにJavaScriptを書くのは「密結合」のリスク
Webサイトに動きをつけようとしたとき、真っ先に思いつくのがHTML要素の属性として直接JavaScriptを記述する onclick 属性ではないでしょうか。
<!-- 避けるべき古い書き方:インラインイベントハンドラ -->
<button onclick="alert('クリックされました!')">送信</button> この方法は手軽ですが、プロジェクトが大きくなるにつれて「どこにどんなロジックが書かれているか」が分からなくなる「密結合」という状態を招きます。インフラの世界で例えるなら、サーバーの起動スクリプトの中にOSの設定を直接書き込んでしまうようなものです。設定(HTML)と実行ロジック(JavaScript)は、明確に分離すべきなのです。
2. 監視役を任命する:addEventListener
そこで登場するのが addEventListener です。これは要素に対して「特定のイベント(クリックやスクロールなど)が起きたら、この関数を実行してね」という監視役を任命する仕組みです。
HTML側には id だけを振り、JavaScript側ですべての挙動をコントロールすることで、コードの可読性と再利用性が劇的に向上します。
コードで見る Before / After
【Before】HTMLの中にロジックが漏れ出している状態
<button onclick="processData()" id="save-btn">保存</button> 【After】HTMLは構造に専念し、JSで挙動を定義する状態
// HTMLは <button id="save-btn">保存</button> のみ
const saveBtn = document.getElementById('save-btn');
// 推奨される現代的な記述
saveBtn.addEventListener('click', () => {
console.log('データを保存します...');
saveToDatabase(); // 外部の重い処理もここから呼び出す
}); 3. なぜ addEventListener を使うべきなのか
単に「綺麗だから」という理由だけではありません。addEventListener には、属性ベースの onclick にはない強力なメリットがあります。
- 複数の処理を登録できる:
onclickは1つの要素に1つしか登録できませんが、リスナーなら「ログを記録する」「色を変える」「データを送る」といった複数の処理を同時並行で監視できます。 - 動的な解除が可能:
removeEventListenerを使えば、特定の条件下で監視を止めることができます。これはメモリ管理の面でも非常に重要です。 - イベントの伝播を制御できる: バブリング(親要素への波及)を止めるなど、複雑なUI制御が可能になります。
4. 注意点:初心者がやりがちな「()」の付け忘れ
イベントリスナーを学び始めたとき、私が最も多く犯したミスが、関数を登録する際に () を付けてしまうことでした。
// ❌ 間違い:関数がその場で実行されてしまう
btn.addEventListener('click', doSomething());
// ✅ 正解:関数の「名前(参照)」だけを渡す
btn.addEventListener('click', doSomething); () を付けると、ボタンが押される前にスクリプトが読み込まれた瞬間に実行されてしまいます。イベントリスナーには「いつか実行するためのレシピ」を渡すのであって、「今すぐの結果」を渡すのではないという感覚が大切です。
5. 実務での活用:猫の手ツールの場合
「猫の手ツール」の開発において、イベントリスナーは至る所で活躍しています。
- 画像選択:
<input>要素のchangeイベントを監視して、写真が選ばれた瞬間にプレビューを生成する。 - ドラッグ&ドロップ:
dropイベントを拾い上げ、ブラウザ標準の「ファイルを開く」挙動をキャンセルしつつ、画像加工処理へ流し込む。 - ダウンロードボタン:
clickイベント時にCanvasからBlobデータを生成し、ユーザーの端末へ安全に保存する。
ユーザーの何気ないアクションをトリガーにして、複雑な処理を連鎖させていく。この「パズルを組み立てるような感覚」こそが、フロントエンド開発の醍醐味であり、ツールに命を吹き込む瞬間なのだと感じています。