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

jQuery Discussion :

Boucle for avec setTimeout


Sujet :

jQuery

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de FCL31
    Profil pro
    Inscrit en
    Août 2007
    Messages
    887
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 887
    Par défaut Boucle for avec setTimeout
    Bonsoir

    Je développe un petit site web en local et j'ai un petit problème :

    Dans une balise <canvas>, en avec JQuery, j'affiche un histogramme.

    Je l'ai fait sans setTimeout et tout marche très bien

    Afin d'ajouter un effet, je voudrais ajouter setTimeout mais là, plus rien ne s'affiche

    voici mon code js :
    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
      function drawCanvas() {    var bebe = $("#bebe").html();
        var enfant = $("#enfant").html();
        var adulte = $("#adulte").html();
        var agee = $("#agee").html();
     
     
        var bebeText = $("#bebe_image").attr("alt");
        var enfantText = $("#enfant_image").attr("alt");
        var adulteText = $("#adulte_image").attr("alt");
        var ageeText = $("#agee_image").attr("alt");
     
     
        var canvas = document.getElementById("canvas");
        var contex = canvas.getContext("2d");
        contex.textAlign="center";
        contex.font="15px Arial";
     
     
        var dataText = [bebe, enfant, adulte, agee];
     
     
        bebe = bebe.substring(0,bebe.length-1);
        enfant = enfant.substring(0,enfant.length-1);
        adulte = adulte.substring(0,adulte.length-1);
        agee = agee.substring(0,agee.length-1);
     
     
        var dataNumber = [bebe, enfant, adulte, agee];
        var barColor = ['#efac55', '#45b0ca', '#92be6c', '#45b0ca']
        var absText = [bebeText, enfantText, adulteText, ageeText];
     
     
        var barWidth=40;
        var barSpace=100;
        var barUnit=5;
     
     
        var posX = 0;
        var posY = 0;
     
     
        for (var i = 0; i<dataNumber.length; i++){
     
     
          setTimeout(function() {
            barHeight = dataNumber[i] * barUnit;
            posX = i*barSpace + 60 + i*barWidth;
            posY = 400 - barHeight;
            contex.fillStyle = barColor[i];
            contex.fillRect(posX, posY - 30, barWidth, barHeight);
            contex.fillText(dataText[i], posX + 20, posY -40);
            contex.fillStyle = 'black';
            contex.fillText(absText[i], posX +20, 390);
          }, 1000);
     
     
        }
     
     
      }
    Si je supprime les lignes 45 et 54, sa marche mais sans l'effet "kiss cool"

    Les données sont récupérée dans des balises HTML (prévu de mettre dans un tableau)

    Merci d'avance pour votre aide.

  2. #2
    Membre extrêmement actif Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 532
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 532
    Par défaut
    Oki, explication :
    on va juste prendre les lignes
    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        for (var i = 0; i<dataNumber.length; i++){
          setTimeout(function() {
            barHeight = dataNumber[i] * barUnit;
    ...
          }, 1000);
        }

    on est bien d'accord , toutes les fonctions demandées dans ta boucle doivent s'exécuter au bout d'un délai de 1 seconde.
    donc,
    à l'échelle de l'horloge des microprocesseurs actuels, cela se passera après que la boucle for (var i = 0; i<dataNumber.length; i++){

    à la fin de cette boucle la valeur de i sera égale à dataNumber.length

    et c'est cette unique valeur finale i = dataNumber.length qui sera utilisée par toutes les fonctions que tu à généré dans ta boucle.

    ce qui est équivalent à

    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        for (var i = 0; i<dataNumber.length; i++){
          setTimeout(function() {
            barHeight = dataNumber[ dataNumber.length ] * barUnit;
    ...
          }, 1000);
        }

    tu peux le constater par toi même au travers d'un simple console.log
    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        for (var i = 0; i<dataNumber.length; i++){
          setTimeout(function() {
            console.log(" valeur de i = " + i);
            barHeight = dataNumber[ i ] * barUnit;
    ...
          }, 1000);
        }

    mais rassure toi, il y a différentes solution possibles, certaines dépendent du type et de la version du navigateur utilisé

  3. #3
    Membre éclairé Avatar de FCL31
    Profil pro
    Inscrit en
    Août 2007
    Messages
    887
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 887
    Par défaut
    Merci psychadelic

    EN fait, la boucle s'en fou de la du setTimeout et n’exécute pas le contenu de ce setTimeout mais fait la boucle quand même.

    Toutefois, il affiche le log et effectivement, i est toujours égal à dataNumber.leng dans le setTimeout.

    Mais pourquoi le log s'affiche et rien ne s’exécute ??

  4. #4
    Membre extrêmement actif Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 532
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 532
    Par défaut
    Citation Envoyé par FCL31 Voir le message
    Merci psychadelicMais pourquoi le log s'affiche et rien ne s’exécute ??
    parce que j'imagine que barHeight = dataNumber[ dataNumber.length ] * barUnit; retourne une valeur indéfinie et que cela affecte tous les calculs suivants, imposant à l'interpréteur un abandon pur et simple de l'exécution de cette fonction...

    Citation Envoyé par FCL31 Voir le message
    EN fait, la boucle s'en fou de la du setTimeout et n’exécute pas le contenu de ce setTimeout mais fait la boucle quand même.
    Oui, c'est le principe, la boucle génère N fonctions "privées" qui devront s'éxécuter plus tard dans leur coin, en attendant il continue sa boucle jusqu'a la fin, et donc en faisant varier la valeur de i jusqu'a ce que atteigne sa limite ( dataNumber.length ) et qui restera à cette valeur quand tes fonction privées devront être traitées par l'interpréteur.

  5. #5
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 521
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 521
    Par défaut
    bonjour,
    est ce que tu es sûr de cette ligne ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    barHeight = dataNumber[i] * barUnit;
    vu que dataNumber est un tableau qui porte des valeurs de type 'string', ce ne sont pas des chiffres.

  6. #6
    Membre éclairé Avatar de FCL31
    Profil pro
    Inscrit en
    Août 2007
    Messages
    887
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 887
    Par défaut
    Citation Envoyé par psychadelic Voir le message
    Oui, c'est le principe, la boucle génère N fonctions "privées" qui devront s'éxécuter plus tard dans leur coin, en attendant il continue sa boucle jusqu'a la fin, et donc en faisant varier la valeur de i jusqu'a ce que atteigne sa limite ( dataNumber.length ) et qui restera à cette valeur quand tes fonction privées devront être traitées par l'interpréteur.
    Une solution (ou au moins une pistes) pour pouvoir contourner ce problème ? STP

    Citation Envoyé par Toufik83 Voir le message
    est ce que tu es sûr de cette ligne ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    barHeight = dataNumber[i] * barUnit;
    Normalement, pas de problème avec cette lige. Le code fonctionne sans le setTimeout.

    Merci pour vos aide.

  7. #7
    Membre extrêmement actif Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 532
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 532
    Par défaut
    Citation Envoyé par FCL31 Voir le message
    Une solution (ou au moins une pistes) pour pouvoir contourner ce problème ? STP
    ben tout simplement passer par une vraie fonction !
    (et pourquoi vouloir à tout prix multiplier des une fonction identique)

    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function desinerBidule( noItem ) {
      barHeight = dataNumber[ noItem ] * barUnit;
      posX = noItem * barSpace + 60 + noItem * barWidth;
      posY = 400 - barHeight;
      contex.fillStyle = barColor[ noItem ];
      contex.fillRect(posX, posY - 30, barWidth, barHeight);
      contex.fillText(dataText[ noItem ], posX + 20, posY -40);
      contex.fillStyle = 'black';
      contex.fillText(absText[ noItem ], posX +20, 390);
    };

    et pour l'appeller :
    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for (var i = 0; i<dataNumber.length; i++) {
      setTimeout( desinerBidule, 1000, i);
    }

    reconnais que t'aime bien te compliquer la vie !

    mais comme mon petit doigt me dit que tu va implémenter ça de travers, je me suis permis de te refaire toute la fonction drawCanvas()
    Code JavaScript : 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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    function drawCanvas() {
     
      var
        bebe        = $("#bebe").html(),
        enfant      = $("#enfant").html(),
        adulte      = $("#adulte").html(),
        agee        = $("#agee").html(),
        bebeText    = $("#bebe_image").attr("alt"),
        enfantText  = $("#enfant_image").attr("alt"),
        adulteText  = $("#adulte_image").attr("alt"),
        ageeText    = $("#agee_image").attr("alt"),
        canvas      = document.getElementById("canvas"),
        contex      = canvas.getContext("2d")
      ;
     
      contex.textAlign = "center";
      contex.font      = "15px Arial";
     
      var dataText = [bebe, enfant, adulte, agee];
     
      bebe   = bebe.substring(0,bebe.length-1);
      enfant = enfant.substring(0,enfant.length-1);
      adulte = adulte.substring(0,adulte.length-1);
      agee   = agee.substring(0,agee.length-1);
     
      var
        dataNumber = [bebe, enfant, adulte, agee],
        barColor   = ['#efac55', '#45b0ca', '#92be6c', '#45b0ca'],
        absText    = [bebeText, enfantText, adulteText, ageeText],
        barWidth   = 40,
        barSpace   = 100,
        barUnit    = 5
      ;
     
      for (var i = 0; i < dataNumber.length; i++) {
        setTimeout( desinerBidule, (1000 +(i*250)), i);
      })
     
      function desinerBidule( noItem ) {
        var    
          barHeight = dataNumber[ noItem ] * barUnit,
          posX      = noItem * barSpace + 60 + noItem * barWidth,
          posY      = 400 - barHeight
        ;
        contex.fillStyle  = barColor[ noItem ];
     
        contex.fillRect(posX, posY - 30, barWidth, barHeight);
        contex.fillText(dataText[ noItem ], posX + 20, posY -40);
        contex.fillStyle = 'black';
        contex.fillText(absText[ noItem ], posX +20, 390);
      };
     
    }; //  drawCanvas()

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

Discussions similaires

  1. [VBA] Boucle "For" avec valeurs spécifiques
    Par NiKoTiNe dans le forum VBA Access
    Réponses: 13
    Dernier message: 28/03/2025, 09h10
  2. Boucle for avec saut
    Par michel71 dans le forum Delphi
    Réponses: 3
    Dernier message: 25/02/2007, 16h16
  3. boucle for avec condition
    Par Daniel Magron dans le forum Delphi
    Réponses: 4
    Dernier message: 22/01/2007, 16h18
  4. Réponses: 2
    Dernier message: 28/08/2006, 18h17
  5. [VB6] boucle for avec liste de valeur defini
    Par Morpheus2144 dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 06/04/2006, 18h12

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