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 :

[DOM] Modification du DOM non visible lors d'un setInterval


Sujet :

JavaScript

  1. #1
    Expert éminent Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Points : 6 449
    Points
    6 449
    Par défaut [DOM] Modification du DOM non visible lors d'un setInterval


    J'ai une variable qui évolue dans le temps, lors d'un traitement lourd, et j'aimerai observer son contenu régulièrement...

    J'ai codé le script suivant, mais j'ai un problème: mon champ texte (ou alors le innerHTML d'un div, peut importe) ne se met à jour qu'à la toute fin du traitement, ce qui ne répond pas vraiment au besoin initial
    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
    <html>
        <body>
            <script type="text/javascript">
            function go() {
                var value = 0;
                var content = document.getElementById('content');
                setInterval(function() {
                        content.value = value;
                }, 10);
                for(var i = 0 ; i <= 1000000 ; ++i) { 
                    Math.log(i)/Math.log(10);
                    value = i;
                }
            }
            </script>
            <input type="button" onclick="go()" value="Start:"/><input type="text" id="content" value="" />
        </body>
    </html>
    Est-ce que quelqu'un ici pourrait me dire ce qui ne va pas dans mon code ? Merci d'avance



  2. #2
    Expert éminent sénior

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    13 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2007
    Messages : 13 474
    Points : 36 571
    Points
    36 571
    Par défaut
    Bonjour,
    problème de portée de variables (locale, en l'occurence)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
                setInterval("document.getElementById('content') ='" + value +"'", 10);
    EDIT : il faut que "value" (mauvais nom pour une variable, d'ailleurs) soit évaluée à la constitution de l'instruction, et non à l'exécution (il n'aura alors plus la valeur attendue)

    A+

  3. #3
    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 644
    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 644
    Points : 66 671
    Points
    66 671
    Billets dans le blog
    1
    Par défaut
    heu à la lecture de ton code je ne comprends pas le "besoin initial" ...

    d'un coté tu mets une valeur dans l'objet ..
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      setInterval(function() {
                        content.value = value;
                }, 10);
    de l'autre là tu ne fais rien :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
                for(var i = 0 ; i <= 1000000 ; ++i) { 
                    Math.log(i)/Math.log(10);
                    value = i;
                }
    enfin c'est juste une boucle indépendante du setInterval ...

    en plus appeler une variable value ... :rolleyes:

    Quel est le but recherché ?
    afficher un comptuer de 0 à 100000 dans un input ?

  4. #4
    Expert éminent Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Points : 6 449
    Points
    6 449
    Par défaut
    Citation Envoyé par E.Bzz Voir le message
    Bonjour,
    problème de portée de variables (locale, en l'occurence)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
                setInterval("document.getElementById('content') ='" + value +"'", 10);
    Désolé:
    1. je ne vois pas le problème de portée dans mon code.
    2. la suggestion proposée ne fonctionne pas mieux (c'est meme pire) et c'est normal car on perd dans ce cas l'aspect "dynamique"...

    Si tu testes mon code, à la fin de mon traitement il indique 1000000 alors qu'avec le code proposé, il indique 0 (pas bon)...

    Citation Envoyé par SpaceFrog Voir le message
    heu à la lecture de ton code je ne comprends pas le "besoin initial" ...
    J'ai un traitement assez long (d'où l'instruction qui ne fait rien mais qui bouffe un peu de perfs pour faire mes tests)
    J'aimerais pouvoir observer en direct live une variable qui évolue pendant ce traitement.

    Citation Envoyé par SpaceFrog Voir le message
    d'un coté tu mets une valeur dans l'objet ..
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      setInterval(function() {
                        content.value = value;
                }, 10);
    La callback a juste pour rôle de mettre à jour mon champ texte. Et ce toutes les 10, 250 ou 1024 millisecondes.

    Citation Envoyé par SpaceFrog Voir le message
    de l'autre là tu ne fais rien :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
                for(var i = 0 ; i <= 1000000 ; ++i) { 
                    Math.log(i)/Math.log(10);
                    value = i;
                }
    Si je fait quelque chose d'important:
    - je bouffe des ressources
    - je mets à jour ma variable

    Citation Envoyé par SpaceFrog Voir le message
    en plus appeler une variable value ... :rolleyes:
    Si ça peut vous faire plaisir
    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
     
    <html>
        <body>
            <script type="text/javascript">
            function go() {
                var toto = 0;
                var content = document.getElementById('content');
                setInterval(function() {
                        content.value = toto;
                }, 10);
                for(var i = 0 ; i <= 1000000 ; ++i) { 
                    Math.log(i)/Math.log(10);
                    toto = i;
                }
            }
            </script>
            <input type="button" onclick="go()" value="Start:"/><input type="text" id="content" value="" />
        </body>
    </html>

  5. #5
    Expert éminent sénior

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    13 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2007
    Messages : 13 474
    Points : 36 571
    Points
    36 571
    Par défaut
    Citation Envoyé par Mr N. Voir le message
    Désolé:
    1. je ne vois pas le problème de portée dans mon code.
    Je suppose que c'est l'essentiel

    Bon courage ...

  6. #6
    Expert éminent Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Points : 6 449
    Points
    6 449
    Par défaut
    "Je suppose..."
    Est-ce que tu joues aux devinettes ou est-ce que tu ne sais pas si il y a effectivement un problème de portée ?

  7. #7
    Rédacteur
    Avatar de marcha
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2003
    Messages
    1 571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Points : 2 351
    Points
    2 351
    Par défaut
    Salut,

    Non, il n'y a pas de problème de portée de variable, il y a une jolie closure tout a fait légale.

    le problème vient du fait que javascript n'est pas multithread, il n'exécute pas des fonctions en parallèle quand bien même elle serait définie en interne d'une autre.

    Le premier appel à la fonction anonyme définie dans setInterval se fera a la fin de l'exécution de la fonction principale.

    Je pense qu'il faut réarchitecturer ton code pour fragmenter le traitement. Qqch dans le genre

    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
     
    var pos;
     
     function go() {
         pos = 0;
         traitement();
     }
     
    function traitement() {
       var fin = pos + 100;
       for(var i = pos ; i < fin; ++i) { 
          Math.log(i)/Math.log(10);
       }
       pos = fin;
       document.getElementById('content').innerHTML = pos;
       if(pos<10000) setTimeout(traitement, 10);
    }

  8. #8
    Expert éminent Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Points : 6 449
    Points
    6 449
    Par défaut
    Merci Marcha pour ta suggestion. Et de confirmer au passage qu'il n'y a pas de problème de portée, je commençais à me poser des question

    J'ai bien pensé au setTimeout, mais le soucis est qu'il va introduire un délai dans mon traitement et le ralentir... Tu confirmes ? Je préfère mettre la priorité sur les perfs du traitement que de le ralentir pouir un simple affichage. Ce dernier n'étant qu'un "bonus"... Bonus qui ne fera qu'agrémenter l'interface utilisateur.

    Le premier appel à la fonction anonyme définie dans setInterval se fera à la fin de l'execution de la fonction principale
    Intéressant... et si je lancait mon traitement via un setTimeout et mon observation via un setInterval, est-ce que ça pourrait regler le problème ?

  9. #9
    Expert éminent Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Points : 6 449
    Points
    6 449
    Par défaut
    Citation Envoyé par Mr N. Voir le message
    et si je lancait mon traitement via un setTimeout et mon observation via un setInterval, est-ce que ça pourrait regler le problème ?
    La réponse est non

  10. #10
    Rédacteur
    Avatar de marcha
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2003
    Messages
    1 571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Points : 2 351
    Points
    2 351
    Par défaut
    Citation Envoyé par Mr N. Voir le message
    J'ai bien pensé au setTimeout, mais le soucis est qu'il va introduire un délai dans mon traitement et le ralentir... Tu confirmes ?
    Oui, mais négligeable à mon sens, tu peux afficher ta progression toutes les secondes et tu perds qq ms par secondes. donc moins de 1%, à toi de voir.

  11. #11
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    336
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 336
    Points : 374
    Points
    374
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
            function go() {
                var value = 0;
                var content = document.getElementById('content');
                for(var i = 0 ; i <= 1000 ; ++i) { 
                    Math.log(i)/Math.log(10);
    				setTimeout(function(nb) {
    					return function() {
    						content.value = nb
    					}
    				}(i),10*i);
                }
            }
    Ceci mets simplement le div à jour, par contre si tu veux observer la mise à jour lors d'un traitement lourd, cela va être difficile, du fait que javascript executera ta boucle en entier avant d'executer le code en dessous, donc l'affichage va bloquer.

Discussions similaires

  1. [OL-2003] contact ajouté non visible lors de l'écriture du mail
    Par zakuli dans le forum Outlook
    Réponses: 2
    Dernier message: 24/07/2009, 12h56
  2. [DOM] Modifer dynamiquement un formulaire
    Par mcdelay dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 21/06/2007, 12h20
  3. [DOM] Modification innerHTML impossible
    Par Christophe Charron dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 27/05/2007, 14h37
  4. [DOM] Modification du DOM d'une popup
    Par Mike_69 dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 28/03/2007, 14h28
  5. [DOM] modification d'un XML ?
    Par ghohm dans le forum Bibliothèques et frameworks
    Réponses: 15
    Dernier message: 13/07/2006, 16h31

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