11484 sujets

JavaScript, DOM et API Web HTML5

Je suis en train d'essayer de faire une classe pour créer une horloge (et en avoir plusieurs sur la même page) mais je me heurte à un problème ... En effet, je n'arrive pas à utiliser la fonction setTimeout() pour appeler une méthode.

Voici le code :
function test(num) {


	//Variables à modifier :

	//Les couleurs :
	this.fCol='7777BB'; //couleur des chiffres.
	this.sCol='9999FF'; //couleur des secondes.
	this.mCol='666699'; //couleur des minutes.
	this.hCol='000066'; //couleur des heures.	 

	//position en absolut :
	this.Xoff=100*(num-0.5);  //à gauche
	this.Yoff=47; //en haut

	//taille
	this.Ybase=34; //hauteur
	this.Xbase=34; //largeur

	


	//ne pas modifier ci-après :
	this.H='...';
	this.H=this.H.split('');
	this.M='....';
	this.M=this.M.split('');
	this.S='.....';
	this.S=this.S.split('');

	this.NS4=(document.layers);
	this.NS6=(document.getElementById&&!document.all);
	this.IE4=(document.all);

	this.Ypos=0;
	this.Xpos=0;
	this.dots=12;
	this.Split=360/this.dots;

	if(this.NS6) {
		for(i=1; i < this.dots+1; i++) {
			with(this) document.write('<div id="n6Digits'+i+num+'" style="position:absolute;top:0px;left:0px;width:30px;height:30px;font-family:Arial;font-size:10px;color:#'+fCol+';text-align:center;padding-top:10px">'+i+'</div>');
		}
		for(i=0; i < this.M.length; i++) {
			with(this) document.write('<div id="Ny'+i+num+'" style="position:absolute;top:0px;left:0px;width:2px;height:2px;font-size:2px;background:#'+mCol+'"></div>');
		}
		for(i=0; i < this.H.length; i++) {
			with(this) document.write('<div id="Nz'+i+num+'" style="position:absolute;top:0px;left:0px;width:2px;height:2px;font-size:2px;background:#'+hCol+'"></div>');
		}
		for(i=0; i < this.S.length; i++) {
			with(this) document.write('<div id="Nx'+i+num+'" style="position:absolute;top:0px;left:0px;width:2px;height:2px;font-size:2px;background:#'+sCol+'"></div>');
		}
	}

}

function clock(num,fuseau){
	
	this.time = new Date ();
	this.secs = this.time.getSeconds();
	this.sec = -1.57 + Math.PI * this.secs/30;
	this.mins = this.time.getMinutes();
	this.min = -1.57 + Math.PI * this.mins/30;
	this.hr = this.time.getHours();
	this.hr = this.hr+fuseau;
	this.hrs = -1.57 + Math.PI * this.hr/6 + Math.PI*parseInt(this.time.getMinutes())/360;

	if(this.NS6) {
		this.Ypos=this.Yoff;
		this.Xpos=this.Xoff;
		
		for(i=1; i < this.dots+1; i++) {
			with(this) document.getElementById("n6Digits"+i+num).style.top=Ypos-15+Ybase*Math.sin(-1.56 +i *Split*Math.PI/180)
			with(this) document.getElementById("n6Digits"+i+num).style.left=Xpos-15+Xbase*Math.cos(-1.56 +i *Split*Math.PI/180)
		}
		for(i=0; i < this.S.length; i++) {
			with(this) document.getElementById("Nx"+i+num).style.top=Ypos+i*Ybase/4.1*Math.sin(sec);
			with(this) document.getElementById("Nx"+i+num).style.left=Xpos+i*Xbase/4.1*Math.cos(sec);
		}
		for(i=0; i < this.M.length; i++) {
			with(this) document.getElementById("Ny"+i+num).style.top=Ypos+i*Ybase/4.1*Math.sin(min);
			with(this) document.getElementById("Ny"+i+num).style.left=Xpos+i*Xbase/4.1*Math.cos(min);
		}
		for(i=0; i < this.H.length; i++) {
			with(this) document.getElementById("Nz"+i+num).style.top=Ypos+i*Ybase/4.1*Math.sin(hrs);
			with(this) document.getElementById("Nz"+i+num).style.left=Xpos+i*Xbase/4.1*Math.cos(hrs);
		}
	}
	
	window.setTimeout('this.clock', 500);
}

