ブラウザ
 Computer >> コンピューター >  >> ソフトウェア >> ブラウザ

event.preventDefault() と event.stopPropagation() でブラウザのデフォルト動作を制御する方法

ブラウザには、さまざまなイベントに対してあらかじめ用意されたデフォルトの挙動が存在します。

たとえば、ユーザーがフォームの「送信」ボタンをクリックすると、フォームのデータはデフォルトで指定されたURLへ送信されます。

また、要素の子要素をクリックした場合、その親要素(コンテナ)でもクリックイベントが発生します。これはイベントが親要素へ伝播するためです。

しかし、場合によってはこれらのデフォルトの挙動を上書きしたいこともあるでしょう。この記事では、event.preventDefault()event.stopPropagation() の2つのメソッドについて解説し、ブラウザで発生するデフォルトのアクションをキャンセルする方法を学びます。

event.preventDefault()

このメソッドは、イベントが発生したときにブラウザが実行するデフォルトのアクションを防止します。

以下に、Webページでよく見られるデフォルトアクションの例と、event.preventDefault() を使ってそれらを上書きする方法を紹介します。

フォーム送信のデフォルト動作を上書きする方法

ユーザーがフォームを送信すると(送信ボタンがクリックされると)、フォームのデフォルトの動作として、データが処理用のURLへ送信されます。

form要素には action 属性と method 属性があり、それぞれフォームの送信先URLとリクエストの種類(getpost など)を指定します。

これらの属性が指定されていない場合、送信先は現在のURLとなり、メソッドには get が使用されます。

たとえば、次のコードを見てみましょう。

<form>
  <input name="email" />
  <input name="password" />
  <input type="submit" />
</form>

このコードから次のようなページが生成されます。

event.preventDefault() と event.stopPropagation() でブラウザのデフォルト動作を制御する方法

「dillion」と「password」と入力してフォームを送信すると、次のように 127.0.0.1:5500/index.htmlget リクエストが送信されているのがわかります。

event.preventDefault() と event.stopPropagation() でブラウザのデフォルト動作を制御する方法

これが、ブラウザがフォームを処理する際のデフォルトの動作です。

しかし、リクエストを送信する前にデータに対して何らかの処理を行いたいケースも多いでしょう。これは現代のフォーム処理では非常に一般的なアプローチです。

たとえば、リクエストをURLへ送る前に、データのバリデーションや整合性チェック、加工、ヘッダーの設定などを行いたい場合があります。

こうしたシナリオでは、フォームのデフォルトの動作を防ぎたいはずです。その実装方法は以下のとおりです。

<form id='form'>
  ...
</form>
const form = document.getElementById('form')

form.addEventListener('submit', (event) => {
  event.preventDefault()
  
  // データを処理し、手動でリクエストを送信する
})

このようにすれば、フォームの送信は自分の手でコントロールできるようになります。

リンク(href 属性を持つアンカータグ a)をクリックすると、デフォルトではブラウザがクリックされたリンク先へ遷移します。

もし、その遷移を横取りして、ナビゲーションの前に何らかの処理を行いたい場合はどうすればよいでしょうか。たとえば、ユーザーが移動先のページへのアクセス権を持っているかどうかを確認するようなケースです。その実装方法は以下のとおりです。

<a id="link" href="https://google.com">Google</a>
const link = document.getElementById("link")

link.addEventListener("click", event => {
  event.preventDefault()

  // 何らかの処理を行ってから遷移する
})

実際に試してみてください。「Google」リンクをクリックしてもページ遷移は発生しません。デフォルトのナビゲーション動作を防止したためです。以降は、遷移処理を自分で実装することになります。

event.stopPropagation()

伝播(プロパゲーション)とは、何かを広げる行為のことで、ここではイベントの伝播を指します。stopPropagation メソッドは、要素でイベントが発生したときに、そのイベントが広がるのを防ぐために使用されます。

JavaScriptでは、要素に対してイベントを発生させると、そのイベントはDOMツリーをさかのぼって親要素や祖先要素へとバブリングしていきます。基本的に、イベントが発生した要素は親のコンテナの「内側」にあるため、親要素も同じイベントを受け取ることになります。

これをよりわかりやすく説明するために、例を使ってみましょう。

要素の子要素をクリックする

次のような要素があるとします。

<div>
  <button>Click me</button>
</div>

button をクリックするとき、ボタンがdivコンテナの中にあるため、同時にdivコンテナもクリックしていることになります。この仕組みにより、クリックイベントはボタンからコンテナへと伝播し、さらにすべての祖先要素を経由してルートまで広がっていきます。

