11548 sujets

JavaScript, DOM et API Web HTML5

Voilà, mon problème est simple, mais je trouve absolument rien qui m'aide sur la toile, donc je viens vous voir.

J'ai un premier fichier php (regard.php) qui génère un html. Dans cet html, il y a un "onclick" en javascript qui transmet des informations.

Ca lance donc une fonction qui traîne dans mon utile.js (mon fourre-tout javascript à moi pour l'instant).

Cette fonction (que j'ai pas encore codé) est sensé faire un truc du genre :
1)désactive le clic
2)on vérifie que les variables au javascript sont possibles
3)on envoie à un fichier php (change.php) certaines informations en get (deux numéros en fait)
4)on change la source, le title et le alt de une ou plusieurs images sur le HTML
5)on lance une alert pour prévenir le joueur de ce qui vient de lui tomber sur le nez
6)on envoie le joueur sur une nouvelle page le cas échéant

Change.php quant à lui :
1) fait toutes les vérifications d'usages
2) va chercher des informations dans une table
3) en fonction des informations modifient 1 ou 2 tables
4) renvoie des informations au JS (sous forme de chiffre de 1 à 3 ça m'irait parfaitement)

les points 1 à 4 du javascript me cause aucun problème.

Mais je buggue complètement sur le point 4 du PHP et le points 5 et 6 du javascript. Forcément, l'alert dépend de la conclusion de change.php; ainsi que la nécessité ou non de rediriger le joueur.


En gros ma question c'est comment faire pour faire un retour d'information de change.php vers utile.js ?
Modifié par Lothindil (07 Sep 2011 - 11:32)
pberghof a écrit :
Bonjour,

Utilises-tu un framework javascript de type jquery ?

Si c'est le cas avec jquery.ajax() tu peux utilises une fonction success qui te permet d’exécuter du javascript en retour de ton appel ajax : http://api.jquery.com/jQuery.ajax/


Même sans framework, avec une requête AJAX, tu as la possibilité de définir ce que tu veux en callback...
J'ai du mal à capter le souci, en fait.
Bah ma question c'est justement comment faire ce callback. Smiley confused

Le seul retour que j'ai fait c'est avec echo dans le php et xmlHttp.responseText dans le javascript...
Mais d'après ce que j'ai lu, c'est très limité comme utilisation. (1 seule transmission possible, considéré comme un string obligatoirement, donc pas de test chiffré dessus) Smiley ohwell

(et non, je n'utilise pas de framework pour mon javascript)
Tu cherches quel format de retour utiliser, en fait.

AJAX est initialement utilisé avec un retour XML (puisque JS parse correctement le XML).
Tu peux aussi (et j'ai envie de dire que c'est l'utilisation la plus pratique) retourner du JSON. PHP possède deux fonctions pile pour ça (json_encode et decode, si ma mémoire est bonne, au pire, composant Zend JSON).

Tu devrais pour ton JS Smiley cligne Ca accélère fortement le développement, et te permet une compatibilité avec la plupart des navigateurs existants, out-of-box Smiley smile
Pour être plus clair...

Mon code sur utile.js donne une structure comme ça :


function VerifGracieuse(rune,colonne)
{var xmlHttp=null;
  try
  {// Firefox, Opera 8.0+, Safari, IE7
    xmlHttp=new XMLHttpRequest();
  }
  catch(e)
  {// Old IE
  try
    {
    xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
  catch(e)
    {
    alert ("Votre navigateur ne supporte pas XMLHTTP, veuillez installer un navigateur plus récent (IE7+, FF2+, Opera 8+, Safari, Chrome)");
    return;  
    }
  }
//désactive le clic (sur les 6 éléments pouvant appeler cette fonction dans le HTML)
//on lance au PHP que la rune n°rune de la colonne a été activé
var url="change.php?a="+rune+"&b="+colonne+"";
  xmlHttp.open("GET",url,false);
  xmlHttp.send(null);
//on change l'image de la rune
//on averti le PJ de ce qu'il vient de déclencher
if(???)
  {
    alert(xmlHttp.responseText);
    window.location.replace("carte.php");
    return false;
  }
  else if(????) 
  {
     alert(xmlHttp.responseText);
  }
  //on réactive le clic



Les ??? sont bien sûr là où je coince complètement...


Le code PHP de change.php donne ça (pour cette partie-là)

//vérification d'usage (que ce qui est transmis par l'URL ne va pas tout faire sauter, que les n° transmis sont possibles, ...)
//vérifier si le PJ a déjà joué avec les colonnes
//vérifier si le PJ n'a pas déjà activé cette rune-là
//updater les tables
//Vérifier la justesse du code si les 8 colonnes ont été activées
//////test pour voir si le code est juste
if($verif==0)   //si pas complet ($verif=0)
{
    ???
}
elseif($erreur==0)   //si vrai changement dans la table carte ($verif=1;$erreur=0)
{
     //changement dans la table
     echo "Tout autour de vous tourbillonne, vous sombrez dans l'inconscience et reprenez conscience ailleurs...";
     ???
}
elseif($erreur==1)//si faux vérifier les PV; ôter 1/2 PVmax+/-10% ($verif=1;$erreur=1)
{
    //ôter les PV nécessaire
    echo "Sortis des huit colonnes, un trait de foudre s'abat sur vous !";
    ???
}


Sur les premiers ??? du php, j'ai juste un chiffre à transmettre (1 en l'occurence)
Sur le second, j'ai 1 chiffre à transmettre (3)
sur le 3ème, j'ai 2 chiffres à transmettre (2 + deux autres nombres qui dépendent des PV perdus et de ce qu'il reste comme PV au PJ)

Ces chiffres (1, 2 et 3) doivent pouvoir être employés dans les "if" du javascript. Le dernier chiffre doit pouvoir être utilisé pour un update d'une image et un update de texte.

Le problème, c'est que jusqu'à présent, je n'ai jamais eu qu'une seule information à transmettre, sans devoir agir dessus, juste pour l'utiliser dans une fonction alert...
Modifié par Lothindil (01 Sep 2011 - 12:23)
Ton cas rentre pile dans l'utilisation de JSON. En PHP, tu retournes une chaîne JSON comprenant ta valeur spéciale et éventuellement d'autres infos, puis dans ton callback JS (que je ne repère pas), tu récupères ton JSON, donc tu peux faire une condition dessus...

Je te conseille très fortement de jeter un oeil sur les tutos AJAX.
Et en pratique, ça se fait comment ? (c'est pas une urgence, c'est pire^^)

*promis j'irais lire les tutos après... Pour l'ajax, j'aurais déjà dû le faire; pour le JSON je ne le connaissais pas y a 24h...*

Je suis ni une as en javascript (disons que je bidouille un peu comme je peux) et encore moins en ajax... (en gros, ça doit être ma 3ème fonction en javascript et ma 2ème en ajax)... Smiley confused
Je te donne un exemple avec jquery:

$.ajax({
  url: "test.php",
  success: function(data){
    $('#toto').text(data.howmany);
    $('#content').text(data.wut);
  }
});


Avec un JSON:
{'howmany': 36, 'wut': 'des kiwis'}


Pouvant être généré par exemple en PHP:
$a = array('howmany'=>36, 'wut'=>'des kiwis');
echo json_encode($a);
exit;


(à vérifier, je n'utilise pas l'API "native" PHP pour passer en JSON)

Dans tous les cas:
- ton PHP retourne une structure (array, objet...) sous format JSON, via echo, simplement
- ton JS reçoit ce JSON et le traite dans le callback AJAX
- dans ce traitement, tu utilises les propriétés JSON : c'est un objet

Si tu ne veux VRAIMENT pas passer par un "framework" JS, pour créer ta fonction de rappel, tu dois la lier à la propriété "onReadyStateChange" de ton objet xmlHttp.

Exemple de tête:
xmlHttp.onReadyStateChange = function(response) {
  if(xmlHttp.readyState == 4) { // correspond à l'état "terminé"
    // ce que tu souhaites faire, donc ici, prendre le response, le traiter comme un JSON
  }
}
Bon, j'ai mis ça en code... maintenant on va vérifier si ça marche...

edit : Génial... ma version de php n'est pas à jour... Bon, on va commencer par mettre PHP à jour... Smiley biggol
Modifié par Lothindil (02 Sep 2011 - 12:53)
bon, mon serveur PHP étant enfin à jour, j'ai pu avancer... mais je crois que j'ai loupé un truc pour utiliser le JSON Smiley sweatdrop

mon fichier php : (fonctionnel seul)

elseif($type==5) 
{
  /*vérification et actions diverses*/
  //si les 8 colonnes ont été activées, vérifier que le code soit juste;
  if($test==1)
  {
    $verif=1;$erreur=0;
    for($a=1;$a<=8;$a++)
    {
      /*vérification de l'énigme*/
    }
  }
  if($verif==0)   //si pas complet echo 1 ($verif=0)
  {
    $arr = array('test' => 1);
    echo json_encode($arr);
  }
  elseif($erreur==0)   //si vrai changement dans pjcarte; echo 3 ($verif=1;$erreur=0)
  {
    /*update des tables*/
    $arr = array('test' => 3);
    echo json_encode($arr);
  }
  elseif($erreur==1)//si faux vérifier les PV; ôter 1/4PVmax+/-10% ($verif=1;$erreur=1)
  {
    /*récupération, création, calcul de variables*/
    $arr = array('test' => 2, 'PVperdu' => $PVperdu, 'dessin' => $dessin, 'PVrestant' => $newPV);
    echo json_encode($arr);
  }   
}


le JavaScript :
function VerifGracieuse(rune,colonne)
{
  if(rune>6||colonne>8)
  {
    return false;
  }
  var xmlHttp=null;
  try
  {// Firefox, Opera 8.0+, Safari, IE7
    xmlHttp=new XMLHttpRequest();
  }
  catch(e)
  {// Old IE
  try
    {
    xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
  catch(e)
    {
    alert ("Votre navigateur ne supporte pas XMLHTTP, veuillez installer un navigateur plus récent (IE7+, FF2+, Opera 8+, Safari, Chrome)");
    return;  
    }
  }
  for (id=1; id<=6; id++)     //désactive le clic
  {
    document.getElementById(id).disabled = true;
  }
  //on lance à l'ajax que la rune n°rune de la colonne a été activé
  var url="change.php?z="+rune+"&y="+colonne+"&type=5";
  xmlHttp.open("GET",url,false);
  xmlHttp.send(null);                  
  //on change l'image de la rune
  var lettre='a'; var sens=0; var k;
  for(k=1;k<=6;k++)
  {
    if(k==rune){sens=1;}else{sens=0;}
    document.getElementById(k).src='images/bouton/gracieuse'+lettre+'-'+sens+'.png';
    lettre = String.fromCharCode(lettre.charCodeAt(0)+1);
  }
  if (xmlHttp.readyState == 4) 
  { 
      var jayson = xmlHttp.responseText;  //on récupère le json du PHP
      JSON.parse(jayson);
  }
  if(jayson.test==0)//s'il y a un problème
  {
    alert(jayson.message);
    return false;
  }
  //on lance l'alert en cas de blessure (2) ou de téléportation (3). Et on reload uniquement en cas de téléportation.
  else if(jayson.test==3)
  {
    alert("Tout autour de vous tourbillonne, vous sombrez dans l'inconscience et reprenez conscience ailleurs...");
    window.location.replace("carte.php");
    return false;
  }
  else if(jayson.test==2) 
  {
    alert("Sortis des huit colonnes, un trait de foudre s'abat sur vous ! Vous perdez "+jayson.PVperdu+" PV");
    document.getElementById(pv).src='images/pv/'+jayson.dessin+'.gif';
    document.getElementById('pvtext').innerHTML=jayson.PVrestant;
  }
  for (id=1; id<=6; id++)     //on réactive le clic
  {
    document.getElementById(id).enabled = true;
  }
}



A part que ma variable "jayson" ne semble pas être analysé, à aucun moment... j'ai pas d'alert ni aucun changement. Smiley confused

Et j'avoue que j'ai beau parcourir des tutoriels, j'y capte pas tout.
Je te rappelle le fonctionnement pour l'utilisateur du callback JS, via un exemple:


var xhr = null;

if (window.XMLHttpRequest || window.ActiveXObject) {
	if (window.ActiveXObject) {
		try {
			xhr = new ActiveXObject("Msxml2.XMLHTTP");
		} catch(e) {
			xhr = new ActiveXObject("Microsoft.XMLHTTP");
		}
	} else {
		xhr = new XMLHttpRequest(); 
	}
} else {
	alert("Votre navigateur ne supporte pas l'objet XMLHTTPRequest...");
	return null;
}

xhr.onreadystatechange = function() {
	if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0)) {
		// traitement avec xhr.responseText
	}
};

xhr.open("GET", "cible.php", true);
xhr.send(null); // ou autre, ça dépend des données à envoyer


Toujours pas tenté par un "framework" comme jQuery ?
$.get('cible.php', {}, function(data) { }); // équivalent à ci-dessus




C'est le onReadyStateChange qui te manque. Il te faut bien saisir le fonctionnement d'AJAX. JS demande l'envoi asynchrone d'une requête. C'est l'objet JS qui a, dans la propriété onReadyStateChange, le comportement à adopter lorsque la requête change de status (code HTTP et code de progression de la requête, d'où les vérifs readyState == 4 (terminé) et statusCode == 200 (http OK)).
Si tu ne définis pas de comportement (donc, une fonction) dans cet onReadyStateChange, JS ne fera rien une fois qu'il aura la réponse à la requête.
Modifié par Lpu8er (07 Sep 2011 - 10:15)
la partie :
xhr.onreadystatechange = function() {

	if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0)) {

		// traitement avec xhr.responseText

	}

};


Elle peut aller après le xhr.send ? (chais pas, ça semble bizarre d'avoir le traitement de ce qui revient du php avant l'envoi^^)


Sinon, ouais, le framework il a l'air plutôt sympa vu comme ça... Smiley rolleyes Faut l'installer ? Ca marche comment ? Smiley murf
Modifié par Lothindil (07 Sep 2011 - 10:31)
En fait, le send envoie les données. Techniquement, c'est donc trop tard. Tout ce que tu fais avant l'envoi, c'est la configuration de l'objet que tu as créé (xhr, xmlHttp, peu importe son nom). Donc tu dois régler onReadyStateChange (pour être précis, c'est une méthode d'événements, tu peux comparer ça aux propriétés d'événements des éléments HTML) avant d'envoyer les données.

Pour les "frameworks" JS, la plupart du temps c'est un ou quelques fichiers JS à poser où tu veux, et que tu intègres dans ta page via la balise script. Oui, c'est tout Smiley smile

Alsacréations est fortement imprégné par jQuery, qui est très performant même si sa syntaxe fait hérisser quelques poils chez les puristes.
Documentation : http://api.jquery.com/

Exemple tiré droit de la doc, pour charger un contenu par AJAX...
$('#result').load('ajax/test.html');



Pour ton impression bizarre, ça vient du fait que c'est de la prog événementielle, rarement rencontrée, à part en JS. Tu définis les comportements selon les événements. C'est un peu comme dire "toi, l'objet au fond de la salle, tu lèveras la main si tu vois un ovni", ce qui pourrait se traduire (en jQuery, par pure simplicité d'écriture, en JS pure la syntaxe est similaire) par:
$('.auFondDeLaSalle').bind('omgOVNI', function() { leverLaMain(); });

Tu définis donc des comportements en fonction d'événements.
En langage de dev, comme PHP (ou Java), tu as des patterns (modèles de conceptions) permettant des fonctionnements similaires. Le pattern Observer est implémenté en PHP via les classes SplObserver et SplSubject, par exemple. Je te donne ce petit aparté si ce mode de fonctionnement t'intéresse, car il est très utile dans le cas d'interface graphique, majoritairement.
Modifié par Lpu8er (07 Sep 2011 - 11:13)
Yess, l'alert se fait avec une des valeurs du JSON... Nickel et finalement simple d'utilisation quand on a compris ^^

(et je sens que je vais me pencher sur le JQuery ^^ j'avoue que vu mes connaissances en javascript, il m'effrayait un peu, mais ça a l'air utile quand même. Smiley confused )


edit : ça m'intéresse... J'ai l'impression que pour faire un jeu en ligne plus intelligent et moins répétitif que d'habitude, tout ou presque est bon à prendre... Smiley cligne
Modifié par Lothindil (07 Sep 2011 - 11:32)