現在jqueryで$('a').on('click',function(){})
といったリンククリックで発火する処理を書いているのですが、html()
を使ってdomを更新したところ、新しく追加された要素で発火しません。どのような原因が考えられるでしょうか?
個人的考察:
処理を$(document).ready(function(){}
内に書いていることが関係しているのではないか
試したこと:
$(document).ready(function(){}
の外に処理を書く
結果:
追加要素以外も発火しなくなってしまった。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/05/17 13:25

退会済みユーザー
2019/05/18 00:31

退会済みユーザー
2019/05/18 00:32

退会済みユーザー
2019/05/18 00:41

退会済みユーザー
2019/05/18 00:43

退会済みユーザー
2019/05/18 00:52 編集

退会済みユーザー
2019/05/18 00:52 編集

退会済みユーザー
2019/05/18 00:45

退会済みユーザー
2019/05/18 00:47

回答3件
4
これはJavaScriptの最も根底にある概念の問題です。
HTMLファイルの中に<script>
タグがある場合、
ブラウザはレンダリングを一時停止してJavaScriptのコードを読み取り実行します。
そしてJavaScriptを「全て実行し終えたら」引き続きHTMLファイルを読み取って画面の構築作業に戻ります。
この前提が非常に重要なんです。
$(document).ready(function(){}
の外に処理を書く
これはhead要素の箇所にscriptタグを設置したと推測されます。
ブラウザはscriptタグを発見するとレンダリングを停止して実行し始めるんでしたよね?
引っ掛けたいa
タグはその場面では作られていません。
なので追加要素以外も発火しなくなってしまいました。
$(document).ready(function(){}
の意味って何?
JavaScriptはscriptタグと同時に全部実行してしまっておしまいと説明しましたね。
は?クリックイベントとかスクロールイベントとかどうすんねん?
それを実現する為に、イベント駆動という概念で解決します。
ブラウザはイベント置き場というものが用意されており、
「達成条件」と「実行してほしい関数」をセットで登録することができます。
例えば$(document).ready(function(){}
のように書いたとしましょう。
これは「達成条件がブラウザのDOMツリー完成」であり、function(){}
の部分が実行してほしい関数になっています。
なのでheadタグ内に作ったscriptであっても、
aタグが作られるまで実行を待ってから実行してくれてるわけですね。賢い!!
jqueryのon()が追加要素で発火しない
$('a').on('click',function(){})
これでようやく本題に帰ってこれます。
この追加されたaタグでコードが発火しないというのは
この行の実行中に見つけたaタグに対して、
クリックされたらこの関数を実行せよ…というイベント登録だからです。
その場に存在しなかったaタグにイベント登録は出来ません。
えー?困る!!
困りますね。解決方法は以下の2通りです。
- 作る度に指定する
- イベントのバブリングを利用する
1個ずつ見ていきましょう。
作る度に指定する
これはそのまんまです。
関数をどっか変数として保存しておき、aタグが作られるタイミングでそのaタグにイベントを設置し直すルールで運用しましょう。
コードにするとこんな感じになるでしょう。
JavaScript
1$(document).ready(function(){ 2 var clickFn = function(){}; 3 $('a').on('click', clickFn); 4 5 // 新しくHTMLを差し込むと同時にaタグにイベントを挿入 6 $('.content') 7 .html('HTML文章') 8 .find('a').on('click', clickFn); 9});
イベントのバブリングを利用する
aタグが消えるなら、消えないタグでクリックを見張れば良いじゃんという解決方法です。
イベントのバブリングとはなんぞや???
もし分からなければこれを見てください
HTML
1<body> 2 <section> 3 <form> 4 <button></button> 5 </form> 6 </section> 7</body>
ボタンがありますね。
あなたはマウスでこのボタンをクリックしました。
さて問題、あなたはマウスで何をクリックしましたか?
は?ボタンクリックしたから当然ボタンだけに決まってるやろ???
実はこれ不正解なのです。
buttonをクリックすると、その親であるformもsectionもbodyも全部クリックしたことになっています。
シートを重ねて、一番頂点の部分を押しているから下にあるシートも全部含まれるでしょというイメージです。
これをイベントのバブリングと呼びます。
深い階層で実行されたイベントは、上の要素の伝播していきます。
なので、浅い階層でクリックイベントを待ちます。
jQueryにはこのイベントのバブリングを利用した解決方法が存在します。
公式リファレンスを閲覧すると…ありました。
.on( events [, selector ] [, data ], handler )
イベントというのは'click'
という文字列ですね。
function(){}
は実行して欲しい関数。
この[]
はプログラミングのお作法で省略可能を示していますが、
このselector
が怪しいですね。
実はこのselector
を指定すると、要素の子孫でセレクタを探し、合致したときに実行するという意味になります。
これは前述のイベントのバブリングを利用して伝播してきた起点を判別して捕まえるという作戦です。
JavaScript
1$(document).ready(function(){ 2 // 例えばcontent内だけを書き換えるぜ!みたいな仕組みにしておいて 3 $('.content').on('click', 'a', function(){}); 4 5 $('.content').html('新しいHTML構造'); 6});
このように記述すれば新しくつくられたaタグでも動作するでしょう。
投稿2019/05/18 04:39
総合スコア21395
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

退会済みユーザー
2019/05/18 09:00

退会済みユーザー
2019/05/19 02:44

退会済みユーザー
2019/05/19 03:08

退会済みユーザー
2019/05/19 03:38
2019/05/19 03:45

退会済みユーザー
2019/05/19 03:51

退会済みユーザー
2019/05/19 03:54

退会済みユーザー
2019/05/19 03:56

退会済みユーザー
2019/05/19 03:57

退会済みユーザー
2019/05/19 04:00

退会済みユーザー
2019/05/19 04:02

退会済みユーザー
2019/05/19 04:37

退会済みユーザー
2019/05/19 04:41

退会済みユーザー
2019/05/19 04:43

退会済みユーザー
2019/05/19 04:52

退会済みユーザー
2019/05/19 04:53
2019/05/19 05:54

退会済みユーザー
2019/05/19 05:58

退会済みユーザー
2019/05/19 06:00 編集

退会済みユーザー
2019/05/19 06:01

退会済みユーザー
2019/05/19 06:03

退会済みユーザー
2019/05/19 06:04

退会済みユーザー
2019/05/19 06:05

退会済みユーザー
2019/05/19 06:33

退会済みユーザー
2019/05/19 06:37

3
ベストアンサー
うーんとyasutomiしゃんが偉そうな事言ってるのに全然回答できないみたいなので、
ぽっくんがお答えちまちゅね。
$('a').on('click',function(){})
は、このコードが実行された時に存在しゅる全ての<a/>タグに対して、「clickイベントが発生ちた時に実行ちゅるハンドラfunction(){}を登録ちている」でちゅ。
だから、後から追加された<a/>には登録されないのでちゅ。
しょれを解決しゅるには、
$(document).on("click", "a", function(){});
のように、ドキュメント自体に対してclickイベントに対するハンドラを登録するのでちゅ。
見てわかるように、on()メソッドの引数の数がかわっていまちゅね?
こういった関数のオーバーロードはjQueryでは頻繁に用いられているまちゅので
注意ちて見てみると良いと思いまちゅ。
投稿2019/05/18 00:39

退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/05/19 04:43

退会済みユーザー
2019/05/19 04:46
2019/05/19 04:56
2019/05/19 05:00
2019/05/19 05:20 編集

退会済みユーザー
2019/05/19 05:24
2019/05/19 05:37 編集

退会済みユーザー
2019/05/19 05:41

退会済みユーザー
2019/05/19 05:43
2019/05/19 05:49 編集

退会済みユーザー
2019/05/19 05:49 編集

退会済みユーザー
2019/05/19 05:52
2019/05/19 05:53
2019/05/19 05:57

退会済みユーザー
2019/05/19 06:07
2019/05/19 06:18 編集

退会済みユーザー
2019/05/19 06:15

退会済みユーザー
2019/05/19 06:15

退会済みユーザー
2019/05/19 06:17
2019/05/19 06:26
2019/05/19 06:38

退会済みユーザー
2019/05/19 06:41

退会済みユーザー
2019/05/19 06:42

退会済みユーザー
2019/05/19 06:42

退会済みユーザー
2019/05/19 06:46
2019/05/19 06:57

退会済みユーザー
2019/05/19 06:59

退会済みユーザー
2019/05/19 11:26 編集
2019/05/19 07:05
2019/05/19 07:16
2019/05/19 07:28
2019/05/19 08:06
2019/05/19 08:07
2019/05/19 08:10
2019/05/19 08:14
2019/05/19 08:20
2019/05/19 08:29 編集
2019/05/19 08:36
2019/05/19 08:38
2019/05/19 08:46
2019/05/19 08:56 編集
2019/05/19 09:21

退会済みユーザー
2019/05/19 10:55 編集

退会済みユーザー
2019/05/19 10:57 編集

退会済みユーザー
2019/05/19 10:57

退会済みユーザー
2019/05/19 10:58

退会済みユーザー
2019/05/19 12:14 編集

退会済みユーザー
2019/05/19 12:00

退会済みユーザー
2019/05/19 12:01

退会済みユーザー
2019/05/19 12:02 編集

退会済みユーザー
2019/05/19 12:03

退会済みユーザー
2019/05/19 12:04

退会済みユーザー
2019/05/19 12:09 編集

退会済みユーザー
2019/05/19 12:07
2019/05/20 13:47

1
おそらく探そうにもキーワードが思い浮かばないのだろうと感じたのでそこだけのヒント回答です。
「jQuery 動的要素 イベント」で検索
→これで出てくるサイトで充分解決します(例:動的に生成したDOM要素に対してjQueryでイベントを設定する場合)
※やっていることは別回答と同じです
低評価されている方はその理由もコメントください。
私も同じ問題にあたったことがあり、提示したキーワードで検索し、解決しました。
それを共有することも「回答」としてはありだと思うのですが如何でしょうか。
「解決しない」と判断されたのでしたらそこはご指摘いただければ回答調整します。
なお、「やっていることは別回答と同じ」と補足した通り、既に出ている回答の焼き直しになるのでなるべくそれは避けたいところではありますね。
この質問についた回答の中で私の回答が一番早く投稿された回答であることを加味しても、
「後発と同じ回答」は意味が分からなくなるので。
本質問の要件がjQueryであることから、私が提示したキーワードとそれで出てくる記事以外の実現方法って結構イレギュラー(ポピュラーではない)なやり方になると思います(私はポピュラーなやり方のみしか知らないですが)
投稿2019/05/17 11:26
編集2019/05/21 00:43総合スコア80888
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。