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 :

Boucle toujours valeur de la dernière itération


Sujet :

JavaScript

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2007
    Messages : 211
    Points : 91
    Points
    91
    Par défaut Boucle toujours valeur de la dernière itération
    Bonjour à tous,

    J'ai un petit soucis dans une boucle . Un peu de code pour commencer :
    Code HTML : 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
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    <!DOCTYPE html><html lang="fr"><head>
    <meta charset="UTF-8">
    <title>Title  the document</title>
    </head>
    <body>
    <center>
    <img id="image" src="/dvbt/1000088321.pgm" alt="1000088321" onclick="selection(1000088321)"><br>
    <button onmouseover="changer_image(400,-15000)" onmouseout="MouseOut()">-10min</button>
    <button onmouseover="changer_image(400,-7500)" onmouseout="MouseOut()">-5min</button>
    <button onmouseover="changer_image(400,-1500)" onmouseout="MouseOut()">-1min</button>
    <button onmouseover="changer_image(400,-750)" onmouseout="MouseOut()">-30sec</button>
    <button onmouseover="changer_image(400,-375)" onmouseout="MouseOut()">-15sec</button>
    <button onmouseover="changer_image(400,-250)" onmouseout="MouseOut()">-10sec</button>
    <button onmouseover="changer_image(400,-125)" onmouseout="MouseOut()">-5sec</button>
    <button onmouseover="changer_image(400,-25)" onmouseout="MouseOut()">-1sec</button>
    <button onmouseover="changer_image(400,-1)" onmouseout="MouseOut()">-1frame</button>
    <button onmouseover="changer_image(40,-1)" onmouseout="MouseOut()">X-1</button>
    <button onmouseover="changer_image(40,1)" onmouseout="MouseOut()">X+1</button>
    <button onmouseover="changer_image(400,1)" onmouseout="MouseOut()">+1frame</button>
    <button onmouseover="changer_image(400,25)" onmouseout="MouseOut()">+1sec</button>
    <button onmouseover="changer_image(400,125)" onmouseout="MouseOut()">+5sec</button>
    <button onmouseover="changer_image(400,250)" onmouseout="MouseOut()">+10sec</button>
    <button onmouseover="changer_image(400,375)" onmouseout="MouseOut()">+15sec</button>
    <button onmouseover="changer_image(400,750)" onmouseout="MouseOut()">+30sec</button>
    <button onmouseover="changer_image(400,1500)" onmouseout="MouseOut()">+1min</button>
    <button onmouseover="changer_image(400,7500)" onmouseout="MouseOut()">+5min</button>
    <button onmouseover="changer_image(400,15000)" onmouseout="MouseOut()">+10min</button>
    <br>
    <img id="1" src="/dvbt/1000088314.pgm" alt="-7" width="5%" onclick="selection(1000088314)">
    <img id="2" src="/dvbt/1000088315.pgm" alt="-6" width="5%" onclick="selection(1000088315)">
    <img id="3" src="/dvbt/1000088316.pgm" alt="-5" width="5%" onclick="selection(1000088316)">
    <img id="4" src="/dvbt/1000088317.pgm" alt="-4" width="5%" onclick="selection(1000088317)">
    <img id="5" src="/dvbt/1000088318.pgm" alt="-3" width="5%" onclick="selection(1000088318)">
    <img id="6" src="/dvbt/1000088319.pgm" alt="-2" width="5%" onclick="selection(1000088319)">
    <img id="7" src="/dvbt/1000088320.pgm" alt="-1" width="5%" onclick="selection(1000088320)">
    <img id="8" src="/dvbt/1000088322.pgm" alt="1" width="5%" onclick="selection(1000088322)">
    <img id="9" src="/dvbt/1000088323.pgm" alt="2" width="5%" onclick="selection(1000088323)">
    <img id="10" src="/dvbt/1000088324.pgm" alt="3" width="5%" onclick="selection(1000088324)">
    <img id="11" src="/dvbt/1000088325.pgm" alt="4" width="5%" onclick="selection(1000088325)">
    <img id="12" src="/dvbt/1000088326.pgm" alt="5" width="5%" onclick="selection(1000088326)">
    <img id="13" src="/dvbt/1000088327.pgm" alt="6" width="5%" onclick="selection(1000088327)">
    <img id="14" src="/dvbt/1000088328.pgm" alt="7" width="5%" onclick="selection(1000088328)">
     
    <form action="index.php" method="post">
    <p>
        Début <input type="text" name="debut" id="debut">
    	Fin <input type="text" name="fin" id="fin">
    	Type <input type="text" name="type">
    	Description <input type="text" name="description">
        <input type="submit" value="Valider">
    </p>
    </form>
     
    </center>
    <script>
    var boucle;
    var a = "1";
     
    function changer_image(temps,nombre_image) {
    temps = Number(temps);
    boucle = setInterval(changer_image1, temps, nombre_image);
     
    }
     
    function changer_image1(nombre_image) { 
    var x = document.getElementById("image").alt;
    x = Number(x);
            var x = x + nombre_image;
            document.getElementById("image").alt = x;
            var str = x.toString();
            var fill = "000000000";
            str = fill.substr(str.length) + str;
            document.getElementById("image").src = "/dvbt/" + str + ".pgm";
            document.getElementById("image").onclick = function(){selection(str);};
            for (var iter = 1; iter < 15; iter++) {
                    var y = document.getElementById(iter).alt;
                    y = Number(y);
                    var z = x + y;
                    var strz = z.toString();
                    var fillz = "000000000";
                    strz = fill.substr(strz.length) + strz;
                    document.getElementById(iter).src = "/dvbt/" + strz + ".pgm";
                    document.getElementById(iter).onclick = function(){selection(strz);};
            }
    }
     
     
    function MouseOut() {
    clearInterval(boucle);
    }
     
    function selection(selec) {
            if (a == "1") { 
            document.getElementById("debut").value = selec; 
            a = "2";
            } else {
            document.getElementById("fin").value = selec; 
            a = "1";
            }
    }
    </script>
    </body></html>

    Mon problème se situe au niveau de la ligne 83
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    document.getElementById(iter).onclick = function(){selection(strz);};
    Le onclick est bien remplacé mais il prend la valeur de la dernière itération de la boucle.

    En exemple cela donne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <img id="12" src="/dvbt/1000088326.pgm" alt="5" width="5%" onclick="selection(1000088328)">
    <img id="13" src="/dvbt/1000088327.pgm" alt="6" width="5%" onclick="selection(1000088328)">
    <img id="14" src="/dvbt/1000088328.pgm" alt="7" width="5%" onclick="selection(1000088328)">
    Au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <img id="12" src="/dvbt/1000088326.pgm" alt="5" width="5%" onclick="selection(1000088326)">
    <img id="13" src="/dvbt/1000088327.pgm" alt="6" width="5%" onclick="selection(1000088327)">
    <img id="14" src="/dvbt/1000088328.pgm" alt="7" width="5%" onclick="selection(1000088328)">
    Je suis un peu perdu car j'ai +/- la même fonction à la ligne 82 qui fonctionne bien. Merci de votre aide.

  2. #2
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant perpétuel
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Points : 22 933
    Points
    22 933
    Billets dans le blog
    125
    Par défaut


    Faites un essai en remplaçant "var" par "let" : for (let iter = 1; iter < 15; iter++) {.

    Blog

    Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
    (Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)

  3. #3
    Invité
    Invité(e)
    Par défaut
    Faites un essai en remplaçant "var" par "let"
    je présume que c'est la fatigue de la soirée

    le pb que tu (sebaas) rencontre est résolu par la closure. Il y a plus de docs sur le net.

    qd ta fonction de callback est appelée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     function(){
     machin strz
    }
    elle cherche la valeur de strz, et strz du scope englobant (boucle for) vaut...la derniere valeur lors de l'itération dans la boucle __comme tu l'as bien constaté__
    en effet ta boucle a fini toutes ses itérations elle a _attaché_ ta fonction de callback 15 fois, mais ces callback n'ont jamais été appelées.
    qqsoit celle qui est appelée, elle cherchera la valeur de strz...cf ligne au dessus

    pr résoudre le pb plusieurs solutions

    1) le plus "straightforward" c'est de creer une closure


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    function fixmrz(mrz){
        var mrzFixé = mrz //inutile mais pour illustration
        return function originalCallback(){
            machin mrz
        }
    }
     
    machin.onclick = fixmrz(mrz)
    fixmrz est __appelée__ dans chaque itération
    la fonction originalCallback, attaché sur onclick, cherchera elle mrz dans son scope englobant, non plus for, mais celui fixmrz (ou mrz vaut cette fois... mrzFixé

    La manière habituellement rencontrée est

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    truc.onclick = (function(iMrz){
        return machin iMrz //tu peux appeler l'argument mrz je le change juste pour bien illustrer la différence, mais si tu l'appeles mrz il "surcharge" celui du scope encore englobant, la boucle for
    })(mrz)
    //ici on fait juste que appeler la fonction à la volée mais concept est exactement le même
    //on ecrit pas function(iMrz){}(mrz) parce que la syntaxe(expression) est pas valide alors on met des parenthèses...
    2) même concept, en "évitant" la boucle for

    si tu as le bénéfice davoir un _array_
    tu peux iterer sur alt via forEach, map,..que je te laisse découvrir


    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
     
     
    var mesElems = []
    for (var iter = 1; iter < 15; iter++) {
        ...
        var elementItere = [ iter, strz ]
        //les elemens sont directement pushés a chaque iteration dans mesElems
        //et donc ont tous des valeurs "differentes"
        mesElems.push( elementItere )
    }
     
    //forEach est une methode de Array, parcourt chacun de ses elem et à chaque elem appèle la fonction de cbk que tu as spécifié.
    //la différence __important__ est que elle appèle ta cbk à chaque "iteration" qu'elle fait
    mesElems.forEach(function(elementItere){
        var iter = elementItere[0]
        var strz = elementItere[1]
        getElementById(iter).onclick = function(){
            machin strz //ici tu vois que strz refere à elementItere
        }
    })
    au début tu écriras pblmt pas mal "solution1" puis nmlt avec le temps tu prends gout à forEach et le fait de ne te plus te préoccuper des boucles for

  4. #4
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 640
    Points : 66 669
    Points
    66 669
    Billets dans le blog
    1
    Par défaut
    Sujet maintes fois traité sur le forum devenu un classique...
    Un petit recherche dans le forum t'aurait apporté une solution avec this ...
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2007
    Messages : 211
    Points : 91
    Points
    91
    Par défaut
    Merci, je vais essayer cela ce soir.

    Citation Envoyé par SpaceFrog Voir le message
    Sujet maintes fois traité sur le forum devenu un classique...
    Un petit recherche dans le forum t'aurait apporté une solution avec this ...
    Et pourtant j'ai cherché ... mais diffice à trouver une réponse quand on n'arrive pas à nommer son problème :-)

  6. #6
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 640
    Points : 66 669
    Points
    66 669
    Billets dans le blog
    1
    Par défaut
    Dans ta boucle attribues l'indexe de la boucle a ton image :

    Je n'ai pas décortiqué ton code, donc il faudra adapter ... mais sur le principe de base :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.sel= "100008832"+i
    du coup ton onclick devient
    avec le sel attribué par js ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <img id="12" src="/dvbt/1000088326.pgm" alt="5" width="5%" sel="1000088328" onclick="selection(this.sel)">

    Autre chose... un id strictement numérique est déconseillé ...
    préfixe le d'un _
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  7. #7
    Invité
    Invité(e)
    Par défaut
    Faites un essai en remplaçant "var" par "let" : for (let iter = 1; iter < 15; iter++) {.
    je présume que c'est la fatigue de la soirée
    en fait non c'est clairement correct!
    tjs pensé (à tord) que let avait une durée de vie sur le scope mais pas à chaque itération

    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
     
    > var b = [];for(let i = 0; i <5; ++i){b.push(function(){console.log(i)})}
    5
    > b.forEach(x=>x())
    0
    1
    2
    3
    4
    undefined
    > var b = [];for(var i = 0; i <5; ++i){b.push(function(){console.log(i)})}
    5
    > b.forEach(x=>x())
    5
    5
    5
    5
    5

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2007
    Messages : 211
    Points : 91
    Points
    91
    Par défaut
    Effectivement, j'ai mis remplacé "var" par "let" partout dans la boucle et cela a fonctionné.
    Let a été ajouté avec ES16 (donc ne fonctionne pas avec certains anciens navigateurs)

  9. #9
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 742
    Points
    4 742
    Par défaut
    et j'imagine que tu as compris cette différence qui causait ton erreur de codage ?
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

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

Discussions similaires

  1. Get valeur toutes les X itérations dans une boucle
    Par Ced39300 dans le forum Général Python
    Réponses: 7
    Dernier message: 15/03/2016, 15h20
  2. Isoler la dernière itération d'une boucle foreach
    Par binco dans le forum Langage
    Réponses: 3
    Dernier message: 16/04/2015, 11h21
  3. [2.x] count symfony2 ma boucle n'affiche que la dernière valeur
    Par Medidev dans le forum Symfony
    Réponses: 1
    Dernier message: 31/03/2014, 17h33
  4. [JSTL] savoir si c'est la dernière itération d'une boucle foreach
    Par dearraed dans le forum Taglibs
    Réponses: 0
    Dernier message: 06/05/2010, 11h39
  5. [E-03] Boucle For Next jusqu'à la dernière valeur trouvée
    Par moilou2 dans le forum Macros et VBA Excel
    Réponses: 15
    Dernier message: 27/11/2008, 14h57

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