[javascript] problème de récursivité

problème de récursivité [javascript] - HTML/CSS - Programmation

Marsh Posté le 02-07-2007 à 13:37:31    

Bonjour,
 
j'ai créé une petite classe en javascript (rien de bien méchant ;) ),
voila une partie du code

Code :
  1. initslideshow function (var1,var2,var3,var4){
  2.   this.var1 = var1
  3.   this.var2 = var2
  4.   this.var3 = var3
  5.   this.var4 = var4
  6.   //extrait du code pour donner une idée, je posterais plus tard la version complete
  7. }
  8. initslideshow.prototype.runslideshow = function (){
  9.   document.image[this.var1].src = thispic[this.i].src
  10.   if (++this.i > this.p) {this.i = 0}
  11.   settimeout('runslideshow ',this.var4) //fonction non trouvé !!
  12. }


j'ai une erreur sous firefox dans la console d'erreur qui me dit que la fonction n'est pas trouvé !
je ne sais pas comment faire pour appeller récursivement la même fonction en gardant les parametres de celle-ci bien sur.
 
en faite suivant les pages, je pourrais être amené à instencier plusieurs fois cet classe avec des parametres différents !


---------------
Tout à commencé par un rêve...
Reply

Marsh Posté le 02-07-2007 à 13:37:31   

Reply

Marsh Posté le 02-07-2007 à 14:26:34    

normal, runslideshow n'est pas une fonction mais une méthode de ta classe initslideshow ( je trouve les noms particulierement mal choisis :o ).
Attention, en utilisant un settimeout tu vas sortir du contexte de ton objet, tu ne pourras donc pas utiliser this.runslideshow.
 
Mais bon, comme j'ai pas la moindre idée de ce que tu veux faire, je trouve que ça sent un peu le paté ton truc.

Reply

Marsh Posté le 02-07-2007 à 14:50:36    

c'est juste pour faire défiller plusieurs banniere publicitaire sur une page
avec des vitesse différentes.
 
en ce qui concerne le choix des fonction ou methode, rien de bien grave pour l'instant ;)
 
si tu as mieux, je suis preneur !


Message édité par stef_dobermann le 02-07-2007 à 14:55:32

---------------
Tout à commencé par un rêve...
Reply

Marsh Posté le 02-07-2007 à 15:27:00    

tu peux montrer tout le code utilisé par ton truc.?

Reply

Marsh Posté le 02-07-2007 à 16:03:08    

pas pour l'instant, je suis au boulot, j'ai pas les sources
mais il n'y en a pas plus pour la partie javascript.
 
il y a juste une image (pour les testes) avec un nom, le nom de l'image est  var1 (premier argument de la classe initslideshow)


---------------
Tout à commencé par un rêve...
Reply

Marsh Posté le 02-07-2007 à 17:43:44    

nan mais là c'est totalement n'importe quoi ce que tu as écrit.
var2, var3 sont initules mais par contre tu te sers de this.i et this.p qui sont pas initialisées, thispic sort de l'espace donc ça mène forcément à rien ...
Donc montre le vrai code ...
edit: mais à l'instinct je ferais quelque chose dans le genre:

Code :
  1. function slideshow(var1, var2, var3, var4){
  2.   this.var1 = var1;
  3.   this.var2 = var2;
  4.   this.var3 = var3;
  5.   this.var4 = var 4;
  6. }
  7. slideshow.prototype.run = function(){
  8.       document.image[this.var1].src = thispic[this.i].src
  9.       if (++this.i > this.p) {
  10.         this.i = 0;
  11.       }
  12. }
  13. ...
  14. window.onload = function (){
  15. var pouet = new slideshow(...);
  16. setInterval('pouet.run', pouet.var4);
  17. }


non testé et garanti avec des erreurs!


Message édité par anapajari le 02-07-2007 à 17:48:17
Reply

Marsh Posté le 03-07-2007 à 12:15:30    

merci pour ce code, il me parrait correct, je teste ca dès que possible, je te mettrais quand meme le code que j'utilisais !


---------------
Tout à commencé par un rêve...
Reply

Marsh Posté le 03-07-2007 à 12:49:18    

anapajari a écrit :

normal, runslideshow n'est pas une fonction mais une méthode de ta classe initslideshow ( je trouve les noms particulierement mal choisis :o ).
Attention, en utilisant un settimeout tu vas sortir du contexte de ton objet, tu ne pourras donc pas utiliser this.runslideshow.
 
Mais bon, comme j'ai pas la moindre idée de ce que tu veux faire, je trouve que ça sent un peu le paté ton truc.


 
Restons précis,  on parle de prototype,  pas de classe...   :D

