11548 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

Je souhaiterais faire un questionnaire (avec gestion d'affichage du temps des questions) utilisant les css (plutôt que les iframes).

Je suis partit du code présent sur cette page : ici mais je n'arrive pas exactement à obtenir ce que je désire (mes connaissances en javascript étant quasi nulles).

Voila le code que j'utilise :
essai.js
function disparition(id, duree) {
   	document.getElementById(id).style.visibility = 'visible';
   	if (!document.getElementById) return false;
   	if (!document.getElementById(id)) return false;
   	this.oDiv = document.getElementById(id);
  	this.parent = this.oDiv.parentNode;
  	this.timeoutId = null;
        this.func = null;
 	this.duree = duree * 1000;
 	this.init();
}

disparition.prototype.init = function() {
	var oThis = this;
 	this.func = function () {oThis.disparait();};
	this.timeoutId = setTimeout(this.func, this.duree);
}

disparition.prototype.disparait = function () {	
	this.parent.removeChild(this.oDiv);
	clearTimeout(this.timeoutId);
}

<html><head>
<script type="text/javascript" src="essai.js"></script></head>
<div><u>Question 1</u> : Question ?
<br><a onclick="var d = new disparition('q1', 5);return false;">Clique ici pour voir les réponses - Vous aurez 5 secondes pour choisir</a><br>
<div style="visibility: hidden;" id="q1">A)  B)  C)  D) </div>
<div class="blanc"><input type=radio name=1 value=0>A</div>
<div class="blanc"><input type=radio name=1 value=2>B</div>
<div class="blanc"><input type=radio name=1 value=0>C</div>
<div class="blanc"><input type=radio name=1 value=0>D</div>
</div>
<br>
<div><u>Question 2</u> : Question ?
<br><a onclick="var d = new disparition('q2', 5);return false;">Clique ici pour voir les réponses - Vous aurez 5 secondes pour choisir</a><br>
<div style="visibility: hidden;" id="q2">A)  B)  C)  D) </div>
<div class="blanc"><input type=radio name=2 value=0>A</div>
<div class="blanc"><input type=radio name=2 value=2>B</div>
<div class="blanc"><input type=radio name=2 value=0>C</div>
<div class="blanc"><input type=radio name=2 value=0>D</div>
</div>
</body>


Le problème c'est que lorsque je clique sur le premier lien, j'ai bien les réponses qui s'affichent pendant 5 secondes avant de disparaître, mais si je clique une deuxième fois sur le même lien j'ai une erreur javascript. Ainsi, j'aimerai que le lien devient inactif une fois cliqué (les réponses ne pouvant être affichées qu'une seule fois).

Ensuite, je voulais savoir si vous savez s'il est possible d'afficher à la fin des 5 secondes le contenu d'un nouveau div (pour inviter les gens à sélectionner leur réponse) plutôt que de supprimer le div.

Le top du top serait que tout soit au même endroit : d'abord le lien qui invite à cliquer pour obtenir les réponses, puis les réponses qui s'affichent pendant 5 secondes et enfin l'invitation à remplir la réponse.

J'espère avoir été assez clair Smiley confus

En tout cas je vous remercie d'avance pour votre aide.

Rémy.
Modifié par remy498 (26 Aug 2006 - 23:49)
La fonction plante au deuxième essai car tu ne masques pas ton div au bout de 5 secondes, tu le supprimes (avec this.parent.removeChild(this.oDiv);)! Donc, lors du second clic, l'élément à afficher n'existe plus, d'où erreur.

D'ailleurs, dans la fonction principale, tu testes bien si l'objet à afficher existes, mais tu testes après l'avoir utilisé !! De la même manière, il est très louable de vérifier l'existence de getElementById, mais tu le fais après l'avoir utilisé. pour qu'elles soient efficaces, if faudra donc que tu déplaces tes deux vérifications (les deux premiers if) au début de la fonction, et éventuellement que tu remplaces la supression du div par un changement de style (this.oDiv.style.visibility = 'visible';).

Pour rendre le lien inactif, tu peux le passer en parammètre de ta fonction principale, et il sera ainsi facilement manipulable (par exempleen le masquant il sera forcément "désactivé"). Enfin, pour afficher les choix, tu peux ajouter un quatrième paramètre qui contient l'identifiant du div pour répondre. En le récupérant de la même manière que celui qui montre les réponses, tu pourras dire de l'afficher dans la fonction qui s'execute au bout de 5 secondes..

