11548 sujets

JavaScript, DOM et API Web HTML5

Bien le bonjour,

je viens vous voir car je me suis enfin mis au javascript, le truc, c'est que je ne suis pas bien doué.

Donc, ce que je cherche à faire, c'est de charger le contenu d'une page PHP dans un DIV.

Je m'éxplique, je suis sur la page d'accueil, qui est divisée en deux partie:

-Le header.php qui contient le logo et le menu principale.
-Le body.php qui contient le contenu en fonction de quel bouton vous appuyez.

Maintenant, j'essaye de faire en sorte que lorsqu'un utilisateur clic sur un bouton de mon menu horizontal, le contenu de la page cible doit venir s'afficher dans le div de body.php sans avoir à recharger la page complète.

Voici ce que j'ai pour l'instant:

index.php

<!DOCTYPE html PUBLIC "-//W3C//DTD DHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Squid Management</title>
<link rel="stylesheet" href="css/header.css" type="text/css" media=screen>
<link rel="stylesheet" href="css/body.css" type="text/css" media=screen>
<link href='http://fonts.googleapis.com/css?family=Droid+Sans&subset=latin' rel='stylesheet' type='text/css'>
</head>

<body>
<?php 
include 'pages/header.php';
include 'pages/body.php';
?>
</body>
</html>


Header.php

<!-- Header SQUID -->
<div id="Logo"><img src="/squid/images/GK_Logo.png" alt="Logo" /></div>
<div id="HeaderMenu">
	<div id="HeaderMenuText" class="FloatRight">
		<ul class="Floatleft">
    		<li><a href="#" onClick="loadpage('/squid/pages/monitoring.php','GlobalBody'); return false;">Monitoring</a></li>
    		<li><a href="#" onClick="loadpage('/squid/pages/reporting.php','GlobalBody');">Reporting</a></li>
    		<li><a href="#" onClick="loadpage('/squid/pages/schedule.php','GlobalBody');">Schedule tasks</a></li>
			<li><a href="#" onClick="loadpage('/squid/pages/configuration.php','GlobalBody');">Configuration</a></li>
		</ul>
	</div>
</div>


body.php

<div id="GlobalBody">
</div>
<script language="javascript" src="/squid/cgi/LoadBody.js"></script>


LoadBody.js

// JavaScript Document
function loadpage(url,id)
{
	var xhr_object = null;
	var contenair = id;
	
if(window.XMLHttpRequest) {
xhr_object = new XMLHttpRequest(); //Création d'un objet xhr_object chargé de communiqué en xml avec le serveur.
xhr_object.open("GET", url, true); //Ouverture / Lecture de l'URL cible.
document.getElementById("contenair").innerHTML = xhr_object.responseText; //Insertion de la reponse text de xhr_object dans le DIV passé en argument. 
}
}


Voila, donc mon problème c'est que j'obtiens l'erreur suivante:

Uncaught TypeError: Cannot set property 'innerHTML' of null

Le hic c'est que comme je débute, je vois pas trop ce qu'il veux le bougre!!

J'ai regardé sur gooooooogle, et apparement c'est une erreur de placement du script, mais meme si je le place en fin de fichier, c'est pareil.

Donc si une âme charitable voulait bien regarder mon bout de code et me dire si c'est correct, je lui en serait reconnaissant. Smiley lol
Modifié par DR I (21 Oct 2010 - 16:37)
Salut DR I,

Je pense qu'il faut que tu enlèves les guillemets autour de "contenair" dans ce bout de code :
document.getElementById("contenair").innerHTML


Tu veux passer une variable et non une chaine de caractère.
Hello, merci de ton aide Smiley lol

Bien, j'ai enlevé les guillemets, et en effet, je n'ai plus d'erreur, le hic c'est que maintenant je n'ai rien qui viens s'afficher sur mon DIV cible.

Est ce normal?
La page php à mettre dans le DIV existe bien et le DIV à bien le bon ID, je ne comprend pas trop ce qui se passe là.

Existe t'il des bonnes pratiques du debugging en javascript?
Personnellement pour le debug javascript, j'utilise firebug pour firefox. Avec cet outil, tu devrais pouvoir tracer ta fonction et trouver ce qui ne va pas.
Bah la j'utilise actuellement les outils de débogage de chrome, par contre je ne vois plus d'erreurs javascript maintenant que j'ai fait le changement que tu m'a indiqué Smiley lol

Par contre, il ne se passe rien Smiley lol alors que normalement le script devrait afficher le contenu d'une page dans un div de mon site Smiley lol
C'est normal : tu n'envoies pas de requête vers ton serveur !

Quand tu as ton objet XHR, il faut que tu fasses :

1 - open : pour préparer ta requête
2 - onreadystatechange : tu lui donne une fonction à exécuter quand il y aura du nouveau dans le traitement de ta requête HTTP (çàd un callback)
3 - send : tu envois ta requête dans la jungle d'internet

Voila, je ne détailles pas plus, tu trouvera des milliers d'articles qui expliqueront cela bien mieux que moi. Smiley cligne
Ok donc je viens de corriger le souci de la syntaxe.

Par contre ce que je me demande, c'est pourquoi quasiment tous les exemples mettent "xhr_objectif.send(null)"?

Si c'est null c'est qu'ils n'envoie rien? Du coup comment fait le serveur pour pouvoir connaître la requête?
Tu n'envois pas rien : tu envois une requête, mais sans contenu.
C'est le cas quand tu envois une requête de type GET.
Bonjour MonsieurY, oui en effet, j'ai lu cette nuance aujourd'hui sur le net.

Donc, pour faire mes tests, j'ai modifié le script afin de faire apparaitre une fenetre qui contient la réponse du serveur comme ceci:


