web-dev-qa-db-ja.com

AJAXロードされたコンテンツは「document.ready」を取得しますか?

昨日、割り当てていた.on('click')イベントハンドラが正常に機能しないという問題がありました。それは、AJAXを介してロードされていたため、.on('click')がまだ存在していなかったため、その要素がDOMに存在する前にdocument.ready()を適用しようとしていたためですそのポイントに到達しました。

私は厄介な回避策でそれを解決しましたが、私の質問は、<script>_タグをajaxにロードされたコンテンツに入れ、その中に別のdocument.ready()を置くと、その2番目のdocument.ready() ajaxコンテンツが読み込まれた後にのみ解析されますか?つまり、個別にロードされたajaxコンテンツは別のdocumentであると見なされ、もしそうであれば、そのajaxでロードされたHTML内に別のdocument.ready()があると思いますか?

または、この状況を処理するより良い方法は何でしょうか? (document.ready()にまだ存在しないDOM要素にイベントリスナーをアタッチする必要があります)

36
user2762294

あなたの質問に答えるには:いいえ、document.readyはajaxリクエストが完了すると二度と起動しません。 (ajaxのコンテンツはドキュメントにロードされるため、ajaxコンテンツ用の2番目のドキュメントはありません)。

問題を解決するには、ajaxコンテンツをロードするElementにイベントリスナーを追加するだけです。例えば:

_$( "div.ajaxcontent-container" ).on( "click", "#id-of-the-element-in-the-ajax-content", function() {
  console.log($( this ));
});
_

_#id-of-the-element-in-the-ajax-content_には、$("selector")で使用する任意のセレクターを使用できます。唯一の違いは、_div.ajaxcontent-container_の下の要素のみが選択されることです。

仕組み: _div.ajaxcontent-container_が存在する限り、セレクター_#id-of-the-element-in-the-ajax-content_に一致するすべての要素(現在または将来のみ存在する場合)は、このクリックイベントをトリガーします。

32
nbar

結果として生じるajax呼び出しのJavascriptは、安全のために(デフォルトで)実行されません。また、存在しない要素にイベントを直接バインドすることはできません。
あなたcan存在する親にイベントをバインドし、その子をチェックするように伝えます:

$(document).ready(function(){
    $(document).on('eventName', '#nonExistingElement', function(){ alert(1); }
    // or:
    $('#existingParent').on('eventName', '#nonExistingElement', function(){ alert(1); }
});

可能な限りトリガー要素にできるだけ近づけるようにしてください。これにより、DOMを介した不必要なバブリングが防止されます。


奇妙な機能を実行している場合、次のようなことができます。

function bindAllDocReadyThings(){
    $('#nonExistingElement').off().on('eventName', function(){ alert(1); }
    // Note the .off() this time, it removes all other events to set them again
}
$(document).ready(function(){
    bindAllDocReadyThings();
});
$.ajaxComplete(function(){
    bindAllDocReadyThings();
});
10
Martijn

これを試してください。コントロールがまだ作成されておらず、イベントを添付しようとしているため機能しません。イベントで使用する場合は正常に機能します。問題が発生した場合はお知らせください。

$(document).ready(function(){
    $(document).on('click', '#element', function (evt) {
        alert($(this).val());
    });
});

ここでの答えは、委任されたイベントです。

JSFiddle

JSFiddle-本当に動的

jQuery

$(document).ready(function(){
    // Listen for a button within .container to get clicked because .container is not dynamic
    $('.container').on('click', 'input[type="button"]', function(){
        alert($(this).val());
    });

    // we bound the click listener to .container child elements so any buttons inside of it get noticed
    $('.container').append('<input type="button" class="dynamically_added" value="button2">');
    $('.container').append('<input type="button" class="dynamically_added" value="button3">');
    $('.container').append('<input type="button" class="dynamically_added" value="button4">');
    $('.container').append('<input type="button" class="dynamically_added" value="button5">');
});

[〜#〜] html [〜#〜]

<div class="container">
    <input type="button" class="dynamically_added" value="button1">
</div>
2
MonkeyZeus

私は、同様の要件を持つ友人とコードベースに取り組んでいます。委任されたイベントハンドラーオプションは、イベントハンドラーをアタッチするだけの場合に最適です。別の方法、特に$(document).ready関数で他のDOM処理を行う必要がある場合は、実行するコードをコードの最後にあるスクリプト要素に配置します。基本的に、次の代わりに:

_<script type="text/javascript">
  $(document).ready(function() {
    // Your code here
  });
</script>
<!-- rest of dynamically loaded HTML -->
_

スクリプトと残りのHTMLを入れ替えてみてください:

_<!-- rest of dynamically loaded HTML -->
<script type="text/javascript">
  // Your code here
</script>
_

これにより、動的にロードされたHTML内の他のすべてのDOM要素がロードされると、ブラウザーはコードを強制的に処理します。もちろん、これは、JSの代わりにCSS/HTMLを使用して、挿入されたHTMLに意図しないUIの影響がないことを確認する必要があることを意味します。その昔のJavascriptトリックです。おまけとして、これのためにjQueryはもう必要ありません。

Chromium v​​34では、動的に読み込まれたHTMLの_<script>_タグ内に2番目の$(document).ready呼び出しを置くと、動的に読み込まれたDOMが読み込まれ、説明したように関数が実行されるようです。この種のコードを使用してテストを自動化しようとすると大きな悲嘆を引き起こしたため、この動作が標準であるかどうかはわかりません。

0
jeteon

JQuery AJAX .load()にはこれを処理するための組み込み機能があります。単純に$('div#content').load('such_a_such.url');の代わりにコールバック関数を含める必要があります。JQuery.load()は以下:

$('div#content').load('such_a_such.url',
    { data1: "First Data Parameter",
      data2: 2,
      data3: "etc" },
    function(){ $('#span1').text("This function is the equivalent of");
                $('#span2').text("the $(document).ready function.");
    }
 );

ただし、データ引数を含める必要はありません。

$( "#result").load( "ajax/test.html"、function(){alert( "ロードが実行されました。");});

http://api.jquery.com/load/

0