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

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

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

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

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

Q&A

解決済

2回答

7143閲覧

【JavaScript】デリゲートを理解したい

k499778

総合スコア599

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

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

0グッド

0クリップ

投稿2016/05/31 13:50

現在JavaScriptの実装をしているのですが、
運用上HTML上でonClick属性を設定しているところを、デリゲートさせて各場所で呼び出すようにしなければなりません。

ただデリゲートは初めて聞いた言葉で調べているのですがいまいち理解できていません。

以下のサイトを拝見しました。
http://blog.webcreativepark.net/2013/12/01-215447.html
http://blog.jnito.com/entry/20110706/1309901221

「メソッドを変数のようにして使うもの」や
「先祖要素にクリックイベントハンドラを登録することで、パブリングの防ぎ、負荷を少なくする方法」
というイメージを持ちました。

しかし、実際に「『デリゲートさせて』各場所で呼び出す」というのはどういうところにポイントを置いて書いたらいいのかがわかりません。

先祖要素にクリックイベントハンドラを登録して、実行したい要素を引数に入れるようにすればいいのか、
あるいはカプセル化?変数のようにメソッドを定義した書き方をすればいいのか、など推測を立てているのですが、まだ掴みきれていません。

もしお答えいただける方がいれば教えていただけると助かります。

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

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

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

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

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

guest

回答2

0

ベストアンサー

個人的にはデリゲートの概念は理解しなくても問題ないと考えています。
jQuery#on と DOM Events のイベントバブリングだけを理解すれば十分に事足ります。

HTML

1<div id="parent"> 2 parent 3 <p id="child">child</p> 4</div> 5 6<script type="text/javascript"> 7'use stirct'; 8jQuery('#parent').on('click', '#child', function (event) { 9 console.log('jQuery: ' + this.id); // "jQuery: child" 10 console.log('jQuery: ' + event.currentTarget.id); // "jQuery: child" 11}); 12 13document.getElementById('parent').addEventListener('click', function handleClick (event) { 14 var target = event.target, 15 id = target.id; 16 17 while (id !== 'parent' && id !== 'child') { 18 target = target.parentNode; 19 id = target.id 20 } 21 22 if (id !== 'child') { 23 return; 24 } 25 26 console.log('DOM: ' + target.id); // "DOM: child" 27 console.log('DOM: ' + this.id); // "DOM: parent" 28 console.log('DOM: ' + event.currentTarget.id); // "DOM: parent" 29}, false); 30</script>
  • イベント定義しているのは #parent なので #child は動的に削除→生成し直してもイベントを再定義する必要はありません
  • イベント定義しているのは #parent ですが、イベントハンドラ関数内では #child にイベント定義しているかのように振る舞います(this 値や event.currentTarget を書き換えます)

ちなみに、jQuery#on(events, handler) はイベントバブリングを利用している為、バブリングしないイベントタイプには適用できません。
jQuery はキャプチャリングフェーズに対応していない為、上位ノードで監視可能なイベントタイプに制限があります。

Re: k499778 さん

投稿2016/05/31 14:51

編集2016/05/31 14:56
think49

総合スコア18156

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

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

k499778

2016/05/31 15:11

回答有り難うございます。 >イベント定義しているのは #parent なので #child は動的に削除→生成し直してもイベントを再定義する必要はありません なるほど。よくイベントを再定義しているのでこの書き方を使えばそれを減らせるかもしれませんね。 イベントバブリングだけを理解すればいいんですね。 ちなみに少し迷うのが「先祖素をどこまで見ればいいか」ということです。 liタグをクリックした時ulタグを超えて、bodyタグとかhtmlタグとかもパブリングしないかなと思い、そこにイベントを設定する必要はないのか、などどの先祖要素にイベントハンドラを設定すればいいのかわからなくなってしまうのです。 もしその疑問を解決する考え方があるのであれば教えていただきたいです。
think49

2016/05/31 15:41

バブリングは常にルートノードまで伝播します。 ルートノードとは古くは document ですが、現在は window ですね。
k499778

2016/06/01 00:08 編集

返答ありがとうございます。 となると >jQuery('#parent').on('click', '#child', function (event) { の「jQuery('#parent')」の部分は ルートノードにする必要はないのかな? という疑問を持ちました。 ご提示下さったコードは先祖要素がparentに当たるためいいと思うのですが、普段コーディングの際はルートノードがdocumentに当たるため、セレクタ部分をどうすればいいのか迷ってしまうのです。 もしその疑問を解決いただけるようであればお答えいただけると嬉しいです。
think49

2016/06/01 02:07 編集

ルートノード(document)でも構いませんが、そうすると常にコード記入順で発火するので順序制御が面倒になると思います。 jQuery(document.body).on('click', '#parent', handleClick); // 2番目 jQuery('#paremt').on('click', '#child', handleClick); // 1番目 ↓ jQuery(document).on('click', '#parent', handleClick); // 1番目 jQuery(document).on('click', '#child', handleClick); // 2番目 バブリングは子要素から親要素へ順番に発火する為、「#child -> #parent -> document.body -> document.documentElement -> document -> window」の順に発火するわけですが、常に document を指定すると入力順で発火します。 http://www2u.biglobe.ne.jp/~oz-07ams/2003/Events3/xml-source-20031107-ja.xml#Events-flow ちなみに、document を指定すると DOMContentLoaded を待たなくていい利点はあります。
k499778

2016/06/01 03:16

返答ありがとうございます。 documentにしてもいいが、順序制御が面倒になるのですね。ただメリットもあるが。 スッキリしました。 わからないところは自分で調べて理解を深めます。 長らく相談に乗って頂きありがとうございました。
guest

0

delegateは「委譲」という意味で使われています。

「html上、もしくはイベントハンドラ上に処理を書かず、一定のオブジェクトに集約せよ」という指示ではないでしょうか?

例えば、

html

1<button onclick="javascript:alert('委譲を全く使わないパターン');">Click me</button>

となっているところを

html

1<button class="awesome-button">Click me</button>

javascript

1$(function(){ 2 $('.awesome-button').click(function(){ 3 alert('clicked!'); 4 }); 5});

と書くことができます。HTML上にjavascriptコードを書かず、javascriptの処理はすべてjs内に書かれているので委譲を使わない場合よりも保守性があがります。
さらに、alert('clicked!')という処理を使いまわしたいならば

html

1<button class="awesome-button">Click me</button> 2<button class="newly-added-button">Click me</button>

javascript

1$(function(){ 2 $('.awesome-button').click(function(){ 3 AlertUtil.doAlert('clicked!'); 4 }); 5 $('.newly-added-button').click(function(){ 6 AlertUtil.doAlert('This is New Button!'); 7 }); 8}); 9 10var AlertUtil={ 11 doAlert:function(msg){ 12 alert(msg); 13 } 14}

と掛けます。この場合、処理を行うのはAlertUtilであり、HTMLとイベント部分の処理は必要な引数だけを渡して処理をAlertUtilに委譲しています。
適切に委譲を使うことで、コードの保守性と再利用性を高めることができます。

投稿2016/05/31 14:05

yohira0616

総合スコア255

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

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

k499778

2016/05/31 14:13

回答有り難うございます。 呼び出し方はまさにその通りで一つのオブジェクトにまとめたものを呼び出して使うといった形でした。 確かにコードの保守性と再利用性が上がりますね。 わかりやすい説明のおかげです。ありがとうございます。 「保守性、再利用性をあげるために一定のオブジェクトに集約する」と覚えておきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問