JavaScriptのイベント対象が入れ子の場合の実装

aタグとその子孫要素に対して同時にクリックイベントを設定することがあったのですが、実装する際に少し手間取ったので実装方法をメモしておきます。

サンプルコード1

縦並びのリストのリンク内に、お気に入りのようなアイコンを配置してみます。
お気に入りアイコンをクリックすると、お気に入り登録の処理が行われる想定です。
(今回はサンプルなので、consoleを出すのみにしています。)

HTML

<ul class="list">
	<li class="list__item">
		<a href="https://www.google.co.jp/" class="list__link">
			<div class="list__image">
				<img src="http://placehold.it/80x80" />
			</div>
			<div class="list__text">
				<p class="list__description">テキストテキストテキスト</p>
				<div class="list__favorite">★</div>
			</div>
		</a>
	</li>
</ul>

CSS

.list__link {
	display: -webkit-box;
	display: -webkit-flex;
	display: flex;
	color: #000000;
	text-decoration: none;
}
.list__image {
	width: 80px;
	padding-right: 10px;
}
.list__favorite {
	display: inline-block;
	padding: 5px;
	color: #ffffff;
	background: #000000;
}

JavaScript

$(function() {
	$('.list__favorite').on('click', function(e) {
		console.log('お気に入り的な処理');
		e.preventDefault();
	});
});

お気に入りアイコンをクリックした時に処理を実行して、preventDefault()でリンクのページ遷移を行わないようにしています。
お気に入り登録のイベント追加のデモページ
 

サンプルコード2

先ほどのサンプルで、リンクをクリックした時にモーダルを開くようにする想定で修正してみます。

JavaScript

$(function() {
	$('.list__link').on('click', function(e) {
		console.log('モーダル的な処理');
		e.preventDefault();
	});
	$('.list__favorite').on('click', function(e) {
		console.log('お気に入り的な処理');
		e.preventDefault();
	});
});

モーダルのイベント追加のデモページ
リンクをクリックした時は問題ありませんが、アイコンをクリックした時にお気に入りの処理とモーダルの処理が発生してしまっています。
 

stopPropagation()を使うことで、JavaScriptで実行しているモーダルの処理を発生しないようにできます。

JavaScript

$(function() {
	$('.list__link').on('click', function(e) {
		console.log('モーダル的な処理');
		e.preventDefault();
	});
	$('.list__favorite').on('click', function(e) {
		console.log('お気に入り的な処理');
		e.preventDefault();
		e.stopPropagation();
	});
});

モーダルのイベント追加のデモページ2
 

サンプルコード3

縦並びのリストが動的に生成される想定で修正してみます。

HTML

リストを追加するボタンを追加します。

<ul class="list">
	<li class="list__item">
		<a href="https://www.google.co.jp/" class="list__link">
			<div class="list__image">
				<img src="http://placehold.it/80x80" />
			</div>
			<div class="list__text">
				<p class="list__description">テキストテキストテキスト</p>
				<div class="list__favorite">★</div>
			</div>
		</a>
	</li>
</ul>
<button id="add">要素追加</button>

JavaScript

var insert = '<li class="list__item">';
insert += '<a href="https://www.google.co.jp/" class="list__link">';
insert += '<div class="list__image">';
insert += '<img src="http://placehold.it/80x80" />';
insert += '</div>';
insert += '<div class="list__text">';
insert += '<p class="list__description">テキストテキストテキスト</p>';
insert += '<div class="list__favorite">★</div>';
insert += '</div>';
insert += '</a>';
insert += '</li>';

$(function() {
	$('.list__link').on('click', function(e) {
		console.log('モーダル的な処理');
		e.preventDefault();
	});
	$('.list__favorite').on('click', function(e) {
		console.log('お気に入り的な処理');
		e.preventDefault();
		e.stopPropagation();
	});
	$('#add').on('click', function(e) {
		$('.list').append(insert);
	});
});

動的に生成したリストにはイベントが設定されていないため、ページ遷移してしまいます。
動的に生成する場合のデモページ
 

$(document).on(‘event’, ‘element’, fn); の形式にすることで、動的に生成したリストでもイベントが発生するようになります。

JavaScript

var insert = '<li class="list__item">';
insert += '<a href="https://www.google.co.jp/" class="list__link">';
insert += '<div class="list__image">';
insert += '<img src="http://placehold.it/80x80" />';
insert += '</div>';
insert += '<div class="list__text">';
insert += '<p class="list__description">テキストテキストテキスト</p>';
insert += '<div class="list__favorite">★</div>';
insert += '</div>';
insert += '</a>';
insert += '</li>';

$(function() {
	$(document).on('click', '.list__link', function(e) {
		console.log('モーダル的な処理');
		e.preventDefault();
	});
	$(document).on('click', '.list__favorite', function(e) {
		console.log('お気に入り的な処理');
		e.preventDefault();
		e.stopPropagation();
	});
	$('#add').on('click', function(e) {
		$('.list').append(insert);
	});
});

動的に生成する場合のデモページ2
 

このエントリーをはてなブックマークに追加

関連記事

コメントを残す

メールアドレスが公開されることはありません。
* が付いている欄は必須項目です

コメントが承認されるまで時間がかかります。

2021年4月
 123
45678910
11121314151617
18192021222324
252627282930