Reply

Marsh Posté le 03-07-2007 à 13:51:28    

Reply

Marsh Posté le 03-07-2007 à 14:22:32    


 
Meeeuuuuuh   non.  Juste précis    :lol:

Reply

Marsh Posté le 03-07-2007 à 14:22:32   

Reply

Marsh Posté le 03-07-2007 à 14:36:43    

Voici le script que l'on m'a fournit pour faire ça,
la seul chose est que la personne fait une duplication compléte du script en changeant le nom des variables pour faire tourner 2 ou 3 bannières différentes :

Code :
  1. // Set slideShowSpeed (milliseconds)
  2. var slideShowSpeed = 4000
  3. // Duration of crossfade (seconds)
  4. var crossFadeDuration = 20
  5. // Specify the image files
  6. var Pic = new Array() // don't touch this
  7. // to add more images, just continue
  8. // the pattern, adding to the array below
  9. Pic[0] = '../images/graph/bann/bann1.jpg'
  10. Pic[1] = '../images/graph/bann/bann2.jpg'
  11. // =======================================
  12. // Ne rien éditer au-dessous de cette ligne
  13. // =======================================
  14. var t
  15. var j = 0
  16. var p = Pic.length
  17. var preLoad = new Array()
  18. for (i = 0; i < p; i++){
  19. preLoad[i] = new Image()
  20. preLoad[i].src = Pic[i]
  21. }
  22. function runSlideShow(){
  23. if (document.all){
  24. document.images.SlideShow.style.filter="blendTrans(duration="+crossFadeDuration+" )"
  25. document.images.SlideShow.filters.blendTrans.Apply()
  26. }
  27. document.images.SlideShow.src = preLoad[j].src
  28. if (document.all){
  29. document.images.SlideShow.filters.blendTrans.Play()
  30. }
  31. j = j + 1
  32. if (j > (p-1)) j=0
  33. t = setTimeout('runSlideShow()', slideShowSpeed)
  34. }


 
Voici le code de mon script :

Code :
  1. </head>
  2. <script>
  3. function initslideshow(imguser,slideShowSpeed,crossFadeDuration,Pic) {
  4. // le constructeur
  5. // propriété publique
  6. this.imguser = imguser
  7. this.slideShowSpeed = slideShowSpeed;
  8. this.crossFadeDuration = crossFadeDuration;
  9. this.Pic = Pic;
  10. this.j = 0
  11. this.preLoad = new Array()
  12. for (this.j = 0; this.j < this.Pic.length; this.j++){
  13.  this.preLoad[this.j] = new Image()
  14.  this.preLoad[this.j].src = this.Pic[this.j]
  15. }
  16. this.j=0
  17. }
  18. initslideshow.prototype.runslideshow = function(){
  19.  if (document.all){
  20.   document.images[this.imguser].style.filter="blendTrans(duration="+this.crossFadeDuration+" )"
  21.   document.images[this.imguser].filters.blendTrans.Apply()
  22.  }
  23.  document.images[this.imguser].src = this.preLoad[this.j].src
  24.  if (document.all){
  25.   document.images[this.imguser].filters.blendTrans.Play()
  26.  }
  27.  if (++this.j > this.p) this.j=0
  28.  alert(this.imguser+'","'+this.j+'","'+this.preLoad+'","'+this.p+'","'+this.crossFadeDuration)
  29.  setTimeout('initslideshow.prototype.runslideshow()', this.slideShowSpeed)
  30. }
  31. </script>
  32. <body>
  33. <p><img src="../img/ban/ASDF50ER34_1000.gif" name='SlideShow' width="600" height="75"></p>
  34. <p><img src="../img/ban/SFDF50ER34_1000.gif" name='SlideShow2' width="600" height="75"></p>
  35. <script language="javascript">
  36. //pour faire une banniere qui tourne toute les 2 secondes
  37. Pic = new Array('../img/ban/ASDF50ER34_1000.gif','../img/ban/SFDF50ER34_1000.gif');
  38. var obj = new initslideshow ('SlideShow',"2000","20",Pic);
  39. obj.runslideshow();
  40. //pour faire une banniere qui tourne toute les 4 secondes
  41. Pic = new Array('../img/ban/ERDF50ER34_1000.gif','../img/ban/DRTDF50ER34_1000.gif');
  42. var obj2 = new initslideshow ('SlideShow2',"4000","20",Pic);
  43. obj2.runslideshow();
  44. </script>
  45. </body>


Message édité par stef_dobermann le 03-07-2007 à 14:37:52

