どうしたらいいでしょうか?
今回はこのような疑問に答えていきます。
前提:appendで追加した要素は通常クリックできません
前提としてお話します。
jQueryにおいて、appendなどで動的に追加した要素は、通常のやり方だとクリックできません。
つまり、以下のようなことをしようとしても失敗します。
const buttonDom = `<div class="more-read-button text-center">
<button id="more-read-button ">もっと見る</button>
</div>`;
$( ".message-button" ).append( buttonDom );
$( "#more-read-button" ).on( "click", function ()
{
console.log("クリックされたよ"); //このコードは動かない
});
そこでこの記事では、問題解決のための方法を2通り紹介していきます。
方法①:親要素にクリックイベントを設置する(dom操作で追加した子要素には設置しない)
まずは1つ目です。
jQueryでappendで追加した要素にクリックイベントを設置したい場合は、親要素に設置する方法で実現できます。
具体的なコードを紹介
このやり方のポイントは「読み込み時から存在する要素にクリックイベントをもたせる」ことです。
例えば、先程のコードの場合は、追加したボタンの要素の親要素のクラスは「message-button」です。
そちらにクリックイベントを設置しましょう。
コードは次のような感じです。
const buttonDom = `<div class="more-read-button text-center">
<button id="more-read-button ">もっと見る</button>
</div>`;
$( ".message-button" ).append( buttonDom );
$( ".message-button" ).on( "click", function ()
{
console.log("クリックされたよ"); //このコードは動く
});
こちらであれば、正常に動きます。
方法②:$( document ).onを使って第2引数に要素を渡す
2つ目の方法は「$( document ).on」を使うものです。
こちらの場合は、親要素を指定しなくても、追加したdom要素にクリックイベントを設置できます。
コードで解説
実際のコードは次のようになります。
const buttonDom = `<div class="more-read-button text-center">
<button id="more-read-button ">もっと見る</button>
</div>`;
$( ".message-button" ).append( buttonDom );
$( document ).on( "click", "#more-read-button", function ()
{
console.log("クリックされたよ"); //このコードは動く
});
このように、セレクタでdocumentを指定しつつ、on()の第2引数に、追加した子要素をセレクタで渡してあげるとうまく動作します。
補足:方法②は原則オススメしません
ちなみになのですが、方法②は通常オススメはしません。
なぜなら、「$( document ).on」を使う場合は、イベントパブリングによってルートノード(document)にたどり着くまでに時間がかかるからです。
クリックした要素から、ルートノードまでの距離が生まれるので、その分コストがかかるということです。
パフォーマンス的にはよくありません。
実装する場合は、今回紹介した方法①を採用するのが良いと思います。
追加した要素から1つ距離は離れていますが、特に負担にはならないはずです。
距離を0にしたいと思う方(追加した要素自体にクリックイベントを設置したい方)もいるかもですが、まぁそこまで拘る必要もないかなと...。
(どうしても、追加した要素自体にクリックイベントを設置したい場合はMutationObserverを使って、domの変更を監視しつつイベントをカスタマイズすることはできます)
ということで、今回はjQueryで動的に追加したDOM要素にクリックイベントが効かない場合の対処方法を紹介しました。
参考になれば幸いです。
最後まで読んでいただきありがとうございました。