test.prototype.clock=clock;

clock1=new test(1);
clock2=new test(2);
clock3=new test(3);
clock4=new test(4);


clock1.clock(1, +1);
clock2.clock(2, -5);
clock3.clock(3, +0);
clock4.clock(4, -1);


Je suis débutant complet avec les classes en JavaScript mais là tout fonctionne sauf le rafraîchissement des horloges, ce qui m'amène à venir demander votre aide.

Spartakis
Modifié par Spartakis (25 Nov 2006 - 13:17)
Bonjour,

SetTimeout permet d'éxécuter une instruction (d'appeler une fonction ou une méthode dans ton cas) après un certain temps, tu pourra trouver un exemple et des explications sur SELFHTML.org.
Modifié par Neovov (24 Nov 2006 - 11:25)
Je sais à quoi sert setTimeout() et j'arrive à l'utiliser avec une simple fonction. Mais là je sèche lorsque cette même fonction que j'appelle se retrouve dans une classe ...

PS: ayant fait pas mal de modifications "test" sur le code, il se peut qu'il y ait des erreurs "débiles" Smiley langue
Non ça ne fonctionne pas non plus ... En tout cas, je sais que mon écriture fonctionne pour une fonction ne se trouvant pas dans un classe.
Oui, au temps pour moi, il faut écrire quelque chose comme ça :
function test(valeur) {
	this.valeur = valeur;
	setTimeout(createClockFunct(this), 500);
}

function clock() {
	alert(this.valeur);
}

test.prototype.clock = clock;

function createClockFunct(test) {
	return function() {test.clock();};
}

new test(2);
GeorgesM : je ne sais pas si je réponds à ta question, mais setTimeout accepte aussi comme premier paramètre une fonction.
Après une petite modification de ton code, cela semblerait pouvoir résoudre mon problème ! Il ne me reste plus qu'à l'appliquer à mon code ... Je reviendrai quand j'aurais avancé un peu.

Merci.
Modifié par Spartakis (24 Nov 2006 - 14:36)
L'attente n'aura pas été longue ...

Donc voici la modification effectuée sur ton code Eldebaran :

function test(valeur) {
	this.valeur = valeur;
	setTimeout(createClockFunct(this), 500);
}



function clock(num) {
	var x=this;
	x.num = num;
	
	/*document.write('<div id="n6Digits'+x.num+'" style="position:absolute;top:0px;left:0px;width:30px;height:30px;font-family:Arial;font-size:10px;color:#000;text-align:center;padding-top:10px">coucou</div>');*/
	alert(x.valeur+x.num);
	setTimeout(createClockFunct(x), 500);
}

test.prototype.clock = clock;

function createClockFunct(test) {
	return function() {test.clock(3);};
}

new test(2);


Ca marche parfaitement mais lorsque je décommente la ligne avec le document.write, ça me fait buggé le code Smiley sweatdrop
Voici l'erreur renvoyé par le débugger Js de FireFox :
Erreur : createClockFunct is not defined
Fichier source : file:///C:/Documents%20and%20Settings/Spartakis/Mes%20documents/Mes%20images/wallpaper/test.html
Ligne : 16

La ligne 16 étant celle se trouvant dans la fonction clock.
Je pense que le problème vient du fait d'utiliser document.write. Le but de cette fonction est d'ajouter du contenu dynamique au moment de la création de la page.

Dans ton cas, il vaut mieux utiliser DOM, et à la limite innerHTML.
C'est bon j'ai résolu mon problème. Merci encore à tous.

