Il contenuto caricato AJAX ottiene un “document.ready”?

Ieri ho avuto un problema in cui un gestore di eventi .on('click') che stavo assegnando non funzionava correttamente. È venuto fuori perché stavo cercando di applicare quel .on('click') prima che quell’elemento esistesse nel DOM, perché veniva caricato tramite AJAX, e quindi non esisteva ancora quando il document.ready() arrivava quel punto.

L’ho risolto con una soluzione imbarazzante, ma la mia domanda è, se dovessi inserire un tag nel contenuto caricato ajax e in un altro document.ready() interno, il secondo document.ready() verrà analizzato SOLO una volta che il contenuto di ajax è stato caricato? In altre parole, considera che il contenuto ajax caricato separatamente sia un altro document e, in tal caso, avere un altro document.ready() all’interno di quel codice HTML caricato ajax funziona nel modo in cui penso che lo faccia?

In alternativa; quale sarebbe un modo migliore per gestire questa situazione? (è necessario colbind un listener di eventi a un elemento DOM che non esiste ancora su document.ready() )

Per rispondere alla tua domanda: No, document.ready non verrà triggersto nuovamente una volta completata una richiesta Ajax. (Il contenuto dell’ajax viene caricato nel tuo documento, quindi non c’è un secondo documento per il contenuto di ajax).

Per risolvere il problema basta aggiungere il listener di eventi all’elemento in cui si carica il contenuto dell’ajax. Per esempio:

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

Per il contenuto di #id-of-the-element-in-the-ajax-content puoi usare qualsiasi selettore che useresti in $("selector") . L’unica differenza è che saranno selezionati solo gli elementi sotto div.ajaxcontent-container .

Come funziona: fintanto che div.ajaxcontent-container esiste tutti gli elementi (se esistono ora o solo in futuro) che corrispondono al selettore #id-of-the-element-in-the-ajax-content attiverà questo clic -evento.

Javascript nella chiamata ajax risultante non verrà scartato (di default) a causa della sicurezza. Inoltre, non è ansible associare direttamente l’evento a elementi non esistenti.
Puoi associare un evento a un genitore esistente e dirgli di controllarlo:

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

Cerca sempre di avvicinarti il ​​più ansible all’elemento di innesco, in questo modo si eviterà che bolle spettrali attraverso il DOM


Se hai alcune funzioni strane in corso, potresti fare qualcosa del genere:

 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(); }); 

prova questo, non funziona perché il tuo controllo non è ancora stato creato e stai provando ad albind un evento, se usi su evento funzionerà correttamente. fammi sapere se incontri problemi.

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

La risposta qui è un evento delegato:

JSFiddle

JSFiddle – Davvero dinamico

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

HTML

 

Sto lavorando su un codice base con un amico che ha requisiti simili. L’opzione del gestore di eventi delegato è sicuramente la migliore se tutto ciò che si desidera è associare i gestori di eventi. Un’alternativa, specialmente se devi eseguire un’altra elaborazione DOM nella tua funzione $(document).ready , è mettere il codice che vuoi eseguire in un elemento di script alla fine del tuo codice. Fondamentalmente, invece di:

   

Prova a scambiare lo script e il resto dell’HTML in modo da avere:

   

Ciò impone al browser di elaborare il codice solo dopo aver caricato tutti gli altri elementi DOM nel codice HTML caricato in modo dinamico. Ovviamente questo significa che dovrai assicurarti che l’HTML inserito non abbia conseguenze non volute dell’interfaccia utente usando CSS / HTML invece di JS. È un vecchio trucco Javascript degli anni passati. Come bonus, non hai più bisogno di jQuery per questo.

Dovrei menzionare che in Chromium v34, inserire una seconda $(document).ready all’interno di un tag nel codice HTML caricato in modo dinamico sembra attendere il caricamento dinamico del DOM e quindi eseguire la funzione come descritto. Non sono sicuro che questo comportamento sia standard anche se mi ha causato un grande dolore quando ho tentato di automatizzare i test con questo tipo di codice.

JQuery AJAX .load () ha una funzione integrata per la gestione di questo. Invece di semplicemente $('div#content').load('such_a_such.url'); dovresti includere una funzione di callback. JQuery .load () offre spazio per quanto segue:

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

Tuttavia, non è necessario includere l’argomento dati.

$ (“#result”) .load (“ajax / test.html”, function () {alert (“Caricamento eseguito”.);});

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