これを確認するために、次のコードでどのように動作するのかを見てみましょう。

<div id="div">
  <button id="button">Click me</button>
</div>
const div = document.getElementById('div')
const button = document.getElementById('button')

button.addEventListener('click', () => {
  console.log('button clicked')
})

div.addEventListener('click', () => {
  console.log('div container clicked')
})

このコードをブラウザで実行してボタンをクリックすると、次のような結果が得られます。

event.preventDefault() と event.stopPropagation() でブラウザのデフォルト動作を制御する方法

divコンテナもクリックイベントを受け取っているため、クリックのコールバック関数も呼び出されています。

イベントの伝播はイベントと要素のデフォルトの挙動ですが、場合によっては望まない挙動になることもあります。数ある例のうち、ここでは1つ紹介します。

Gmailの新規メッセージポップアップです。

event.preventDefault() と event.stopPropagation() でブラウザのデフォルト動作を制御する方法

上部には3つのアクションボタンがあります。1つはポップアップを最小化し、1つは全画面表示に切り替え、もう1つはポップアップを閉じます。

しかし、「新規メッセージ」のテキストがある上部バーにもクリックハンドラーが設定されており、クリックするとポップアップが最小化されるようになっています。

event.preventDefault() と event.stopPropagation() でブラウザのデフォルト動作を制御する方法

ここで避けたいのは、いずれかのボタンをクリックした際に、クリックイベントが上部バーにまで伝播してしまい、そちらのイベントハンドラーも実行されてしまうことです。つまり、たとえば閉じるボタンをクリックしたときに、上部バーまで最小化されてしまうのは望ましくありません。

こうしたケースでは、伝播を止める必要があります。

ポップアップが次のように構築されていると仮定します。

<div id='top-bar'>
  <!-- メッセージ要素 -->
  <!-- ボタン群 -->
</div>
const topBar = document.getElementById('top-bar')
const closeButton = document.getElementById('close-btn')

topBar.addEventListener('click', () => {
  // ポップアップを最小化または最大化する
})

closeButton.addEventListener('click', () => {
  // ポップアップを閉じる
})

さらに、イベントが上部バーに広がらないように、ボタンのリスナーにも stopPropagation メソッドを追加します。そのためには、ボタンのリスナーを次のように更新します。

closeButton.addEventListener('click', (event) => {
  event.stopPropagation()
  // ポップアップを閉じる
})

これにより、上部バーは直接クリックされたときにのみクリックイベントを受け取るようになります。

まとめ

event.preventDefault()event.stopPropagation() の違いは、前者がブラウザによるデフォルトのアクションを防止するのに対し、後者はイベント自体のデフォルトの挙動(ツリーをさかのぼる伝播)を防止するという点です。

これらのデフォルトのアクションや挙動は誤りではなく、通常のコーディング中に特別に気にかける必要はありません。しかし、この記事の例で見てきたように、これらを上書きしたいシナリオも実際には存在します。用途に応じて適切に使い分けることで、より柔軟なイベント処理を実現できます。

  1. 【初心者向け】Microsoft Edgeで閲覧データを管理・削除する方法

    Microsoft Edgeで閲覧データを管理・削除する方法 Windows 10の登場とともに、Microsoftは長年親しまれてきたInternet Explorerに代わる新たな標準ブラウザとして「Microsoft Edge」を投入しました。Edgeは、ハードドライブに保存する情報を種類ごとにきちんと分類して管理しており、ログイン資格情報、Cookie、キャッシュなどを保存します。さらに、ポップアップの表示を許可したサイトの一覧や、ストリーミングコンテンツの視聴に必要なデジタル著作権管理(DRM)データといった、閲覧セッションやユーザー設定に関する項目も保持しています。 こうした機能は

  2. 【Microsoft Edge】キャッシュとCookieをクリアする方法を徹底解説

    Edgeブラウザのキャッシュをクリアする方法をお探しですか?インターネットでウェブサイトを閲覧すると、キャッシュやCookieがバックグラウンドで自動的に作成され、ハードディスクに保存されます。これはすべてのブラウザで起こる現象であり、一度訪れたページの2回目以降の読み込みが速くなるなど、便利な面もあります。しかし、キャッシュやCookieにはいくつかのデメリットもあり、そのひとつとして、Webページの新しいコンテンツが正しく表示されなくなることがあります。最善の解決策は、定期的にキャッシュとCookieをクリアすることです。この記事では、Edgeブラウザでキャッシュをクリアする方法をわかりや