前置き:

  • 環境: MacOS Catalina , Chrome
  • 言語: TypeScript/JavaScript
  • フレームワーク: Angular

※ 何か間違いがありましたら、ご指摘お願いします!

Sponsored Link


対処方法は2つ

僕が色々と調べてわかった対処法は下記2つです。

  1. 親と子を同じ階層に持ってくる
  2. Event オブジェクトを利用して、処理を中断させる

1. 親と子を同じ階層に持ってくる

JavaScript の性質上、ある要素のイベントを拾うと、その要素の親〜祖先要素全てをたどって、それら全ての要素にセットされたイベントを拾うようになっています。

そのため、もし click イベントを発動させたとき、親以上の階層に click イベントが2つあれば2つ、3つあれば3つ click イベントが発動します。

なので、click イベントを持つ要素を親子関係にしなければ、click イベントが発動しないようになります。

<div class="grandparent">
  <div class="parent" (click)="parentClickEvent()">
    <div class="child2" (click)="childClickEvent()"> ... </div>
  </div>
</div>

↓↓↓ 下記のように記述する ↓↓↓

<div class="parent">
  <div class="child1" (click)="childClickEvent()"> ... </div>
  <div class="child2" (click)="childClickEvent2()"> ... </div>
</div>

ただ、「どうしても親子関係の状態で click イベントを記述しておきたい!」という人は次の方法をとってみると良いと思います!

2. Event オブジェクトを利用して、処理を中断させる

この方法では、「Event オブジェクトにある target と、クリックした要素を比較して、異なる場合は処理を中断する」といった記述をします。記述する場所は、処理を中断させたい parentClickEvent() 内にします。

下記のような感じになります。

<div class="grandparent">
  <div class="parent" (click)="parentClickEvent()" #parentElement>
    <div class="child2" (click)="childClickEvent()"> ... </div>
  </div>
</div>
※ JavaScript ではなく TypeScript 仕様の書き方ですが、JavaScript でもちゃんとできます。

import { Renderer2 } from '@angular/core'
...
@ViewChild('parentElement') parentElement: ElementRef;

parentClickEvent(): void {
  let target: HTMLElement = Renderer2.event.target; // クリックした要素
  // ↑ こちらは、自分で発動させたい要素くらいはわかっていると思うので、
  // ↑ ViewChild を利用した、this.parentElement.nativeElement を使っても良いと思います!
  let currentTarget: HTMLElement = Renderer2.event.currentTarget; // 実行中イベントを持つ要素
  if (target === currentTarget) return;
  ... 任意の処理 ...
}

childClickEvent(): void {
  ... 任意の処理 ...
}

TypeScript の書き方ですが、「クリックした要素」と「event.target」が取得できていれば、JavaScript でも問題なくできます!

Sponsored Link


なぜ親と子の click イベントが一緒に発動してしまうのか?

親と子のイベントがどちらも一回のイベントで拾われて順番に発動する現象は、イベントバブリング と呼ばれています。全てのイベントで発生するものではないらしいですが、click イベントでは発生しました。(ちょっとだけ困った😂)

イベントバブリングは イベント伝搬(プロパゲーション) の一つで、イベント伝搬にはあと1つ イベントキャプチャリング があります。これについてはここでは詳しく触れません。

ただし、JavaScript を触れる上では、知っておいた方が良いことらしいです。(知らなかった)

僕も勉強中なので、あとで簡単に記事をまとめてみようと思います!
興味がある方はぜひ、下記の記事も見てみてください!

〜準備中〜

参照:

ちゃんと知ってる?JavaScriptのイベントバブリングを学ぼう

Sponsored Link