Voici le code si cela peut intéresser quelqu'un :
<html>
<head></head>
<body background="./wallpaper-vista-inspirat.png">
<script>

function test(num,fuseau,pays) {


	//Variables à modifier :
	this.fuseau 	= fuseau;
	this.num 		= num;
	this.pays		= pays;

	//Les couleurs :
	this.fCol		= '7777BB'; //couleur des chiffres.
	this.sCol		= '9999FF'; //couleur des secondes.
	this.mCol		= '666699'; //couleur des minutes.
	this.hCol		= '000066'; //couleur des heures.	 

	//position en absolut :
	this.Xoff		= 100*(num-0.5);  //à gauche
	this.Yoff		= 640; //en haut

	//taille
	this.Ybase		= 34; //hauteur
	this.Xbase		= 34; //largeur

	


	//ne pas modifier ci-après :
	this.H			= '...';
	this.H			= this.H.split('');
	this.M			= '....';
	this.M			= this.M.split('');
	this.S			= '.....';
	this.S			= this.S.split('');

	this.NS4		= (document.layers);
	this.NS6		= (document.getElementById && !document.all);
	this.IE4		= (document.all);

	this.Ypos		= 0;
	this.Xpos		= 0;
	this.dots		= 12;
	this.Split		= 360/this.dots;

	if(this.NS6 || this.IE4) {
		with(this) document.write('<div id="ampm'+pays+'" style="position:absolute;top:0px;left:0px;font-size:24px;color: #d0d0d0;font-weight: bold"></div>');
		for(i=1; i < this.dots+1; i++) {
			with(this) document.write('<div id="n6Digits'+i+num+'" style="position:absolute;top:0px;left:0px;width:30px;height:30px;font-family:Arial;font-size:10px;color:#'+fCol+';text-align:center;padding-top:10px">'+i+'</div>');
		}
		for(i=0; i < this.M.length; i++) {
			with(this) document.write('<div id="Ny'+i+num+'" style="position:absolute;top:0px;left:0px;width:2px;height:2px;font-size:2px;background:#'+mCol+'"></div>');
		}
		for(i=0; i < this.H.length; i++) {
			with(this) document.write('<div id="Nz'+i+num+'" style="position:absolute;top:0px;left:0px;width:2px;height:2px;font-size:2px;background:#'+hCol+'"></div>');
		}
		for(i=0; i < this.S.length; i++) {
			with(this) document.write('<div id="Nx'+i+num+'" style="position:absolute;top:0px;left:0px;width:2px;height:2px;font-size:2px;background:#'+sCol+'"></div>');
		}
		with(this) document.write('<div id="'+pays+'" style="position:absolute;top:0px;left:0px;font-size:11px;font-weight: bold;color: #666">'+pays+'</div>');
	}
	setTimeout(createClockFunct(this), 0);
}

