MochiuWiki : SUSE, EC, PCB
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
JavaScriptの基礎 - イベント(DOM)のソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
JavaScriptの基礎 - イベント(DOM)
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == DOMイベントとは、Webブラウザ上で発生するユーザ操作やシステム上の出来事を検出して処理するための仕組みである。<br> クリック、キー入力、フォーム送信、ページ読み込み等の出来事がイベントとして発生し、登録されたリスナー関数が呼び出される。<br> <br> イベントは <code>EventTarget</code> インターフェースを実装する全てのオブジェクトで発生する。<br> 代表的な実装対象として、<code>Element</code>、<code>Document</code>、<code>Window</code> があり、<code>XMLHttpRequest</code> や <code>AudioNode</code> 等もイベントを送出する。<br> <br> イベントの登録には、<code>addEventListener</code> メソッドを使用する。<br> イベントが発生すると、DOMツリーをキャプチャリングフェーズで下降して、ターゲットに到達した後にバブリングフェーズで上昇する。<br> <br> この伝播の仕組みを利用して、親要素で子要素のイベントをまとめて処理するイベント委譲というパターンも広く使われる。<br> <br> また、Reactではブラウザのネイティブイベントをラップした <code>SyntheticEvent</code> を使用しており、Webブラウザ間の差異を吸収している。<br> <br> DOMの基本操作については、[[JavaScriptの基礎 - DOM操作]]のページを参照すること。<br> <br><br> == addEventListener == <code>addEventListener</code> は、指定したイベントタイプに対してリスナー関数を登録するメソッドである。<br> 同じイベントタイプに対して複数のハンドラを登録でき、それぞれが独立して実行される。<br> <br> ==== 基本構文 ==== <code>addEventListener</code> の基本的な呼び出し形式を以下に示す。<br> <br> <syntaxhighlight lang="javascript"> element.addEventListener(type, listener) element.addEventListener(type, listener, options) element.addEventListener(type, listener, useCapture) </syntaxhighlight> <br> 下表に、引数の説明を示す。<br> <br> <center> {| class="wikitable" |+ addEventListener の引数一覧 ! 引数 !! 説明 |- | <code>type</code> !| 登録するイベントの種類を表す文字列<br>例: <code>'click'</code>, <code>'keydown'</code>, <code>'submit'</code> |- | <code>listener</code> || イベント発生時に呼び出されるコールバック関数<br>引数としてイベントオブジェクトを受け取る。 |- | <code>options</code> || オプションオブジェクト または <code>useCapture</code> の真偽値 (省略可能) |} </center> <br> 使用例を以下に示す。<br> <br> <syntaxhighlight lang="javascript"> const button = document.getElementById('myButton') button.addEventListener('click', (event) => { console.log('クリックされました') console.log(event.target) }) </syntaxhighlight> <br> ==== オプション ==== 第3引数にオブジェクトを渡すことにより、リスナーの動作を細かく制御できる。<br> <br> <center> {| class="wikitable" |+ addEventListenerオプション一覧 ! オプション !! 型 !! デフォルト !! 説明 |- | <code>capture</code> || Boolean || false || キャプチャフェーズでリスナーを実行するかどうかを指定する。<br><u>false</u> の場合はバブリングフェーズで実行される。 |- | <code>once</code> || Boolean || false || <code>true</code> の場合、<br>リスナーは最初のイベント発生時にのみ実行され、その後自動的に削除される。 |- | <code>passive</code> || Boolean || false || <u>true</u> の場合、<code>preventDefault()</code> を呼び出さないことをブラウザに宣言する。<br>スクロールパフォーマンスの向上に活用できる。 |- | <code>signal</code> || AbortSignal || - || <code>AbortSignal</code> オブジェクトを指定することにより、<br><code>abort()</code> 呼び出し時にリスナーを自動的に削除できる。 |} </center> <br> ===== onceオプション ===== <code>once: true</code> を指定すると、リスナーは最初のイベント発生時にのみ実行され、実行後に自動的に削除される。<br> 手動で <code>removeEventListener</code> を呼び出す必要がないため、1回限りの処理に適している。<br> <br> <syntaxhighlight lang="javascript"> const button = document.getElementById('myButton') // 最初の1回だけクリックを処理する button.addEventListener('click', (event) => { console.log('最初のクリックのみ処理されます') }, { once: true }) </syntaxhighlight> <br> ===== passive オプション ===== <code>passive: true</code> を指定すると、リスナー内で <code>preventDefault()</code> を呼び出さないことをWebブラウザに宣言する。<br> Webブラウザはリスナーの実行を待たずにスクロール処理を即座に開始できるため、スムーズなスクロール体験を実現できる。<br> <br> <syntaxhighlight lang="javascript"> const container = document.getElementById('scrollContainer') container.addEventListener('wheel', (event) => { // スクロール関連の処理 (preventDefault()は呼ばない) console.log('スクロール量:', event.deltaY) }, { passive: true }) </syntaxhighlight> <br> ===== signal オプション ===== <code>AbortController</code> と <code>AbortSignal</code> を組み合わせることにより、複数のリスナーを1度にまとめて削除できる。<br> 無名関数で登録したリスナーも削除できるため、関数参照を保持する必要がなくなる。<br> <br> <syntaxhighlight lang="javascript"> const controller = new AbortController() element.addEventListener('click', () => { console.log('クリックされました') }, { signal: controller.signal }) element.addEventListener('keydown', () => { console.log('キーが押されました') }, { signal: controller.signal }) element.addEventListener('mousemove', () => { console.log('マウスが移動しました') }, { signal: controller.signal }) // 全てのリスナーを一度に削除する controller.abort() </syntaxhighlight> <br><br> == removeEventListener == <code>removeEventListener</code> は、<code>addEventListener</code> で登録したリスナーを削除するメソッドである。<br> <br> ==== 基本的な使い方 ==== <code>removeEventListener</code> でリスナーを削除するには、登録時と同じ関数参照を渡す必要がある。<br> <br> <u>ただし、無名関数を使用した場合は同一の参照が得られないため、削除できないことに注意が必要である。</u><br> <br> <syntaxhighlight lang="javascript"> // 正しい例 : 名前付き関数を使用する function handleClick() { console.log('クリックされました') } element.addEventListener('click', handleClick) element.removeEventListener('click', handleClick) // 同じ参照なので削除される // 動作しない例 : 無名関数を使用する element.addEventListener('click', function() { console.log('clicked') }) element.removeEventListener('click', function() { console.log('clicked') }) // 別の関数参照なので削除されない </syntaxhighlight> <br> <u>また、<code>capture</code> フラグが登録時と完全に一致していない場合も削除に失敗する。</u><br> <br> <syntaxhighlight lang="javascript"> element.addEventListener('mousedown', handleMouseDown, true) element.removeEventListener('mousedown', handleMouseDown, true) // 成功 element.removeEventListener('mousedown', handleMouseDown, false) // 失敗 (captureが一致しない) </syntaxhighlight> <br> ==== AbortControllerによる解除 ==== <code>signal</code> オプションを活用した現代的なパターンでは、複数のリスナーをまとめて管理・解除できる。<br> コンポーネントのクリーンアップ処理等、複数のリスナーを一括削除する場面で有効である。<br> <br> <syntaxhighlight lang="javascript"> class EventManager { constructor() { this.controller = new AbortController() } setup(element) { const signal = this.controller.signal element.addEventListener('click', this.handleClick, { signal }) element.addEventListener('keydown', this.handleKeydown, { signal }) element.addEventListener('scroll', this.handleScroll, { signal }) } handleClick(event) { console.log('クリック:', event.target) } handleKeydown(event) { console.log('キー:', event.key) } handleScroll(event) { console.log('スクロール') } // 全てのリスナーを一括削除する cleanup() { this.controller.abort() } } </syntaxhighlight> <br><br> == イベントオブジェクト == イベント発生時にリスナー関数へ渡されるオブジェクトである。<br> 発生したイベントに関する詳細な情報とメソッドを提供する。<br> <br> ==== 共通プロパティ ==== 下表に、全てのイベントオブジェクトが持つ共通のプロパティを示す。<br> <br> <center> {| class="wikitable" |+ イベントオブジェクトの共通プロパティ ! プロパティ !! 型 !! 説明 |- | <code>type</code> || String || イベントの種類を識別する名前<br>例: <code>'click'</code>, <code>'keydown'</code> |- | <code>target</code> || EventTarget || イベントが最初にディスパッチされた要素<br>バブリング時も変わらない。 |- | <code>currentTarget</code> || EventTarget || 現在イベントリスナーが登録されている要素<br>バブリング中は変化する。 |- | <code>timeStamp</code> || DOMHighResTimeStamp || イベントが作成された時刻 (ページ表示開始からのミリ秒) |- | <code>eventPhase</code> || Number || イベントフローの現在フェーズ<br><br>1: キャプチャリング<br>2: ターゲット<br>3: バブリング |- | <code>bubbles</code> || Boolean || イベントがバブリングするかどうか |- | <code>cancelable</code> || Boolean || <code>preventDefault()</code> でデフォルト動作をキャンセルできるかどうか |- | <code>defaultPrevented</code> || Boolean || <code>preventDefault()</code> が呼び出されたかどうか |- | <code>isTrusted</code> || Boolean || Webブラウザにより生成されたイベントの場合は <u>true</u><br>スクリプトで生成した場合は <u>false</u> |} </center> <br> 下表に、<code>target</code> と <code>currentTarget</code> の違いを示す。<br> <br> <center> {| class="wikitable" |+ target と currentTarget の違い ! プロパティ !! 説明 |- | <code>event.target</code> || イベントが最初に発火した実際の要素<br>子要素をクリックした場合はその子要素を指す。 |- | <code>event.currentTarget</code> || リスナーが登録された要素<br>バブリング中は親要素を指すこともある。 |} </center> <br> ==== 共通メソッド ==== 全てのイベントオブジェクトが持つ主要なメソッドを以下に示す。<br> <br> ===== preventDefault ===== <code>cancelable</code> が <code>true</code> のイベントに対して、Webブラウザのデフォルト動作をキャンセルする。<br> <br> フォームの送信、リンクのナビゲーション、テキスト選択等のデフォルト動作を制御する時に使用する。<br> <br> <syntaxhighlight lang="javascript"> // フォームのデフォルト送信をキャンセルして独自処理を行う form.addEventListener('submit', (event) => { event.preventDefault() // 独自のバリデーションや非同期送信処理を実行 handleFormSubmit(new FormData(form)) }) // リンクのナビゲーションをキャンセルする link.addEventListener('click', (event) => { event.preventDefault() handleNavigation(link.href) }) </syntaxhighlight> <br> ===== stopPropagation ===== イベントのDOM内での伝播を停止する。<br> このメソッドを呼び出すと、親要素に向かうバブリングが停止する。<br> <br> <syntaxhighlight lang="javascript"> child.addEventListener('click', (event) => { event.stopPropagation() console.log('子要素のみで処理され、親要素には伝播しない') }) </syntaxhighlight> <br> ===== stopImmediatePropagation ===== <code>stopPropagation</code> の効果に加えて、同じ要素に登録された後続のリスナーの実行も防止する。<br> <br> <syntaxhighlight lang="javascript"> element.addEventListener('click', (event) => { event.stopImmediatePropagation() console.log('このリスナーは実行される') }) element.addEventListener('click', (event) => { console.log('このリスナーは実行されない') }) </syntaxhighlight> <br> ==== マウスイベントのプロパティ ==== 下表に、マウスイベント固有のプロパティを示す。<br> <br> <center> {| class="wikitable" |+ マウスイベントの座標プロパティ ! プロパティ !! 説明 |- | <code>clientX</code> / <code>clientY</code> || ビューポート (表示領域) の左上を原点とした座標<br>スクロール位置に依存しない。 |- | <code>pageX</code> / <code>pageY</code> || ドキュメント全体の左上を原点とした座標<br>スクロール量を含む。 |- | <code>offsetX</code> / <code>offsetY</code> || イベントのターゲット要素のパディングエッジを原点とした座標 |- | <code>screenX</code> / <code>screenY</code> || ユーザの物理スクリーンの左上を原点とした座標 |- | <code>button</code> || 押されたマウスボタンを示す数値<br><br>0 : 左ボタン<br>1 : 中ボタン<br>2 : 右ボタン<br><br><code>click</code> イベントでは常に <u>0</u> |- | <code>altKey</code> / <code>ctrlKey</code> / <code>shiftKey</code> / <code>metaKey</code> || イベント発生時に対応する修飾キーが押されていたかどうか |} </center> <br> ==== キーボードイベントのプロパティ ==== キーボードイベント固有の重要なプロパティを以下に示す。<br> <br> <center> {| class="wikitable" |+ key と code の違い ! プロパティ !! 説明 !! 例: 日本語キーボードで[Y]キーを押下した場合 |- | <code>key</code> || ユーザのキーボードレイアウトに依存した実際の文字 (論理キー) || <u>"y"</u> または <u>"Y"</u> |- | <code>code</code> || キーボードレイアウトに依存しない物理的なキーの位置 (物理キー) || <u>"KeyY"</u> (常に固定) |} </center> <br> 下表に、使い分けの指針を示す。<br> <br> <center> {| class="wikitable" |+ key と code の使い分けの指針 ! プロパティ !! 使用する場面 |- | <code>key</code> || ユーザが何を入力しているかを判定したい場合<br>(テキスト入力の処理、ショートカットキーの検出等) |- | <code>code</code> || キーボードの物理的な位置が重要な場合<br>(ゲームのWASD操作等、レイアウトによらず同じキーを使用する場合) |} </center> <br> <syntaxhighlight lang="javascript"> document.addEventListener('keydown', (event) => { console.log(`key: ${event.key}`) // "y" または "z" (レイアウトに依存) console.log(`code: ${event.code}`) // "KeyY" (常に物理位置) // 修飾キーの組み合わせを検出する例 if (event.ctrlKey && event.key === 's') { event.preventDefault() saveDocument() } }) </syntaxhighlight> <br><br> == イベントバブリングとキャプチャリング == DOMイベントは要素間を伝播する仕組みを持つ。<br> <br> この仕組みを理解することは、イベントハンドリングを正確に制御するために不可欠である。<br> <br> ==== 3つのフェーズ ==== DOMイベントは以下の3つのフェーズを順番に経る。<br> <br> # キャプチャリング段階 (<code>eventPhase: 1</code>) #: イベントはウィンドウから発生した要素 (ターゲット) に向かって伝播する。 #: <code>capture: true</code> で登録したリスナーがこのフェーズで実行される。 #: <br> # ターゲット段階 (<code>eventPhase: 2</code>) #: イベントがターゲット要素に到達した状態。 #: ターゲット要素に登録されたリスナーが実行される。 #: <br> # バブリング段階 (<code>eventPhase: 3</code>) #: イベントはターゲット要素から祖先要素に向かって伝播する。 #: デフォルト (<code>capture: false</code>) で登録したリスナーがこのフェーズで実行される。 <br> ==== バブリングの実例 ==== ネストした要素においてバブリングがどのように機能するかを以下に示す。<br> <br> <syntaxhighlight lang="javascript"> const parent = document.getElementById('parent') const child = document.getElementById('child') // バブリングフェーズ (デフォルト) で登録 parent.addEventListener('click', () => { console.log('Parent: バブリング') }) child.addEventListener('click', () => { console.log('Child: ターゲット') }) // child要素をクリックした際の実行順序: // 1. Child: ターゲット // 2. Parent: バブリング </syntaxhighlight> <br> ==== キャプチャリングの実例 ==== <code>capture: true</code> を指定すると、バブリングフェーズより先にリスナーが実行される。<br> <br> <syntaxhighlight lang="javascript"> const parent = document.getElementById('parent') const child = document.getElementById('child') // キャプチャリングフェーズで登録 parent.addEventListener('click', () => { console.log('Parent: キャプチャリング') }, { capture: true }) child.addEventListener('click', () => { console.log('Child: ターゲット') }) // バブリングフェーズで登録 parent.addEventListener('click', () => { console.log('Parent: バブリング') }) // child要素をクリックした際の実行順序: // 1. Parent: キャプチャリング // 2. Child: ターゲット // 3. Parent: バブリング </syntaxhighlight> <br> ==== バブリングしないイベント ==== 以下に示すイベントは <code>bubbles</code> プロパティが <u>false</u> であり、バブリングしない。<br> <br> * <u>focus</u> *: 代替として <u>focusin</u> (バブリングする) を使用できる。 * <u>blur</u> *: 代替として <u>focusout</u> (バブリングする) を使用できる。 * <u>mouseenter</u> *: 対応する <u>mouseover</u> はバブリングする。 * <u>mouseleave</u> *: 対応する <u>mouseout</u> はバブリングする。 * <u>load</u> * <u>unload</u> * <u>scroll</u> * <u>resize</u> <br> ==== stopPropagationの注意点 ==== <code>stopPropagation</code> を安易に使用すると、以下に示すような問題が生じる可能性がある。<br> <br> * グローバルに登録したクリックハンドラ (モーダルの外側クリックで閉じる処理等) が動作しなくなる。 * アナリティクスツールや計測タグのイベントトラッキングが機能しなくなる。 * 他の機能が依存するイベントリスナーが動作しなくなる。 <br> 代替として、<code>event.target</code> を確認することにより、伝播を止めずに条件分岐できる。<br> <br> <syntaxhighlight lang="javascript"> // stopPropagationを使用する代わりに、targetを確認する const modal = document.getElementById('modal') modal.addEventListener('click', (event) => { // モーダルの背景 (overlay) をクリックした場合のみ閉じる if (event.target === modal) { closeModal() } }) </syntaxhighlight> <br><br> == イベント委譲 == <u>イベント委譲 (Event Delegation) は、個々の子要素にリスナーを登録する代わりに、</u><br> <u>親要素1つにリスナーを登録し、バブリングを利用してイベントを処理するパターンである。</u><br> <br> ==== 概念と利点 ==== イベント委譲の主なメリットを以下に示す。<br> <br> * パフォーマンス向上 *: 登録するリスナーの数を大幅に削減できる。 *: 100件のリスト項目があっても、リスナーは1つで済む。 * 動的要素への対応 *: 後から追加された要素に対しても自動的にリスナーが適用される。 *: そのため、新たに登録し直す必要がない。 *: コード量の削減 *: 1つのハンドラで複数の要素のイベントを処理できる。 <br> ==== event.targetを使用したパターン ==== 最もシンプルなイベント委譲の例を以下に示す。<br> <br> <syntaxhighlight lang="javascript"> const list = document.getElementById('list') // リスト全体に1つのリスナーを登録する list.addEventListener('click', (event) => { // クリックされた要素が削除ボタンかどうかを確認する if (event.target.classList.contains('btn-delete')) { // 対象のリスト項目を削除する event.target.closest('li').remove() } // 編集ボタンのクリックを処理する if (event.target.classList.contains('btn-edit')) { const item = event.target.closest('li') startEditing(item) } }) </syntaxhighlight> <br> ==== event.target.closest()を使用したパターン ==== <code>closest()</code> メソッドを組み合わせることにより、ネストした要素構造でもより堅牢なイベント委譲を実装できる。<br> <code>closest()</code> の詳細については、[[JavaScriptの基礎 - DOM操作]]のページを参照すること。<br> <br> <syntaxhighlight lang="javascript"> document.getElementById('table-body').addEventListener('click', (event) => { // クリックされた位置から最も近い .btn-delete を持つ要素を探す const deleteBtn = event.target.closest('.btn-delete') if (deleteBtn) { // ボタンを含む行 (tr要素) を取得する const row = deleteBtn.closest('tr') const id = row.dataset.id // サーバーへの削除リクエストを送信してから行を削除する deleteRecord(id).then(() => { row.remove() }) } // 編集ボタンの処理 const editBtn = event.target.closest('.btn-edit') if (editBtn) { const row = editBtn.closest('tr') openEditDialog(row.dataset.id) } }) </syntaxhighlight> <br><br> == 主要なイベント一覧 == ==== マウスイベント ==== <center> {| class="wikitable" |+ マウスイベント一覧 ! イベント !! バブリング !! cancelable !! 説明 |- | <code>click</code> || ○ || ○ || 要素をクリック (マウスボタンを押して離す) した時に発生する。 |- | <code>dblclick</code> || ○ || ○ || 要素をダブルクリックした時に発生する。 |- | <code>mousedown</code> || ○ || ○ || マウスボタンを押した瞬間に発生する。 |- | <code>mouseup</code> || ○ || ○ || マウスボタンを離した瞬間に発生する。 |- | <code>mousemove</code> || ○ || × || マウスポインタが移動した時に発生する。 |- | <code>mouseenter</code> || × || × || ポインタが要素に進入した時に発生する。<br>バブリングしない。 |- | <code>mouseleave</code> || × || × || ポインタが要素から離脱した時に発生する。<br>バブリングしない。 |- | <code>mouseover</code> || ○ || × || ポインタが要素上に来た時に発生する。<br>子要素を含む。<br>バブリングする。 |- | <code>mouseout</code> || ○ || × || ポインタが要素から離れた時に発生する。<br>子要素を含む。<br>バブリングする。 |- | <code>contextmenu</code> || ○ || ○ || 右クリック時に発生する。<br><code>preventDefault()</code> でコンテキストメニューを抑制できる。 |} </center> <br> ==== キーボードイベント ==== <center> {| class="wikitable" |+ キーボードイベント一覧 ! イベント !! バブリング !! cancelable !! 説明 |- | <code>keydown</code> || ○ || ○ || キーを押した瞬間に発生する。<br>キーを押下し続けると繰り返し発生する。 |- | <code>keyup</code> || ○ || ○ || キーを離した瞬間に発生する。 |- | <code>keypress</code> || ○ || ○ || (非推奨) 文字キーを押した時に発生する。<br><code>keydown</code> または <code>input</code> イベントを使用すること。 |} </center> <br> <code>keypress</code> が非推奨となった理由を以下に示す。<br> * デバイスや入力方法への依存性が高く、IME (日本語入力等) で正しく機能しない場合がある。 * Webブラウザ間で動作にばらつきがある。 * テキスト入力の検出には、<code>input</code> イベント、キー操作の検出には <code>keydown</code> イベントを使用すること。 <br> ==== フォームイベント ==== <center> {| class="wikitable" |+ フォームイベント一覧 ! イベント !! バブリング !! cancelable !! 説明 |- | <code>submit</code> || ○ || ○ || フォームが送信された時に発生する。<br><code>preventDefault()</code> でページ遷移を防止できる。 |- | <code>change</code> || ○ || × || 入力値が変更され、要素がフォーカスを失った時に発生する。 |- | <code>input</code> || ○ || × || 入力値がリアルタイムに変更された時に発生する。 |- | <code>focus</code> || × || × || 要素がフォーカスを取得した時に発生する。<br>バブリングしない。 |- | <code>blur</code> || × || × || 要素がフォーカスを失った時に発生する。<br>バブリングしない。 |- | <code>reset</code> || ○ || ○ || フォームがリセットされた時に発生する。 |} </center> <br> ==== ドキュメント・ウィンドウイベント ==== <center> {| class="wikitable" |+ ドキュメント・ウィンドウイベント一覧 ! イベント !! バブリング !! cancelable !! 説明 |- | <code>DOMContentLoaded</code> || ○ || × || HTMLの解析が完了し、DOMが構築された時に発生する。<br>外部リソースの読み込み完了は待たない。 |- | <code>load</code> || × || × || ページ上の全てのリソース (画像、スクリプト等) の読み込みが完了した時に発生する。 |- | <code>beforeunload</code> || × || ○ || ページがアンロードされる直前に発生する。<br>ユーザへの離脱確認ダイアログを表示できる。 |- | <code>resize</code> || × || × || ウィンドウのサイズが変更された時に発生する。 |- | <code>scroll</code> || × || × || ページまたは要素がスクロールされた時に発生する。 |} </center> <br><br> == ReactのSyntheticEventとの違い == Reactは独自のイベントシステムとして <code>SyntheticEvent</code> を提供している。<br> <br> 下表に、ネイティブDOMイベントとの主な違いを示す。<br> <br> <center> {| class="wikitable" |+ ネイティブDOM vs React のイベント比較 ! 項目 !! ネイティブDOM !! React (SyntheticEvent) |- | 命名規則 || <code>onclick</code><br><code>onkeydown</code> (全て小文字) || <code>onClick</code><br><code>onKeyDown</code> (キャメルケース) |- | ハンドラの値 || 文字列 または 関数参照 || 関数参照のみ |- | イベント委譲 || 手動で親要素に実装する。 || Reactのルート要素に自動委譲される。 |- | イベントオブジェクト || ネイティブ <code>Event</code> オブジェクト || <code>SyntheticEvent</code> (ネイティブイベントのラッパー) |- | イベント解除 || <code>removeEventListener</code> を手動で呼び出す。 || コンポーネントのアンマウント時に自動削除される。 |- | クロスブラウザ対応 || Webブラウザごとに差異がある場合がある。 || 全てのWebブラウザで統一されたAPIを提供する。 |- | ネイティブイベントへのアクセス || そのまま使用 || <code>event.nativeEvent</code> でアクセス可能 |} </center> <br> <code>SyntheticEvent</code> の使用例を以下に示す。<br> <br> <syntaxhighlight lang="javascript"> // Reactコンポーネントでのイベント処理 function MyButton() { const handleClick = (event) => { // event は SyntheticEvent オブジェクト console.log(event.type) // "click" console.log(event.target) // クリックされた要素 // ネイティブイベントへのアクセス console.log(event.nativeEvent) // ネイティブ Event オブジェクト } return <button onClick={handleClick}>クリック</button> } </syntaxhighlight> <br> Reactでネイティブイベントを直接使用する場合は、<code>useEffect</code> フック内で <code>addEventListener</code> を呼び出す必要がある。<br> <br> <syntaxhighlight lang="javascript"> import { useEffect, useRef } from 'react' function MyComponent() { const elementRef = useRef(null) useEffect(() => { const element = elementRef.current const controller = new AbortController() // ネイティブのaddEventListenerを使用する element.addEventListener('click', handleClick, { signal: controller.signal }) // クリーンアップ処理 return () => controller.abort() }, []) return <div ref={elementRef}>要素</div> } </syntaxhighlight> <br><br> == 関連情報 == * [[JavaScriptの基礎 - DOM操作]] *: DOM要素の取得、作成、追加、削除、スタイル操作、closest()メソッドの詳細 * [[JavaScriptの基礎 - Fetch API]] *: AbortControllerを使ったリクエストのキャンセル、非同期処理 * [[JavaScriptの基礎 - エラーハンドリング]] *: try / catch構文、非同期処理のエラーハンドリング <br><br> {{#seo: |title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki |keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,電気回路,電子回路,基板,プリント基板 |description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux |image=/resources/assets/MochiuLogo_Single_Blue.png }} __FORCETOC__ [[カテゴリ:Web]]
JavaScriptの基礎 - イベント(DOM)
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse