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

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

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

Delegatesとは、オブジェクト指向型プログラミングにおいて、あるオブジェクトの操作を一部の他のオブジェクトに代替させる手法のこと。オブジェクトは他のデリゲートに頼って関数を実行することができます。

イベントハンドラ

マウスのクリックなどの特定の事象(イベント)が発生した時に実行される処理のことをイベントハンドラと呼びます。

JavaScript

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

jQuery

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

Q&A

解決済

3回答

6382閲覧

ネイティブのJSでデリゲートイベントを実装して子要素の情報を取得したいです

kde

総合スコア29

Delegates

Delegatesとは、オブジェクト指向型プログラミングにおいて、あるオブジェクトの操作を一部の他のオブジェクトに代替させる手法のこと。オブジェクトは他のデリゲートに頼って関数を実行することができます。

イベントハンドラ

マウスのクリックなどの特定の事象(イベント)が発生した時に実行される処理のことをイベントハンドラと呼びます。

JavaScript

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

jQuery

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

0グッド

1クリップ

投稿2017/06/07 05:45

編集2017/06/07 07:35

###前提・実現したいこと
現在、jQueryで書かれたコードをネイティブのJSに変換をしています。
その中でonイベントを使ってデリゲート処理を行っている箇所があり、
ネイティブのJSでどのように書いて再現すればよいのかわからず質問させていただきました。

実現したいことは下記です。

  • 下記の#wrapを起点にイベントを監視(.itemは動的に増える可能性があるため)
  • #wrapの子要素をクリックすると、その.itemを起点にして任意の子要素の情報を取得。

(item1テキストをクリックしたら、spanタグのid(この場合id1)、aタグのhref属性値(この場合1.html)を取得。

  • 取得した情報をajaxで送信(これは別件なので本質問の対象外です)

jqueryで書かれているのは下記です。

$("#wrap").on('click','.item',function(event) { event.preventDefault(); event.stopPropagation(); // idを取得 var id = $(this).find(".child").attr("id"); // hrefを取得 var href = $(this).find("a").attr("href"); console.log(id, href); });

###発生している問題
#wrapをクリックするとイベントターゲットがa要素まで行ってしまい、.itemを起点にすることできません。
どうやればシンプルに実装できるでしょうか。

###該当のソースコード

html

1<div id="wrap"> 2 <div class="item"> 3 <span class="child" id="id1"><a href="1.html">item1</a></span> 4 </div> 5 <div class="item"> 6 <span class="child" id="id2"><a href="2.html">item2</a></span> 7 </div> 8 <div class="item"> 9 <span class="child" id="id3"> <a href="3.html">item3</a></span> 10 </div> 11 <div class="item"> 12 <span class="child" id="id4"><a href="4.html">item4</a></span> 13 </div> 14 <div class="item"> 15 <span class="child" id="id5"><a href="5.html">item5</a></span> 16 </div> 17</div> 18 19<button id="btn">add</button>

javascript

1const wrap = document.getElementById('wrap'); 2 3wrap.addEventListener('click', function(e) { 4 e.preventDefault(); 5 console.log(e.target); // -> <a href="1.html">item1</a> 6 /* 7 ここをなんとかしたい 8 */ 9}, false); 10 11 12// addボタンのイベント登録 13const btn = document.getElementById('btn'); 14let num = 6; 15btn.addEventListener('click', function() { 16 const item = document.createElement('div'); 17 item.innerHTML = `<span class="child" id="id${num}"><a href="${num}.html">item${num}</a></span>`; 18 item.classList.add('item'); 19 num++; 20 wrap.appendChild(item); 21});

お力添えいただけると幸いです。何卒よろしくお願いいたします。

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

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

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

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

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

guest

回答3

0

ベストアンサー

event.target.id === 'wrap' の時だけ処理をスキップさせて下さい。

HTML

1<div id="wrap"> 2 <div class="item"> 3 <span class="child" id="id1"><a href="1.html">item1</a></span> 4 </div> 5 <div class="item"> 6 <span class="child" id="id2"><a href="2.html">item2</a></span> 7 </div> 8 <div class="item"> 9 <span class="child" id="id3"><a href="3.html">item3</a></span> 10 </div> 11 <div class="item"> 12 <span class="child" id="id4"><a href="4.html">item4</a></span> 13 </div> 14 <div class="item"> 15 <span class="child" id="id5"><a href="5.html">item5</a></span> 16 </div> 17</div> 18 19<button id="btn">add</button> 20 21<script> 22'use strict'; 23document.getElementById('wrap').addEventListener('click', function handleClick (event) { 24 var item = event.target, currentTarget = event.currentTarget; 25 26 if (item === currentTarget) { 27 return; 28 } 29 30 while (item && !item.classList.contains('item')) { 31 item = item.parentNode 32 } 33 34 var child = item.firstElementChild, 35 id = child.id, 36 href = child.firstChild.href; // 絶対URIがNGなら getAttribute() 37 38 console.log(id, href); 39 event.preventDefault(); 40}, false); 41</script>

Re: kde さん

投稿2017/06/07 06:27

編集2017/06/07 06:37
think49

総合スコア18189

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

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

kde

2017/06/07 07:41

早々にありがとうございます! event.currentTargetの存在、whileでの祖先要素への移動、これらを知ることができ大変勉強になりました。このコードであればitem内に要素が増えても自分が理想とする形での情報取得が行えると感じました。 本当にありがとうございます。
guest

0

closest()があります。IE が必要なら Polyfill もどうぞ。
https://developer.mozilla.org/ja/docs/Web/API/Element/closest

JavaScript

1e.target.closest('.item'); // Element or null.

投稿2017/06/07 05:57

x_x

総合スコア13749

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

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

kde

2017/06/07 07:59

早々にありがとうございます!closest()メソッドの存在知りませんでした。非常に便利そうなのでじっくり見させていただきます。
guest

0

掴んでからどうしたいのかによりますが、こんな感じでどうでしょうか?

javascript

1window.onload=function(){ 2 n2a(document.querySelectorAll('#wrap .item')).forEach(function(i){ 3 i.addEventListener('click',function(e){ 4 var t=e.target; 5 console.log(t); 6 e.preventDefault(); 7 }); 8 }); 9} 10function n2a(node){ 11 if(!NodeList.prototype.forEach){ 12 node = Array.prototype.slice.call(node,0); 13 } 14 return node; 15}

投稿2017/06/07 06:13

yambejp

総合スコア116468

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

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

namimon

2017/06/07 07:48

querySelectorAllは死んだnodeなので、追加した要素には効かないのではないでしょうか
kde

2017/06/07 07:49

早々にありがとうございます!少ないコードで実装でき素晴らしいと思いました! addボタンをクリックして動的に.itemを生成して増やしたときに再度イベントを定義する必要がありそうでしたが、大変参考になりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問