function clock(num, fuseau, Xoff, Yoff, Xbase, Ybase, Split, dots, S, M, H, pays) {
	
	time = new Date ();
	secs = time.getSeconds();
	sec = -1.57 + Math.PI * secs/30;
	mins = time.getMinutes();
	min = -1.57 + Math.PI * mins/30;
	hr = time.getHours();
	hr = hr+fuseau-1;//on enlève 1 parce que le PC est à l'heure GMT+1
	hrs = -1.57 + Math.PI * hr/6 + Math.PI*parseInt(time.getMinutes())/360;
	
	ampm = ((hr%24)+1>12) ? "PM" : "AM";

	if(this.NS6 || this.IE4) {
		Ypos=Yoff;
		Xpos=Xoff;
		
		Xpos = Xpos+400;
		
		for(i=1; i < dots+1; i++) {
			document.getElementById("n6Digits"+i+num).style.top		= Ypos-15+Ybase*Math.sin(-1.56 +i *Split*Math.PI/180)
			document.getElementById("n6Digits"+i+num).style.left	= Xpos-15+Xbase*Math.cos(-1.56 +i *Split*Math.PI/180)
		}
		for(i=0; i < S.length; i++) {
			document.getElementById("Nx"+i+num).style.top	= Ypos+i*Ybase/4.1*Math.sin(sec);
			document.getElementById("Nx"+i+num).style.left	= Xpos+i*Xbase/4.1*Math.cos(sec);
		}
		for(i=0; i < M.length; i++) {
			document.getElementById("Ny"+i+num).style.top	= Ypos+i*Ybase/4.1*Math.sin(min);
			document.getElementById("Ny"+i+num).style.left	= Xpos+i*Xbase/4.1*Math.cos(min);
		}
		for(i=0; i < H.length; i++) {
			document.getElementById("Nz"+i+num).style.top	= Ypos+i*Ybase/4.1*Math.sin(hrs);
			document.getElementById("Nz"+i+num).style.left	= Xpos+i*Xbase/4.1*Math.cos(hrs);
		}
		document.getElementById(pays).style.top		= Ypos+47;
		document.getElementById(pays).style.left 	= Xpos-(5*pays.length/2);
		
		document.getElementById("ampm"+pays).style.top 	= Ypos-12;
		document.getElementById("ampm"+pays).style.left	= Xpos-(18*ampm.length/2);
		document.getElementById("ampm"+pays).innerHTML 	= ampm;
	}
	setTimeout(createClockFunct(this), 500);
}

test.prototype.clock=clock;

function createClockFunct(test) {
	return function() {test.clock(test.num, test.fuseau, test.Xoff, test.Yoff, test.Xbase, test.Ybase, test.Split, test.dots, test.S, test.M, test.H, test.pays);};
}

clock1=new test(1, +1, "Paris, France");
clock2=new test(2, +9, "Tokyo, Japan");
clock3=new test(3, -7, "Irvine, USA");
clock4=new test(4, +0, "Londres, UK");
clock2=new test(5, +9, "Seoul, South Korea");

</script>
</body>

Il y a encore un peu de bidouille sur ce code mais le principe est bien là. Je pense que j'aurais quelques variables à mettre en global pour délester le tube de la méthode clock() Smiley langue
Hello,

J'ai quelques remarques par rapport à ton code.

- Es-tu vraiment obligé d'appliquer un comportement différent selon les navigateurs ? Cette technique est connue pour être peu fiable et peu durable.
- As-tu vraiment besoin des "with(this)" ? La plupart des développeurs expérimentés déconseillent l'utilisation de cette fonctionnalité. Elle est lente, et dangereuse : quand tu écris
with(this) document.write('<div id="Nz'+i+num+"...");
Si dans le futur tu ajoutes une propriété "i" à ton objet, c'est elle qui sera prise en compte ici. De plus, si tu enlèves la propriété "num", l'interpréteur Javascript ira la chercher dans les portées supérieures, ce qui peut donner des résultats inattendus si tu as une variable globale qui s'appelle "num".
- Pourquoi écris-tu :
function createClockFunct(test) {
	return function() {test.clock(test.num, test.fuseau, test.Xoff, test.Yoff, test.Xbase, test.Ybase, test.Split, test.dots, test.S, test.M, test.H, test.pays);};
}
alors que la fonction clock aura justement accès aux propriétés de l'objet "test" à travers "this" ?
- Si ton problème est résolu, peux-tu s'il te plait éditer ton premier message, comme indiqué dans les règles du forum ?
Modifié par Eldebaran (25 Nov 2006 - 12:47)
Je ne savais pas pour tout ce que tu as dit ... Smiley confused mais ce code n'est qu'une reprise d'un code trouvé sur le net que je n'ai que transformé en classe.
Je vais donc enlever le "with(this)" et mettre les "this" où il faut.
Pour le comportement suivant les navigateurs, je comptais l'enlever parce qu'il est totalement inutile.
Sinon pour la dernière remarque, c'était pour être sur que le code marchait bien et cela faisait bien sûr parti des petites bidouilles que je pensais enlever Smiley ravi