IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Manipulation de tableau dans une boucle


Sujet :

JavaScript

  1. #1
    Membre expérimenté
    Avatar de yotta
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Septembre 2006
    Messages
    1 088
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 088
    Points : 1 540
    Points
    1 540
    Par défaut Manipulation de tableau dans une boucle
    Bonsoir,

    Je rencontre un problème de compréhension dans mon utilisation de Javascript et j'aurai bien besoin d'aide.
    Pour faire cours, j'ai besoin de créer un tableau d'objets contenant x instances de l'objet Image.
    Le paramètre fourni à mon script dans l'appel de sa fonction est un tableau de chaîne contenant x chaines de texte représentant les URL des images.
    J'ai donc commencé par créer un tableau d'objets, avec dans l'intention de le remplir par une simple boucle classique. Comme le code du dessin de l'image est un peu compliqué, j'ai procédé hors boucle, en travaillant avec un tableau de longueur 1.
    J'ai mis au point le code suivant pour m'assurer de bien contrôler tous les paramètres du dessin en étendant se remplissage manuel avec une seconde image :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    	ImagesLogos[0] = new Image();
    	ImagesLogos[0].src = logos[0];
    	ImagesLogos[0].onload = function() { ctx2.drawImage(ImagesLogos[0], positions[0] + Math.round((positions[0+1]-positions[0])/2) - Math.round(parseInt(dims[0].split(":")[0])/2), yh, parseInt(dims[0].split(":")[0]), parseInt(dims[0].split(":")[1]));}
    	ImagesLogos[1] = new Image();
    	ImagesLogos[1].src = logos[1];
    	ImagesLogos[1].onload = function() { ctx2.drawImage(ImagesLogos[1], positions[1] + Math.round((positions[1+1]-positions[1])/2) - Math.round(parseInt(dims[1].split(":")[0])/2), yb, parseInt(dims[1].split(":")[0]), parseInt(dims[1].split(":")[1]));}
    Le tableau d'objets ImagesLogos est instancié en début de code comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var ImagesLogos = new Array(logos.length);
    Le tableau dims n'est autre qu'un tableau de chaînes contenant les dimensions de chaque image sous la forme "largeur:hauteur" fourni par le paramètre 'dims' de la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function experience(dates, largeur, logos, dims) {...
    Tout le tableau logos qui lui contient des chaînes représentant les URL des images. Ces tableaux sont tous de même longueur.
    Le code ci-dessus fonctionne parfaitement bien.
    Cependant, si j'essaie de le conditionner sous forme de boucle ça ne fonctionne plus ???
    Voilà le code produit sous forme de boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	for (var i = 0 ; i < 2 ; i++) {
    		ImagesLogos[i] = new Image();
    		ImagesLogos[i].src = logos[i];
    		ImagesLogos[i].onload = function() { ctx2.drawImage(ImagesLogos[i], positions[i] + Math.round((positions[i+1]-positions[i])/2) - Math.round(parseInt(dims[i].split(":")[0])/2), yb, parseInt(dims[i].split(":")[0]), parseInt(dims[i].split(":")[1]));}
    		}
    Je n'arrive pas à comprendre pourquoi ???
    Quelqu'un pourrait-il maider ?
    Merci..

  2. #2
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut
    C'est le problème classique d'asynchronisme. Les images mettent un peu de temps à se charger, le temps de faire la requête réseau / l'interprétation etc...

    Du coup au moment où ta première image est chargée, la boucle for s'est déjà été exécutée pour toutes tes images et la variable i possède la dernière valeur occupée dans la boucle (dans ton exemple, c'est 2). Donc dans le code du onload, i vaut toujours 2 ce qui est la source de tes problèmes.

    Utiliser let au lieu de var pour déclarer la variable i permet de résoudre le problème mais c'est une norme assez récente qui n'est pas supportée par certains vieux navigateurs (tu l'auras compris, je parle d'Internet Explorer). Une solution compatible tout navigateur est de créer une nouvelle closure (fermeture en français). Si ce mot ne te dit rien, voilà un tuto vidéo: http://www.developpez.net/forums/d15...t-cours-video/. L'exemple qu'il donne à 12:00 correspond exactement à ton cas.

    Voilà une petite fonction utilitaire makeClosure pour t'aider :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    function makeClosure(fn){
      var args = [].slice.call(arguments, 1);
      return function(){
         return fn.apply(this, args.concat(arguments));
      }
    }
     
    function onloadImage(i){
      ctx2.drawImage(
        ImagesLogos[i],
        positions[i] + Math.round((positions[i+1]-positions[i])/2) - Math.round(parseInt(dims[i].split(":")[0])/2),
        yb, 
        parseInt(dims[i].split(":")[0]), 
        parseInt(dims[i].split(":")[1])
      );
    }
     
    for (var i = 0 ; i < 2 ; i++) {
      ImagesLogos[i] = new Image();
      ImagesLogos[i].src = logos[i];
      ImagesLogos[i].onload = makeClosure(onloadImage, i);
    }

  3. #3
    Membre expérimenté
    Avatar de yotta
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Septembre 2006
    Messages
    1 088
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 088
    Points : 1 540
    Points
    1 540
    Par défaut Un grand merci
    C'est pile poil la réponse qu'il me fallait.
    Comme j'utilise Firefox, je me suis contenté du 'let', mais j'ai regardé le tuto vidéo dont vous m'avez fourni le lien, et j'ai bien tout compris. Je ferai ça plus proprement quand je mettrai en ligne.
    Encore merci !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de taille de tableau
    Par Beush dans le forum C
    Réponses: 4
    Dernier message: 01/11/2005, 18h41
  2. Problème de taille de tableau
    Par k-nine dans le forum C
    Réponses: 6
    Dernier message: 25/09/2005, 10h16
  3. Problème d'initialisation variable tableau
    Par HeZiX dans le forum Langage
    Réponses: 3
    Dernier message: 08/06/2005, 17h30
  4. problème d'affectation de tableau ...
    Par Mike888 dans le forum C
    Réponses: 23
    Dernier message: 26/02/2005, 15h52
  5. Réponses: 4
    Dernier message: 20/08/2004, 11h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo