質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

4回答

50791閲覧

【$(document).on()】について

hoshiimohunda

総合スコア15

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

3クリップ

投稿2017/03/01 01:25

編集2017/03/01 03:02

jqueryでクリックイベントを拾いたいような場合、
以下の記述で可能かと思います。

$(【セレクタ】).o n('click', function () { // 何かの処理 });

しかし、上記の場合、後から追加されたHTMLについては
クリックイベントが発動しないため、
HTMLを追加したタイミングでイベントの再読み込みが必要かと思います。

以下の記述であれば、後から追加されたHTMLについても
クリックイベントが有効なのですが、
上記の記述方法に比べてパフォーマンスが悪いなどはありますでしょうか?
※部分更新を多く行いたいため本件ご質問させていただきました。

$(document).on('click', '【セレクタ】', function () { // 何かの処理 });

お手数ですが、ご存じの方いらっしゃいましたらご教示ください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kei344

2017/03/01 02:18

質問文のコードはそれぞれコードブロックで囲んでいただけませんか? ```(バッククオート3つ)で囲み、前後に改行をいれるか、コードを選択して「<code>」ボタンを押すとコードブロックになります。
hoshiimohunda

2017/03/01 03:03

kei344 さんご指摘ありがとうございます。コードブロックにさせていただきました。
guest

回答4

0

ベストアンサー

イベントバブリング

理論上はイベントバブリングによってルートノード(document)に辿り着くまでに伝播する数だけパフォーマンスに差が出ます。

HTML

1<!DOCTYPE html> 2<html> 3 <head> 4 <title>sample</title> 5 <script src="./jquery-3.1.1.js"></script> 6 <script> 7 'use strict'; 8 jQuery(document).on('click', '.bar', function (event) { 9 console.log(event.type); 10 }); 11 </script> 12 </head> 13 <body> 14 <main> 15 <ul id="foo"> 16 <li class="bar">bar</li> 17 <li class="bar">bar</li> 18 <li class="bar">bar</li> 19 <li class="bar">bar</li> 20 </ul> 21 </main> 22 </body> 23</html>

上記HTMLでは「li -> ul -> main -> body -> html -> document」と伝播されます。
伝播する数を抑える為にはより対象の要素ノードに近い場所にイベント定義する必要があります。
この例でいえば、#foo でイベント定義すればいいでしょう。

JavaScript

1jQuery('#foo').on('click', '.bar', function (event) { 2 console.log(event.type); 3});

上記コードを適用するには </body> 直前にコードを書くか、jQuery(function () {}) 内に定義する必要があります。
伝播する数を0にするには .bar 自身にイベント定義しなければなりません。

JavaScript

1jQuery('.bar').on('click', function (event) { 2 console.log(event.type); 3});

この場合、動的に <li class="bar"> が挿入された要素ノードまでは対応できませんので、動的に要素ノードを追加する処理の方でイベント定義する必要があります。

MutationObserver

MutationObserver を使用すれば、動的に要素ノードが挿入されたタイミングでイベント定義する事が可能です。
ただし、要素ノードが追加される度に MutationObserver のチェック処理が走る事になり、全ての要素ノードの挿入処理のパフォーマンスが低下します。
つまり、他の機能でノード挿入処理があった場合、そちらのノード挿入処理のパフォーマンスも低下してしまいます。
他のノード挿入時のパフォーマンス低下を防ぐ為には「.bar を挿入処理となるコード」に「clickイベント定義処理」となるコードを追加する必要があります。

メモリ

イベントを定義した数だけメモリを消費する事になります。
ルートノード(document)にイベント定義すればメモリ消費量はわずかですが、各要素ノード(.bar)にイベント定義すれば、.bar の存在する数だけ比例してメモリ消費量は増えます。
従って、対象の要素数が膨大になる場合はメモリを圧迫してパフォーマンスに影響が出る可能性があります。

jQuery

当然ですが、jQueryの独自処理分もコストがかかります。
素のJavaScriptで書けば、より高いパフォーマンスが得られます。

JavaScript

1document.getElementById('foo').addEventListener('click', function (event) { 2 var li = event.target; 3 4 if (li.classList.contains('bar')) { 5 console.log(event.type); 6 } 7}, false);

パフォーマンス検証

最終的にはバランスです。
適用されるHTML/CSSによってもパフォーマンスが変わってくるので、実際にコードを書いて動かしてパフォーマンスを比較してみるのが一番だと思います。

Re: hoshiimohunda さん

投稿2017/03/01 04:34

think49

総合スコア18162

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hoshiimohunda

2017/03/01 07:13

ご回答をありがとうございます。 よく理解できました。 クリックイベントの対象となる要素の数など次第で 選択すべき方法は変わりそうですね。
guest

0

MutationObserverを使うとDOMの変化を検知できるので,そこで「クリックイベントのイベントハンドラを再登録する」という処理を行うと一番無駄が無いと思います。尤も,このAPIお世辞にも使いやすいとは言えないので,パフォーマンス的に問題がある場合のみピックする,ぐらいでもいいとは思いますが。

MutationObserver - Web API インターフェイス | MDN


【追記】

kapetan/jquery-observe: Observe DOM mutations with jQuery

↑イケてるjQueryプラグインがありました,これ採用しましょう!

投稿2017/03/01 02:10

編集2017/03/01 02:14
mpyw

総合スコア5223

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

質問する前に自分で1万個ぐらいのボタンを設置したテストページを作成して、それぞれのパターンを実行し比較してみればいいと思いますが。
イベントのバブリングについて勉強してください。

投稿2017/03/01 01:40

turbgraphics200

総合スコア4267

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

多少のパフォーマンスの差ができる可能性はありますが
認識できるほど差がでることはないと思います
むしろこの機能を利用しないと実現できないわけですから
利用しない手はありません

追記

前回はjQueryを前提とした回答でしたが、jQueryを使わなくてもできます
documentにaddEventListenerしてください

javascript

1<script> 2document.addEventListener('click',function(e){ 3 var t=e.target; 4 if(t.getAttribute('id')=="hoge"){ 5 console.log(t.textContent); 6 } 7}); 8</script> 9<div id="hoge">fuga</div>

投稿2017/03/01 01:33

編集2017/03/01 03:22
yambejp

総合スコア114769

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問