webentwicklung-frage-antwort-db.com.de

Tut AJAX geladene Inhalte erhalten ein "document.ready"?

Gestern hatte ich ein Problem, bei dem ein .on('click') -Ereignishandler, den ich zugewiesen hatte, nicht richtig funktionierte. Es hat sich herausgestellt, dass ich versucht habe, .on('click') anzuwenden, bevor dieses Element im DOM vorhanden war, weil es über AJAX geladen wurde und daher noch nicht existierte, als document.ready() diesen Punkt erreichte .

Ich löste es mit einer umständlichen Abhilfe, aber meine Frage ist, wenn ich einen in den Ajax geladenen <script>-Tag und einen anderen document.ready() darin einfügen würde, würde der zweite document.ready() nur einmal in diesem Ajax analysiert werden Inhalt ist fertig geladen? Anders ausgedrückt: Ist der separat geladene ajax-Inhalt eine andere document, und wenn ja, funktioniert ein anderes document.ready() in diesem ajax-geladenen HTML-Code so, wie ich es glaube?

Alternative; Was wäre der bessere Weg, um mit dieser Situation umzugehen? (Sie müssen einen Ereignis-Listener mit einem DOM-Element verknüpfen, das noch nicht in document.ready() vorhanden ist.)

36
user2762294

Um Ihre Frage zu beantworten: Nein, document.ready wird nicht erneut ausgelöst, wenn eine Ajax-Anforderung abgeschlossen ist. (Der Inhalt des Ajax wird in Ihr Dokument geladen, daher gibt es kein zweites Dokument für den Ajax-Inhalt.).

Um Ihr Problem zu lösen, fügen Sie einfach den Ereignis-Listener zu dem Element hinzu, in das Sie den Ajax-Inhalt geladen haben . Zum Beispiel:

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

Für #id-of-the-element-in-the-ajax-content können Sie einen beliebigen Selektor verwenden, den Sie in $("selector") verwenden würden. Der einzige Unterschied besteht darin, dass nur Elemente unter div.ajaxcontent-container ausgewählt werden.

Wie es funktioniert: Solange div.ajaxcontent-container vorhanden ist, werden alle Elemente (falls sie jetzt oder nur noch in der Zukunft existieren), die mit dem Selektor #id-of-the-element-in-the-ajax-content übereinstimmen, dieses Klick-Ereignis auslösen.

32
nbar

Javascript in dem resultierenden Ajax-Aufruf wird aus Sicherheitsgründen (standardmäßig) nicht ausgeführt. Sie können das Ereignis auch nicht direkt an nicht vorhandene Elemente binden.
Sie can binden ein Ereignis an einen übergeordneten Elternteil und sagen ihm, dass die untergeordneten Elemente überprüft werden sollen: 

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

Versuchen Sie immer, so nah wie möglich an das auslösende Element heranzukommen, um ein unnötiges Sprudeln durch das DOM zu verhindern


Wenn Sie einige seltsame Funktionen haben, können Sie Folgendes tun:

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

probieren Sie dies aus. Das funktioniert nicht, weil Ihr Steuerelement noch nicht erstellt wurde und Sie versuchen, ein Ereignis anzuhängen. Lassen Sie mich wissen, wenn Sie Probleme haben.

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

Die Antwort hier ist eine delegierte Veranstaltung:

JSFiddle

JSFiddle - Wirklich dynamisch

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

Ich arbeite an einer Code-Basis mit einem Freund, der ähnliche Anforderungen hat. Die delegierte Ereignishandleroption ist auf jeden Fall das Beste, wenn Sie nur Eventhandler anhängen möchten. Eine Alternative, vor allem, wenn Sie andere DOM-Verarbeitung in Ihrer $(document).ready-Funktion durchführen müssen, besteht darin, den Code, den Sie ausführen möchten, in ein Skriptelement am Ende Ihres Codes einzufügen. Grundsätzlich statt:

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

Versuchen Sie, das Skript und den Rest des HTML-Codes zu vertauschen.

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

Dadurch wird der Browser gezwungen, Ihren Code erst zu verarbeiten, wenn er alle anderen DOM-Elemente in das dynamisch geladene HTML geladen hat. Dies bedeutet natürlich, dass Sie sicherstellen müssen, dass der eingefügte HTML-Code keine unbeabsichtigten Auswirkungen auf die Benutzeroberfläche hat, indem Sie CSS/HTML anstelle von JS verwenden. Es ist ein alter Javascript-Trick aus vergangenen Jahren. Als Bonus benötigen Sie dafür nicht mehr jQuery.

Ich sollte erwähnen, dass das Einfügen eines zweiten $(document).ready-Aufrufs in einen <script>-Tag im dynamisch geladenen HTML-Code in Chromium v34 auf das Laden des dynamisch geladenen DOM zu warten scheint. Ich bin nicht sicher, ob dieses Verhalten Standard ist, da es mir große Trauer bereitet hat, als ich versuche, Tests mit dieser Art von Code zu automatisieren.

0
jeteon

JQuery AJAX .load () verfügt über eine integrierte Funktion zur Handhabung dieser . Anstelle von $('div#content').load('such_a_such.url'); sollten Sie eine Callback-Funktion verwenden. JQuery .load () bietet Platz für Folgendes:

$('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.");
    }
 );

Sie müssen das Datenargument jedoch nicht einschließen.

$ ("#result") .load ("ajax/test.html", function () { alert ("Laden wurde durchgeführt."); });

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

0