// JavaScript Document
function loadpage(url,id)
{
	var xhr_object = null;
	var contenair = id;
	
if(window.XMLHttpRequest) {
xhr_object = new XMLHttpRequest(); //Création d'un objet xhr_object chargé de communiqué en xml avec le serveur.
xhr_object.open("GET", url, true); //Methode d'attaque souhaité (ici GET car HTTP normal) / URL cible / Mode de transmission, ici true car AJAX.
xhr_object.send(null);

//document.getElementById(contenair).innerHTML = xhr_object.responseText; //Insertion de la reponse text de xhr_object dans le DIV passé en argument. 

		alert (xhr_object.responseText);
}
}


Le hic, c'est que la boite s'affiche bien mais ne contient strictement rien alors qu'elle devrait afficher:


<?php
echo ('<img src="http://cache.gizmodo.fr/wp-content/uploads/2010/10/privacyTN.jpg" />');
?>


ou bien:


<img src="http://cache.gizmodo.fr/wp-content/uploads/2010/10/privacyTN.jpg" />


hors là je n'ai rien Smiley bawling

par contre, cette fois, Chrome me dit bien:

XHR finished loading: "http://novavision.studio.free.fr/squid/pages/monitoring.php".
En fait quand tu fais une requête "xhr_object.open("GET", url, true);" le true veux dire "mode asynchrone". C'est très bien, et la dessus tu ne fais pas d'erreur, par contre ton problème vient du fait que tu n'as pas bien saisis ce que cela implique.

Voila ce qu'il se passe pas à pas :

1 - tu exécutes la fonction loadpage
2 - 1 ou 2 millièmes de secondes plus tard, tu initialise ton objet xhr (open)
3 - 1 ou 2 millièmes de secondes plus tard, tu envois ta requête http (send)
4 - 1 ou 2 millièmes de secondes plus tard, tu met le contenu de la réponse dans ta div
5 - tu sors de ta fonction loadpage
6 - plusieurs centaines de millisecondes plus tard tu reçois la réponse de ton serveur... sauf que c'est trop tard !!


Pour remédier à ce problème il faut que tu exécutes ton action (mettre à jour ta div) de manière asynchrone. Pour faire cela tu va donner à ton objet xhr une fonction qu'il se chargera lui même d'exécuter en temps et en heure. Cela s'appelle un "callback".

En gros cela va te donner ça :

1 - tu exécutes la fonction loadpage
2 - 1 ou 2 millièmes de secondes plus tard, tu initialise ton objet xhr (open)
3 - 1 ou 2 millièmes de secondes plus tard, tu donnes à ton objet xhr un callback (onreadystatechange)
4 - 1 ou 2 millièmes de secondes plus tard, tu envois ta requête http (send)
5 - tu sors de ta fonction loadpage
6 - plusieurs centaines de millisecondes plus tard tu reçois la réponse de ton serveur...
7 - l'objet xhr lance la fonction que tu lui avais confié auparavant
8 - la fonction met à jour le contenu
9 - tu décapsules une bière pour fêter ça

// JavaScript Document 
function loadpage(url,id) 
{ 
  var xhr_object = null; 
  var contenair = id; 
     
  if(window.XMLHttpRequest) { 
    xhr_object = new XMLHttpRequest();
    xhr_object.open("GET", url, true); //true car asynchrone.
    xhr_object.onreadystatechange = function(){ // quand il y a du nouveau executes ça
      if(xhr_object.readyState != 4) return; // on s'en moque
      if(xhr_object.status != 200 && xhr_object.status != 304){
        alert("erreur " + xhr_object.status); // quelque chose cloche sur ton serveur
        return;
      }
      document.getElementById(contenair).innerHTML = xhr_object.responseText;
    };
    xhr_object.send(); // pas besoin de null
  } 
} 


PS : sinon, pour que ce soit un peu moins abstrait je te conseilles d'installer fiddler, c'est un inspecteur http, cela te permet de voir toutes les requêtes http, leur réponse, les headers, absolument tout. C'est très utile pour débugger (et plus pratique firebug et les outils chrome), et tu verra plus clairement ce qu'il se passe dans tes communication réseau : à quoi corresponds vraiment une requête GET, POST, etc.
Modifié par MonsieurY (21 Oct 2010 - 14:29)
Merci beaucoup MonsieurY, je vais vérifier et faire des tests avec tes explications.

Je viens d'aller à la fnac chercher deux bouquins pour "JAVASCRIPT/AJAX", un debutant, et un expert, comme ça, j'ai les deux niveaux ;-D

Juste une question:

-Si j'ai bien compris, dans ton exemple, req vas devoir etre defini, ou bien remplacé par xhr_object non?

Sinon il vas me dire que l'objet n'est pas défini? Smiley rolleyes

Encore merci pour votre aide à tous.
Je fait des tests et je reviens vers vous.
Modifié par DR I (21 Oct 2010 - 14:34)
Arff, on a modifié nos postes en meme temps Smiley lol

Au final, j'avais bien percuté pour le coup des déclarations d'objets, variables etc. ;-D
DR I a écrit :
Juste une question:

-Si j'ai bien compris, dans ton exemple, req vas devoir etre defini, ou bien remplacé par xhr_object non?

Sinon il vas me dire que l'objet n'est pas défini? Smiley rolleyes


L'objet req, c'est xhr_object, j'ai fait un copier coller d'un de mes sites et j'ai oublié de renommer l'objet. C'est corrigé.
Chose Promis, chose due!

Ça fonctionne tres bien maintenant, et j'ai bien compris comment faire maintenant!

Je viens de tester avec un OnMouseOver, c'est génial.

Par contre, il vas pas falloir abuser de ces effets je pense.
Smiley rolleyes