Je suis très mauvais en discours, alors ca ira mieux comme ca :


function disparition(lien, idReponses, idFormulaire, duree) {
	// La fonction getElementById est-elle dispo ?
   	if (!document.getElementById) return false;

	// On récupère les deux div
	this.divReponses = document.getElementById(idReponses);
	this.divFormulaire = document.getElementById(idFormulaire);

	// On-t-ils été trouvés ?
	if(this.divReponses == null || this.divFormulaire == null)
		return null;
 
	// On masque le lien
	lien.style.display = 'none';

	var oThis = this;
	// On appelle la fonction de changement de div dans X secondes
	this.idTimer = setTimeout(function() { oThis.disparait();}, duree * 1000);
}

// Au bout de X secondes...
disparition.prototype.disparait = function () {	
	// On masque les réponses
	this.divReponses.style.display = 'none';
	// On affiche le formulaire
	this.divFormulaire.style.display = 'block';

	// Et on arrete le chrono pour ne pas rappeler la fonction dans X secondes
	clearTimeout(this.timeoutId);
}




Dans la page cela nous donne :


<head>
<script type="text/javascript" src="essai.js"></script></head>
<body>
<div><u>Question 1</u> : Question ?
<br><a [b]onclick="var d = new disparition(this, 'q1', 'r1', 5);return false;"[/b]>Clique ici pour voir les réponses - Vous aurez 5 secondes pour choisir</a><br>
<div style="display: none;" [b]id="q1"[/b]>A)  B)  C)  D) </div>
<div class="blanc" [b]id='r1'[/b]>
<input type=radio name=1 value=0>A<br />
<input type=radio name=1 value=2>B<br />
<input type=radio name=1 value=0>C<br />
<input type=radio name=1 value=0>D
</div>
</div>
<br>
<div><u>Question 2</u> : Question ?
<br><a [b]onclick="var d = new disparition(this, 'q2', 'r2', 5);return false;"[/b]>Clique ici pour voir les réponses - Vous aurez 5 secondes pour choisir</a><br>
<div style="visibility: hidden;" [b]id="q2"[/b]>A)  B)  C)  D) </div>
<div class="blanc" [b]id='r2'[/b]>
<input type=radio name=1 value=0>A<br />
<input type=radio name=1 value=2>B<br />
<input type=radio name=1 value=0>C<br />
<input type=radio name=1 value=0>D
</div></div>
</body>



J'ai aussi remplacé visibility par display, ainsi les éléments se remplacent les uns les autres plutôt que d'avoir de gros blancs parcequ'ils sont fixes. Par contre ca risque de faire pas mal bouger la page au fur et à mesure que ca apparaît / disparait, mais tu peux régler ce problème en donnant une hauteur fixe aux div qui englobent tous les éléments de chaque question

Voila (arf, c'est long... Smiley sweatdrop )
Je te remercie grandement du temps que tu as passé sur mon problème.

Je vais essayer ça tout de suite pour voir si ça fonctionne bien Smiley smile

Encore un GRAND merci.

Rémy.
C'est parfait ça marche comme souhaité, je n'aurai jamais imaginé que c'était possible.

Encore merci pour ton aide très précieuse.

PS : j'ai rajouté une ligne dans le script, sinon la question ne s'affichait pas (j'espère que c'est correct ce que j'ai fait).


function disparition(lien, idReponses, idFormulaire, duree) {
	// La fonction getElementById est-elle dispo ?
   	if (!document.getElementById) return false;

	// On récupère les deux div
	this.divReponses = document.getElementById(idReponses);
	this.divFormulaire = document.getElementById(idFormulaire);

	// On-t-ils été trouvés ?
	if(this.divReponses == null || this.divFormulaire == null)
		return null;
 
	// On masque le lien
	lien.style.display = 'none';

        [b]this.divReponses.style.display = 'block';[/b]

	var oThis = this;
	// On appelle la fonction de changement de div dans X secondes
	this.idTimer = setTimeout(function() { oThis.disparait();}, duree * 1000);
}

// Au bout de X secondes...
disparition.prototype.disparait = function () {	
	// On masque les réponses
	this.divReponses.style.display = 'none';
	// On affiche le formulaire
	this.divFormulaire.style.display = 'block';

	// Et on arrete le chrono pour ne pas rappeler la fonction dans X secondes
	clearTimeout(this.timeoutId);
}