---------------
Tout à commencé par un rêve...
Reply

Marsh Posté le 04-07-2007 à 13:05:51    

Dans ton setTimeout,  change  initslideshow.prototype.runslideshow()  par   obj.runslideshow()  (ou obj2 selon la banière que tu veux utiliser).
Dans le corps de ton <body> tu crées les variables obj et obj2.  C'est elles que tu dois utiliser pour faire référence aux objets (et pour les puristes  ;),  obj et obj2 contiennent bien une référence).
 
!!!!!!!     Les   ;   manquent presque partout   !!!!!!!!!!  A corriger.

Reply

Marsh Posté le 04-07-2007 à 14:54:34    

merci pour l'info !


---------------
Tout à commencé par un rêve...
Reply

Marsh Posté le 04-07-2007 à 15:07:51    

marchera pas :o voir ma 1ere reponse.
Dans runslideshow tu es sur une méthode de ton objet, celui-ci est donc représenté par this et non par le nom de la variable y faisant référence. Pour faire ce que suggère bignose, il te faudrait connaitre le "nom" de la variable faisant référence à ton objet dans la méthode.
Perso je ferais le setTimeOut hors de runslideshow.

Code :
  1. initslideshow.prototype.runslideshow = function(){
  2.             if (document.all){
  3.                 document.images[this.imguser].style.filter="blendTrans(duration="+this.crossFadeDuration+" )"
  4.                 document.images[this.imguser].filters.blendTrans.Apply()
  5.             }
  6.             document.images[this.imguser].src = this.preLoad[this.j].src
  7.            
  8.             if (document.all){
  9.                 document.images[this.imguser].filters.blendTrans.Play()
  10.             }
  11.             if (++this.j > this.p) this.j=0
  12.             alert(this.imguser+'","'+this.j+'","'+this.preLoad+'","'+this.p+'","'+this.crossFadeDuration)
  13.            
  14.     }
  15. ...
  16. var obj = new initslideshow ('SlideShow',"2000","20",Pic);
  17. setInterval(obj.runslideshow(), obj..slideShowSpeed);

Reply

Marsh Posté le 04-07-2007 à 15:27:36    

Le script mis précédemment est le code de base, comme dit dans les précédent post,"je suis à mon travail, je ne peux vous fournir le code initiale... " voila qui est fait :)
 
en ce qui concerne le code ci-dessus, il ne fonctionne qu'une fois !
l'image change bien au bout de 2 secondes, mais c'est tout !!
le script n'a pas l'air de continuer, aucune erreur dans la console javascript de firefox !


---------------
Tout à commencé par un rêve...
Reply

Marsh Posté le 04-07-2007 à 15:33:27    

euh tu as bien mis setInterval comme moi ou, par le plus grand des hasards, tu ne l'aurais pas remplacer par un setTimeOut


Message édité par anapajari le 04-07-2007 à 15:33:42
Reply

Marsh Posté le 04-07-2007 à 15:39:12    

oups !


---------------
Tout à commencé par un rêve...
Reply

Marsh Posté le 04-07-2007 à 15:42:02    

tiens j'ai cette erreur qui apprait à chaque fois que le script est exécuté :

Code :
  1. Erreur : this.preLoad[this.j] has no properties
  2. Fichier source : http://localhost/banniere/src/Banmultiple.htm
  3. Ligne : 28


 
c'est cette ligne :

Code :
  1. document.images[this.imguser].src = this.preLoad[this.j].src


je ne comprend pas pourquoi :?:
 
mais sinon l'image change :D
 
merci anapajari
 
je part bosser, à plus tard :)


Message édité par stef_dobermann le 04-07-2007 à 15:43:00

---------------
Tout à commencé par un rêve...
Reply

Marsh Posté le 04-07-2007 à 20:58:30    

anapajari a écrit :

marchera pas :o voir ma 1ere reponse.
Dans runslideshow tu es sur une méthode de ton objet, celui-ci est donc représenté par this et non par le nom de la variable y faisant référence. Pour faire ce que suggère bignose, il te faudrait connaitre le "nom" de la variable faisant référence à ton objet dans la méthode.
[/code]


 
Seulement voila,  des applications utilisant cette méthode pour faire tourner des dizaines d'objets de façon asynchrone dans un browser j'en ai déja fait pas mal...  Alors je reconnais que c'est pas la méthode qu'on utiliserait avec des langages comme c++, c# ou java,  mais ici on est en javascript et dans un browser.  Il faut donc utiliser ce qu'on a sous la main.
 
