2010-03-31 6 views
3

J'essaie d'avoir un bouton qui onclick va appliquer une classe loading (place le curseur sur "wait") au corps, avant de faire une série de requêtes ajax.jQuery addClass() ne fonctionne pas avant jQuery.ajax()

code

est:

$('#addSelected').click(function(){ 
    $('body').addClass('loading'); 

    var products = $(':checkbox[id^=add_]:checked'); 
    products.each(function(){ 
     var prodID = $(this).attr('id').replace('add_', ''); 
     var qty = $('#qty_' + prodID).val(); 
     if($('#prep_' + prodID).val()) 
     { 
      prodID += ':' + $('#prep_' + prodID).val(); 
     } 
     // Have to use .ajax rather than .get so we can use async:false, otherwise 
     // product adds happen in parallel, causing data to be lost. 
     $.ajax({ 
      url: '<?=base_url()?>basket/update/' + prodID + '/' + qty, 
      async: false, 
      beforeSend: function(){ 
       $('body').addClass('loading'); 
      } 
     }); 
    }); 
}); 

J'ai essayé de faire

$('body').addClass('loading'); 

avant les demandes, et comme un rappel beforeSend, mais il n'y a pas de différence.

Dans firebug je peux voir que body n'atteint pas la classe loading jusqu'à ce que les demandes sont terminées.

Des idées? Je n'ai pas ce tri d'une manière que je considère comme propre, mais j'ai trouvé une solution.

Si j'ajoute setTimeout(function(){ ci-dessus var products... et }, 1); en dessous de la fin du bloc products.each, ce morceau est en retard, donc addClass arrive en premier.

+0

quel élément a l'ID de addSelected? S'il s'agit d'une balise d'ancrage, cela peut provoquer l'actualisation de la page. sauf si vous empêchez cela ailleurs dans votre code. – Samuel

+0

c'est un Josh

+0

Dans mon expérience pour l'utilisation ** addClass() ** l'élément doit déjà avoir un ** class =" "** dedans! Si l'élément n'a pas de classe, vous devez utiliser ** attr() ** comme suit: $ ('body'). Attr ('classe', 'chargement'); –

Répondre

2

Jetez un coup d'œil au .ajaxStart jquery event.

Il ressemblerait à quelque chose comme ça

$('#addSelected').ajaxStart(function() { 
    $('body').addClass('loading'); 
}); 

EDIT: Je pris un coup d'œil à la documentation jquery et a constaté que la mise en async = false verrouille le navigateur d'autres actions. De la documentation jquery:

asyncBoolean Par défaut: true

Par défaut, toutes les demandes sont envoyées asynchrones (à savoir ce paramètre est réglé sur true par défaut). Si vous avez besoin de requêtes synchrones, définissez cette option sur false. Notez que les requêtes synchrones peuvent verrouiller temporairement le navigateur, en désactivant toutes les actions pendant que la demande est active.

Cela peut-il causer le problème? Essayez de vous connecter à la console dans l'événement ajaxStart et voyez s'il se déclenche.

+0

Cela commence aussi une fois les requêtes terminées: S – Josh

+0

La connexion à la console fonctionne correctement, c'est juste la méthode jquery qui est retardée.On dirait que je vais devoir utiliser la méthode setTimeout. – Josh

+0

Ayant exactement le même problème que décrit dans la question d'origine, la définition de 'async: false' dans l'appel ajax a fonctionné pour moi! – TheThirdMan

0

Quelle version de jQuery utilisez-vous? Je fais des fonctionnalités très similaires et mes appels ont toujours lieu avant l'appel ajax. J'utilise la version 1.4.2 de jQuery, alors peut-être que votre problème est une version plus ancienne? En outre, étant donné que vous effectuez une boucle "each()", vous devez absolument appeler addClass avant l'appel .ajax.

+0

En utilisant 1.3.2, et juste essayé avec le google hébergé 1.4.2, et j'ai le même problème. Il n'y a pas d'autre question sur la page non plus. – Josh