Closed11
Event Delegationをちょっと調べて、pointer-events: noneを置き換える
このスクラップのベースはこれ
この前公開した記事で、「動的生成の要素のそれぞれにイベントハンドラを設定するには、その要素それぞれを囲むコンテナーにイベントを設定すると良いんだよ」って書いた。
こう書いてたのを…
改善前.js
const taskCompletedButtons = document.querySelectorAll('.btn-completed');
taskCompletedButtons.forEach((e) => {
e.addEventListener('click', (j) => {
if(j.target.className === 'Hello') {
// なにか処理がはいります
}
});
});
こう書くようにする
const listRootElm = document.getElementById('container');
listRootElm.addEventListener('click', (e) => {
if(e.target.className === 'btn-completed') {
// なにか処理がはいります
}
});
でもこうすると、たとえば下記のようなHTMLを前提にすると、spanで囲んだ要素をクリックしてもイベントが発生しない。
サンプルHTML
<ul id="container">
<li>
<buton class="btn-completed">
<span class="btn-completed-text">タスクを完了にする</span>
</buton>
健康診断の予約をする
</li>
<li>
<buton class="btn-completed">
<span class="btn-completed-text">タスクを完了にする</span>
</buton>
ガス代の支払いをする
</li>
</ul>
これをボタン(.btn
)の範囲内がクリックされたときにifの条件を満たすようにするために、一番最初に載せたリンクを参照して、以下のCSSを追加した。
.btn-completed-text {
pointer-events: none;
}
解決したいことは解決したので、別にこれでもいいんだけど、
今日改めてイベント移譲(Event Delegation)の記事を見たら、どうもCSSを追加しなくてもいけそうなことを発見したので書き換えようと思う。
参考にする該当コードをそのままコピーしてきた
table.onclick = function(event) {
let td = event.target.closest('td'); // (1)
if (!td) return; // (2)
if (!table.contains(td)) return; // (3)
highlight(td); // (4)
};
イベントが発生した要素の親に、指定要素が含まれているかを確認している
let td = event.target.closest('td');
含まれてなければ処理はそこで終了
if (!td) return;
コンテナー要素をイベント監視の対象にしているので、イベントの発生した要素が、想定したコンテナーに属するのかを確認する
if (!table.contains(td)) return;
これを使えば、pointer-events: none;
を指定しなくても良くなる
let td = event.target.closest('td');
このスクラップは2022/05/07にクローズされました