Comme je l'ai déja dit dans un post précédent,  en javascript tout ce qu'i n'est pas défini dans une fonction quelle qu'elle soit via le mot clé var est défini dans l'objet intrinsèque Global.  Dès lors, et par conséquent,  ceci fonctionne :
 
function  truc()
{...}
 
function truc.prototype.run()
{...
 
   setTimeout(A.run(), 1000);
...
}
 
 
var  A = new truc();
 
 
Pourquoi ?
 
Parce que A est défini en dehors de toute fonction.  Elle est donc créée dans l'objet Global.  En utilisant setTimeout(A.run(), 1000),  on s'adresse à la variable A définie dans l'objet Global (évidement,  si on a défini une variable locale A,  ça marchera pas).  L'objet Global est unique tant qu'on ne ferme pas le browser.  Tout ceci n'est qu'une propriété du langage javascript,  rien de plus.  Et c'est aussi une des ses faiblesses,  car quand les gens ne déclarent pas leurs variables dans leurs fonctions via le mot clé var,  ils ne se rendent souvent pas compte que ces variables se retrouvent toutes dans l'objet Global,  avec tous les problèmes de collisions et de débugage que ça implique.  
 
Encore une fois,  je le répète (qu'on vienne pas me relancer là-dessue)  c'est juste exploiter une propriété du javascript (qui est en fait simplement un moyen de faire du multi-thread),  avec d'autres langages on fera évidement autrement.
 
Alors on dira,  quel bordel !  Comment déguger un truc comme ça ?   Et je répondrai :  en ayant de bonnes habitudes de programmation,  en appliquant des best practices de qualité,  ça ne pose aucun problème.  Les gens n'ayant aucune discipline de programmation auront de toute façon des problèmes,  avec cette méthode ou avec une autre.  Le code présenté ici par stef_doberman n'est en aucun cas de qualité suffisante pour pouvoir utiliser cette méthodologie efficacement,  loin s'en faut.  Mais le cas étant simple,  ça ne pose pas de problème.
 
En tout cas,  je déconseille totalement l'utilisation de setInterval,  sauf à ceux à qui il reste encore quelques cheveux à s'arracher.  Car là c'est vraiment indébugable (et je parle par expérience malheureusement).

Reply

Marsh Posté le 04-07-2007 à 22:57:48    

Code :
  1. lala.prototype.run = function() {
  2.     // blah blah blah
  3.  
  4.     setTimeout(
  5.         function(obj) { return function() {obj.run();}; }(this)    
  6.     , 1000);
  7. }


Jmet pas la déco (et y'a d'autres manières de le faire), mais l'idée est là , on a aucunement besoin de saloper l'espace global pour faire ça [:spamafote]


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 05-07-2007 à 13:27:58    

bignose a écrit :


function  truc()
{...}
function truc.prototype.run()
{...

 

  setTimeout(A.run(), 1000);
...
}
var  A = new truc();


J'ai le droit de vomir?
En dehors de l'erreur sur la déclaration d'une méthode via prototype, ce que tu as écrit traduit une profonde incompréhension de la notion d'objet.
Cela cantonne l'utilisation du prototype "truc" au seul objet A.
Exemple:

Code :
  1. function truc( p ){
  2.   this.prop = p;
  3. }
  4. truc.prototype.run = function(){
  5.   alert(A.prop);
  6. }
  7. var A = new truc('toto');
  8. var B = new truc('tata');
  9. B.run(); // affiche toto


ça n'a strictement rien à voir avec utiliser "une propriété du langage javascript", c'est juste faire n'importe quoi [:spamafote].
Et ça va totalement à l'encontre de ce que tu écris ensuite:

bignose a écrit :

en ayant de bonnes habitudes de programmation,  en appliquant des best practices de qualité,  ça ne pose aucun problème.  Les gens n'ayant aucune discipline de programmation auront de toute façon des problèmes,  avec cette méthode ou avec une autre.


enfin:

bignose a écrit :

En tout cas,  je déconseille totalement l'utilisation de setInterval,  sauf à ceux à qui il reste encore quelques cheveux à s'arracher.  Car là c'est vraiment indébugable (et je parle par expérience malheureusement).


c'est vrai qu'il vaut mieux faire un méthode appelé via setInterval et dans cette méthode refaire un nouveau setInterval à chaque appel... totalement logique [:w3c compliant]


Message édité par anapajari le 05-07-2007 à 13:28:47
Reply

Marsh Posté le 05-07-2007 à 18:36:20    

sur ce coup, je suis d'accord avec anapajari


---------------
Tout à commencé par un rêve...
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed