2010-06-15 3 views
0

J'utilise ajax pour insérer une série de blocs d'information via une boucle. Les blocs ont chacun un titre et une longue description qui est cachée par défaut. Ils fonctionnent comme un accordéon, montrant seulement une description à la fois parmi tous les blocs.manipuler le contenu inséré par ajax, sans utiliser le rappel

Le problème est l'ouverture de la description sur le premier bloc. Je voudrais vraiment le faire avec javascript juste après la boucle qui les crée est fait. Est-il possible de manipuler éléments créés à partir d'un appel ajax sans utiliser le rappel?

<!-- example code--> 
<style> 
    .placeholder, .long_description{ 
    display:none;} 
</style> 
</head><body> 
<script> /* yes, this script is in the body, dont know if it matters */ 
$(document).ready(function() { 
    $(".placeholder").each(function(){ // Use the divs to get the blocks 
     var blockname = $(this).html(); // the contents if the div is the ID for the ajax POST 
     $.post("/service_app/dyn_block",'form='+blockname, function(data){ 
      var divname = '#div_' + blockname; 
      $(divname).after(data); 
      $(this).setupAccrdFnctly(); //not the actual code 
     }); 
    }); 

    /* THIS LINE IS THE PROBLEM LINE, is it possible to reference the code ajax inserted */ 
    /* Display the long description in the first dyn_block */ 
    $(".dyn_block").first().find(".long_description").addClass('active').slideDown('fast'); 
}); 
</script> 
<!-- These lines are generated by PHP --> 
<!-- It is POSSIBLE to display the dyn_blocks --> 
<!-- here but I would really rather not --> 
<div id="div_servicetype" class="placeholder">servicetype</div>  
<div id="div_custtype" class="placeholder">custtype</div>   
<div id="div_custinfo" class="placeholder">custinfo</div>   
<div id="div_businfo" class="placeholder">businfo</div> 
</body> 
+0

Vous devez utiliser la fonction de rappel ... c'est ap exemple de pourquoi il est là :) –

Répondre

0

Le problème est que AJAX est asynchronus (par défaut)

$(".dyn_block").first().find(".long_description").addClass('active').slideDown('fast'); 

exécutera avant qu'il y ait des données. Vous ne pouvez donc pas éviter les rappels.

Au lieu du scrutin vous pouvez définir la fonction suivante

var amount = $(".placeholder").size(); 
function ajaxDone() { 
amount--: 
if(amount == 0) { 
    $(".dyn_block").first().find(".long_description").addClass('active').slideDown('fast'); 
} 
} 

Si vous voulez slideDown le premier quand tout le traitement est fait. Comme Nick suggéré En ce qui concerne le commentaire de ne pas savoir wether il importe ou non d'avoir votre javascript sur le HTML, consultez this SO question

il y a:

Donc le script ressemblerait à ceci

<script> /* yes, this script is in the body, dont know if it matters */ 

    var amount = $(".placeholder").size(); 
    function ajaxDone() { 
     amount--: 
     if(amount == 0) { 
     $(".dyn_block").first().find(".long_description").addClass('active').slideDown('fast'); 
     } 
    } 


     $(document).ready(function() { 
      $(".placeholder").each(function(){ // Use the divs to get the blocks 
       var blockname = $(this).html(); // the contents if the div is the ID for the ajax POST 
       $.post("/service_app/dyn_block",'form='+blockname, function(data){ 
        var divname = '#div_' + blockname; 
        $(divname).after(data); 
        $(this).setupAccrdFnctly(); //not the actual code 
       }); 
      }); 

      /* THIS LINE IS THE PROBLEM LINE, is it possible to reference the code ajax inserted */ 
      /* Display the long description in the first dyn_block */ 

     }); 
     </script> 

EDIT une meilleure façon de réaliser la même chose (au lieu d'utiliser la fonction ajaxDone)

$(document).ajaxStop(function() { 
    $(".dyn_block").first().find(".long_description").addClass('active').slideDown('fast'); 
    $(this).unbind('ajaxStop'); 
}); 
+0

Il y a un moyen * beaucoup * plus facile de faire ceci :) Comme ceci: '$ (document) .ajaxStop (function() {$ (". Dyn_block: premier .long_description "). AddClass ('actif'). SlideDown (' fast '); $ (this) .unbind (' ajaxStop ');}); ' –

+0

Vous avez raison! Merci d'avoir souligné cela, je vais modifier la réponse – Lombo

+0

$ (document) .ajaxStop a travaillé comme un champion! Merci beaucoup à vous tous! – Cody

0

AJAX par nature est "asynchrone". Cela signifie que l'exécution continue heureusement après l'envoi de la requête asynchrone; le contenu attendu ne sera pas disponible tant que l'appel AJAX n'est pas terminé. Ainsi, lorsque vous essayez d'accéder au contenu, vous n'obtiendrez rien. Lorsque vous traitez des opérations asynchrones, vous devez utiliser des rappels car vous ne pouvez jamais savoir quand l'opération est terminée. Je ne suis pas sûr de savoir pourquoi vous êtes contre l'utilisation du rappel - c'est la raison pour laquelle il est là - pour vous aider à faire face à des opérations asynchrones.

EDIT

Vous pouvez avoir SJAX (synchrone JAX) si vous définissez la propriété async-false. Il est donc possible de faire ce que vous suggérez, mais vous verrouillez votre navigateur jusqu'à la fin de la requête.

+0

Correction ici, c'est * est * possible. Vous pouvez même verrouiller le navigateur en le faisant, ce qui est exactement ce que 'async: false; –

+0

@Nick Craver c'est vrai. J'ai oublié ça. Je m'embête rarement avec 'async: false'. Va modifier pour corriger. –

Questions connexes