2011-03-17 3 views
0

J'ai une salle de discussion en ligne qui utilise jQuery/Ajax pour demander des données au serveur. Cependant, la méthode que j'utilise est très inefficace et j'essaie de l'améliorer en chargeant seulement les données du serveur si le contenu du chat a été changé (nouveau message, etc.) La méthode semble être logiquement correcte, bien qu'elle n'évalue jamais à vrai. J'ai joint le code ci-dessous, s'il vous plaît dites-moi ce que je fais mal car cela me donne un moment très difficile. Je veux que le chat div soit modifié uniquement lorsque les données du serveur sont différentes.Quel est le problème avec cette fonction jQuery/Ajax?

function loadMsgs() 
{ 
var v_loadMsgs = new XMLHttpRequest(); 

v_loadMsgs.open("GET", "msgs.php"); 

v_loadMsgs.onreadystatechange = function() 
{ 
    var old_content = $("#msgs").html(); 
    var new_content = v_loadMsgs.responseText; 

    if (old_content != new_content) 
    { 
     $("#msgs").html(new_content); 
    } 

    if (old_content == new_content) 
    { 
     $("#msgs").html("EQUAL!"); // only here for testing 
    } 
}; 

v_loadMsgs.send(null); 
} 

Répondre

1

J'utiliserais simplement les fonctions AJAX de jQuery. Ils font vraiment tout simple:

function loadMsgs() 
{ 
    jQuery.get("msgs.php", function(data) 
    { 
     if ($("#msgs").html() != data) 
     { 
      $("#msgs").html(data); 
     } else { 
      $("#msgs").html("EQUAL!"); // only here for testing 
     } 
    }); 
} 

Si vous voulez vraiment savoir pourquoi votre méthode ne fonctionne pas, vous n'êtes pas vérifier si le serveur vous envoie en fait une réponse (qui renvoie une readyState de 4):

function loadMsgs() 
{ 
var v_loadMsgs = new XMLHttpRequest(); 

v_loadMsgs.open("GET", "msgs.php"); 

v_loadMsgs.onreadystatechange = function() 
{ 
    if (v_loadMsgs.readyState == 4) 
    { 
     var old_content = $("#msgs").html(); 
     var new_content = v_loadMsgs.responseText; 

     if (old_content != new_content) 
     { 
      $("#msgs").html(new_content); 
     } 

     if (old_content == new_content) 
     { 
      $("#msgs").html("EQUAL!"); // only here for testing 
     } 
    } 
}; 

v_loadMsgs.send(null); 
} 
+0

Fonctionne comme un charme! Je vais aller plus loin dans les fonctions Ajax de jQuery, elles ont l'air vraiment sympa. Merci beaucoup! – Zack

+0

jQuery est rempli avec des tonnes de fonctions utiles;) Cochez l'une des réponses comme solution, si la réponse a répondu à votre question. Lorsque vous le faites, cela aide d'autres personnes ayant le même problème à trouver la solution plus rapidement. – Blender

+0

Merci, je viens de le faire :) Et merci beaucoup d'avoir signalé mon erreur initiale, ça me rendait fou. Je ne vérifiais pas le readyState parce que j'avais l'impression que jQuery le faisait seul, mais je suppose que c'était un mauvais malentendu! – Zack

1

essayer d'utiliser jquery's ajax functions

+1

Merci pour la suggestion, mais je cherche une explication pour expliquer pourquoi cela ne fonctionne pas. Ma mise en œuvre est-elle défectueuse ou cette méthode n'est-elle pas appropriée? – Zack

+0

qu'est-ce que 'toujours évalue à true'? – Neal

+0

Conçu pour écrire faux! – Zack

3

Lorsque vous faites .html(), le navigateur HTML vous donne parfaitement formaté. Autrement dit, tous les tags sont fermés, tous les attributs entre guillemets, ce genre de chose. Et ce que vous revenez de msgs.php est, très probablement, pas parfaitement formaté. Par conséquent, la différence.

Si vous êtes inquiet au sujet de l'inefficacité, cependant, cette méthode serait très inefficace. Je veux dire, oui, vous ne mettez plus à jour l'UI inutilement, mais vous chargez toujours la liste des messages du serveur, n'est-ce pas?

Afin d'économiser quelques octets ici, vous devriez plutôt avoir utilisé la technique "si-modifié". C'est, avec la liste des messages, retourner une sorte d'horodatage. Dites, juste un nombre entier. Lorsque quelque chose change sur le serveur, augmentez cet entier de un. Lorsque vous demandez une mise à jour au serveur, demandez à votre code AJAX de passer l'horodatage reçu précédemment, puis demandez au serveur de répondre "rien n'a changé" si l'horodatage est en cours. Sinon, demandez au serveur de transmettre la nouvelle liste de messages. C'est, à peu près, l'idée.

+0

Wow, je ne le savais pas, merci. Il semble que mon meilleur pari est de regarder dans les fonctions jQuery.ajax() pour quelque chose comme ça, je suppose. – Zack

+0

@ user665132: voir ma mise à jour s'il vous plaît. Et au fait, utiliser 'jQuery.ajax' ne vous aidera pas du tout. –

+0

Je vois ce que vous dites. Cela semble être une bonne idée, car le reponseText stocke toutes les données fournies par le serveur et est constamment vidé/rechargé avec lui. Je vais certainement faire ça :) – Zack

Questions connexes