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

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

ただいまの
回答率

88.77%

動的に追加された要素にイベントを指定した際の挙動について

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 191

HiromuNakajima

score 10

jQueryの仕様について質問です。

下記サイトの「なぜ上級者向けのイベント構文を覚えないといけないのか?」の項目で、
以下の通りの説明がありました。

jQuery入門 設計力を学ぶデザインドリル|イベント(1)

なぜ上級者向けのイベント構文を覚えないといけないのか?
初心者向けのイベント構文は、動的な要素(プログラムで後から追加された要素)に対応していません。
そのため、インタラクティブなコンテンツでは対応できない場合があるのです。 
このサンプルではイベントの処理はdiv要素をクリックしても「click!」と表示されません。

実際に動作テストも行いましたが、確かに.appendToイベントで追加されたdiv要素をクリックしても、
「click!」と表示されず、.textイベントが動作していないことを確認しました。

しかしながら、HTMLのbody内に最初からdiv要素が存在していた場合、
最初から存在してdiv要素をクリックする事で、.appendToイベントで追加されたdivに対しても、.textイベントが動作します。

仕様上の問題だと思いますが、ちょっとここの仕様が思うように呑み込めず、
ググっても詳細について明確な回答が拾えなかったので、
誰か詳しい方の解説をいただきたく質問しました。

▼初心者向けのイベント構文

$("div").click(function (){
        $("div").text("click!");
    });
    $("<div>").appendTo("body");
<!DOCTYPE html>
<html lang="jp" dir="ltr">

<head>
  <meta charset="utf-8">
  <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
  <link rel="stylesheet" href="test.css">
  <script src="test.js" charset="utf-8"></script>
  <title></title>
</head>

<body>

</body>

</html>



bodyに既存のdivがない場合

bodyに既存のdivがある場合

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+3

仕様上の問題だと思いますが、ちょっとここの仕様が思うように呑み込めず、
ググっても詳細について明確な回答が拾えなかったので、
誰か詳しい方の解説をいただきたく質問しました。

$('div')は、それを実行した時点で存在する<div>要素を拾います。

外側でイベントをセットするときに使った$('div')は、ページロード時点で存在したものだけになりますし、クリックイベントの中の$('div')は、クリックした時点で存在するものを拾います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/10/25 15:43

    回答ありがとうございます!
    とても分かりやすい回答でした。

    イベントセット時の$("div")はページロード時点で存在したものだけを拾うのはわかっていたのですが、
    イベントセット時の$("div")で拾ったdiv要素を、クリックイベント内の$("div")に、
    そのまま使いまわしているものと変な勘違いをしておりました・・・。

    変な認識を早めに払拭できて助かりました。
    基本的なオブジェクト構造を少し理解できたように感じます。
    本当にありがとうございました。

    キャンセル

+1

どこで引っかかっているかわかりませんが
特定のセレクタに機能をつけてもあとから追加したら反映されないのは理解できませんか?

対策はonで上位のタグから参照するだけです

  • ダメな例
    div2は反応しない
<script>
$(function(){
  $('div').on('click',function (){
    $(this).text("click!");
  });
  $('<div>div2</div>').appendTo('body');
});
</script>
<div>div1</div>
  • 正しい処理
    div2も反応する
<script>
$(function(){
  $('body').on('click','div',function (){
    $(this).text("click!");
  });
  $('<div>div2</div>').appendTo('body');
});
</script>
<div>div1</div>

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/10/25 16:17

    回答ありがとうございます!

    質問時は、イベントセット時の$("div")で拾ったdiv要素をクリックイベント内の$("div")に、
    そのまま使いまわしているものと変な勘違いをしておりました・・・。

    キャンセル

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

  • ただいまの回答率 88.77%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る