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 :

Valeur du timeout différente suivant les navigateurs ?


Sujet :

JavaScript

  1. #1
    Membre à l'essai
    Inscrit en
    août 2009
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : août 2009
    Messages : 15
    Points : 11
    Points
    11
    Par défaut test des intervalles sur un setTimeout
    Salut à tous,

    (suis nouveau,, 2ème post sur ce fofo,, ^^)

    je viens juste vous faire part d'un étrange (mais hélas, ... peu surprenant) problème... de compatibilité de résultats entre firefox / IE... & demande votre avis/aide sur la question,,

    je m'explique,... la manip est la suivante :

    1) je lance un timer via un setTimeout en javascript... jusque là, rien de spécial,

    echo " var timer=setTimeout(\"do_calc()\",100);";

    (bon, je le lance en php, okay... )

    2) le script va mettre à jour une valeur toutes les 100ms sec < okay, ça marche,,

    3) j'ouvre 2 navigateurs -> IE + firefox -> qui vont interroger le même script, approximativement dans la même seconde,

    & bien... figurez-vous qu'au bout d'un certains temps (voir 1 minute, ça suffit), il va y avoir un décalage de plusieurs secondes entre les 2 différents navigateurs !! IE va avoir tendance à afficher le résultat en retard (calcul lent?)

    problème connu ? existe-t-il un fix ?

    faut-t-il s'amuser à scripter/chronométrer la différence de calcul entre IE & FF pour utiliser la fonction setTimeout de manière "homogène"/crossbrowser-esque ??

    merci d'avance pour vos réponses, & vos lumières,
    Cdt,

    GBS63,,

  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 602
    Points
    36 602
    Par défaut
    Bonjour,
    le setTimeout() ne lance l'instruction qu'une seule fois.
    Tu as donc dû mettre en place une boucle ou un appel récursif, je suppose ...
    A mon avis l'écart vient du temps de traitement entre les appels au setTimeout() ...
    Pour vérifier (si 100 ms représente un temps différent pour les 2 nav), essaye de faire le même appel avec un setInterval(...,100).
    (sans boucle ou appel récursif, donc)

    A+
    Pour tout savoir sur l'utilisation du forum

    En postant votre message, n'oubliez pas les Règles du Club.

  3. #3
    Membre à l'essai
    Inscrit en
    août 2009
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : août 2009
    Messages : 15
    Points : 11
    Points
    11
    Par défaut
    merci pour la réponse,

    okay, je vais tenter avec setInterval... mais aux derniers essaies, quand j'avais tenté avec cette function, ça freezait le script sous IE & ff... ^^
    (mais je pense avoir compris pourquoi & trouvé un fix : http://alexle.net/archives/169

    & je vais tenter également de chronométrer l'affaire,,

  4. #4
    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 602
    Points
    36 602
    Par défaut
    Citation Envoyé par GBS63 Voir le message
    quand j'avais tenté avec cette function, ça freezait le script sous IE & ff... ^^
    Si ta fonction est un peu "lourde" et que tu l'appelles 10 fois par seconde, forcément .....

    J'ai vu le lien, mais jamais eu ce problème avec setInterval

    On peut voir la fonction do_calc() ?

    A+
    Pour tout savoir sur l'utilisation du forum

    En postant votre message, n'oubliez pas les Règles du Club.

  5. #5
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : juin 2008
    Messages : 23 647
    Points : 91 423
    Points
    91 423
    Billets dans le blog
    20
    Par défaut
    Une erreur "classique" consiste aussi à lancer le setInterval dans la fonction appelée à la fin du timer... ce qui a pour facheuse conséquence de multiplier les timers et d'exploser la mémoire.
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function do_something(){
        // code de la fonction
        setInterval(do_something, 100);
    }
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  6. #6
    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 602
    Points
    36 602
    Par défaut
    +1

    D'autant plus classique lorsqu'on modifie la fonction pour passer d'un appel récursif du setTimeout() à l'utilisation du setInterval() ...

    A+
    Pour tout savoir sur l'utilisation du forum

    En postant votre message, n'oubliez pas les Règles du Club.

  7. #7
    Membre à l'essai
    Inscrit en
    août 2009
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : août 2009
    Messages : 15
    Points : 11
    Points
    11
    Par défaut
    Citation Envoyé par Bovino Voir le message
    Une erreur "classique" consiste aussi à lancer le setInterval dans la fonction appelée à la fin du timer... ce qui a pour facheuse conséquence de multiplier les timers et d'exploser la mémoire.
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function do_something(){
        // code de la fonction
        setInterval(do_something, 100);
    }
    exact, j'avais probablement fait cette erreur !!

    bon, j'ai scripté une sorte de chronomètre, permettant de tester un peu mieux tout ça,

    http://bdmusique.free.fr/timestamp.php

    le code :
    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
    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
    103
    104
    105
    106
    107
    108
    109
    <html>
    <head>
    <title>Test du timestamp</title>
    </head>
    <body>
     
    <div id="debug" >&nbsp;</div>
    <br>
    <div id="time1" >&nbsp;</div>
     
    <script>
     
    var compteur=0;
    var seconde=1000;
     
    var testing=Array();
    testing[0]='';
     
    var now=new Date();
    var t1=now.getTime();
    testing[0]=t1;
     
    var after_1min=new Date();
    var t2=testing[0]+(60*1000);
    after_1min.setTime(t2);
    var temp_ideal=after_1min.getTime();
     
    testing[1]=t1;
     
    var time0_report=now.getHours()+":"+now.getMinutes()+":"+now.getSeconds()+":"+now.getMilliseconds();
    var time1_report=after_1min.getHours()+":"+after_1min.getMinutes()+":"+after_1min.getSeconds()+":"+after_1min.getMilliseconds();
     
    document.getElementById('debug').innerHTML=compteur+ " à la fin du test, le timestamp idéal devrait être: "+temp_ideal+" (test démarré à "+time0_report+" & normalement finit à "+time1_report+")"; 
     
    function stop_timer(value)
    {
    //	clearTimeout(timer);
    	clearInterval(value);
    }
     
    var globalScope = new Array();
     
    /* A. Constructor */
    function TimeTicker()
    {
    document.getElementById('time1').innerHTML="départ: "+testing[0]+" & le compteur est : "+compteur;
     
    if( document.all )
    	{
    	/* A.3.1.1 - make a reference to the current object and saved in the global scope array
    	* to use later to correct the scope.
    	*/
    	globalScope[ this.uniqueId ] = this;
    	this.timer = setInterval( 'ieIntervalHandler("' + this.uniqueId + '","updateTime")', 1000 );
    	}
    else
    	{
    	/* A.3.2 - Mozilla */
    	this.timer = setInterval ( function( that ) { that.updateTime(); }, 1000, this );
    	}
    }
     
    /* B. This function is to update the time value somewhere on the screen */
    TimeTicker.prototype.updateTime = function ()
    {
    compteur=compteur+1;
    var now=new Date();
     
    var t3=now.getTime();
     
    current_delay=t3-testing[1];
     
    diff_time=t3-testing[0];
     
    testing[1]=t3;
     
    var fix_diff_time=Math.round(diff_time/seconde)*1000;
     
    decalage=diff_time-fix_diff_time;
     
    document.getElementById('time1').innerHTML=compteur+" & temps total écoulé (en millisecondes) : "+diff_time+" & il devrait être : "+fix_diff_time+" / intervalle actuel ="+current_delay+" / décalage sur le global ="+decalage; 
     
    if (compteur==60)
    	{
    	var now_after_1min=new Date();
    	var temp_ideal=now_after_1min.getTime();
     
    	var time2_report=now_after_1min.getHours()+":"+now_after_1min.getMinutes()+":"+now_after_1min.getSeconds()+":"+now_after_1min.getMilliseconds();
     
    	diff_time=t2-testing[0];
    	document.getElementById('time1').innerHTML=compteur+ " -> fin du test : le timestamp vaut "+t3+" ("+time2_report+") / decalage ="+decalage; 
     
    	stop_timer(this.timer);
    	return false;
    	}
    }
     
    function ieIntervalHandler( id, strFunc )
    {
    /* D.1 - correct the scope then make the call */
    var scope = globalScope[id];
    eval( "scope." + strFunc + "()" );
    }
     
    timer=new TimeTicker;
     
    </script>
    </body>
    </html>
    1ères constatations,,
    avec Internet Explorer :
    il a tendance à prendre du retard ! (+16 ms/seconde au départ... se stabilise souvent vers la 8ème / 10ème sec) le décalage total peut être de +31, +47, voir 64ms+

    avec firefox :
    il a tendance à s'éxécuter plus rapidement ! sur la 1ère seconde : décalage de -1ms / jusqu'à -14s, puis il se stabilise vers la 4ème seconde

    (test réalisé avec une seule fenêtre ouverte, pour chaque navigateur... machine au repos)

    alors je sais bien que js est côté client, et que le résultat va dépendre du proc' & de la machine éxécutante... mais quand même... sur certains calcul, ça fait de bonnes variations de résultat...

    voyez-vous un ptit bout de script, qui pourrait fixer ces décalages ? si vous avez une idée...

    j'essaierai de mon côté,

  8. #8
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : juin 2008
    Messages : 23 647
    Points : 91 423
    Points
    91 423
    Billets dans le blog
    20
    Par défaut
    Bon, je savais bien que je l'avais lu quelque part et je viens effectivement de retrouvre la source : le livre de John Resig : Secrets of the JavaScript Ninja.
    Dans une partie consacrée aux timers et après de multiples tests, il en vient à la conclusion qu'il peut y avoir un délai en moyenne de 15ms sur windows et 10ms sur OS X pour le déclenchement d'un timer. Ce qui signifie que pour des valeurs de 100ms, la marge d'erreur est en moyenne de 10 à 15%, ce qui est bien entendu inacceptable dans des problématiques de précision... Et malheureusement, il n'y a pas de parade apperemment
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  9. #9
    Membre à l'essai
    Inscrit en
    août 2009
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : août 2009
    Messages : 15
    Points : 11
    Points
    11
    Par défaut
    je pense qu'une parade est scriptable... j'vais y réfléchir...

    merci pour les recherches de ton côté, & pour les avis/opinions,

  10. #10
    Rédacteur

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

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

    Informations forums :
    Inscription : février 2009
    Messages : 6 387
    Points : 23 533
    Points
    23 533
    Billets dans le blog
    124
    Par défaut
    Bonsoir.

    J'ai réalisé récemment des tests de rapidité avec Firebug sur window.setInterval(expression, milliseconds);

    avec trois formes pour expression :
    1) un texte ;
    2) le nom de la fonction ;
    3) une fonction anonyme.

    Dans mon test (une seule ligne, très simple) 4000 appels par test, il fallait 0.88 à 1.1ms pour chaque appel à setInterval. Les temps varient à chaque série de tests, si je devais donner un classement je dirais que la forme 1 et la forme 2 se valent, souvent un léger avantage pour la forme 2.

    Mais pour la fonction anonyme, il faut également 1ms(en moyenne) pour l'évaluation de la fonction à chaque appel.

    Comme votre test utilise la forme 1 pour IE et la forme 3 pour F, je pense que F est désavantagé.

    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.)

  11. #11
    Membre à l'essai
    Inscrit en
    août 2009
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : août 2009
    Messages : 15
    Points : 11
    Points
    11
    Par défaut
    Citation Envoyé par Bovino Voir le message
    Bon, je savais bien que je l'avais lu quelque part et je viens effectivement de retrouvre la source : le livre de John Resig : Secrets of the JavaScript Ninja.
    Dans une partie consacrée aux timers et après de multiples tests, il en vient à la conclusion qu'il peut y avoir un délai en moyenne de 15ms sur windows et 10ms sur OS X pour le déclenchement d'un timer. Ce qui signifie que pour des valeurs de 100ms, la marge d'erreur est en moyenne de 10 à 15%, ce qui est bien entendu inacceptable dans des problématiques de précision... Et malheureusement, il n'y a pas de parade apperemment
    dans l'idée, il y aurait 2 parades possibles :

    1) on détecte le décalage entre chaque intervalle, & on réajuste en fonction,... par ex :
    a) au 1er passage, le timer a -10ms de retard
    b) on fixe en stoppant le timer / & on relance le timer en ajoutant +10ms à la valeur initiale du timer (compensation du timer, en fait)
    c) si le retard est nul au prochain passage, on réinitialise la valeur initiale du timer... sinon, on continue les corrections... etc,,

    2) peut-être plus léger :
    on réalise les calculs par rapport au timestamp exact... par ex :
    * si le timestamp est de -10ms par rapport à ce qu'il devrait être (sur la valeur du setInterval), on réalise les calculs par rapport à sa valeur réelle, & non par rapport à ce qu'il devrait en théorie être,

    plus concrètement, imaginons une valeur de départ de 3600, avec un décompte horaire de -3600/h qui est affiché toutes les 100ms,
    donc, au bout d'une heure précise, on devrait avoir 0 comme valeur... (mais ça n'est pas le cas, car problème avec la fonction setInterval, on l'a vu,)
    les 2 idées seraient :
    1) soit on fait un fix sur les erreurs de temps, en ajoutant/retranchant de l'intervalle-temps, en fonction de l'avance/retard du script
    2) soit on fait nos calculs par rapport au temps réel écoulé (& non par rapport à x intervalles passés/ x loops)

    j'ai scripté un peu les 2 idées,... mais je pense que la solution (2) me semble la + appropriée... à l'usage, la (1) serait probablement trop lourde, (car sans cesse relancer/stopper une boucle, pour tenter de stabiliser le temps... bof... ^^)

    si vous avez d'autres idées,

    & vos avis & commentaires sont les bienvenus,,

  12. #12
    Membre à l'essai
    Inscrit en
    août 2009
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : août 2009
    Messages : 15
    Points : 11
    Points
    11
    Par défaut
    script en test selon la 2ème idée :
    2) soit on fait nos calculs par rapport au temps réel écoulé (& non par rapport à x intervalles passés/ x loops)
    http://bdmusique.free.fr/test_time.php

    pour tester, vous pouvez utiliser ce genre de valeurs :
    ======
    #test A :
    Y=0 (valeur initiale test, qu'on va augmenter/diminuer)
    x=1 (à chaque boucle, on augmente de x la valeur Y)
    t=1 (le temps d'une boucle, en ms)
    b=1000 (le nombre de boucles à lancer)
    [pour cet exemple, désactivez le débug pour un meilleur résultat]

    a) pour ces valeurs x & t, environ 60 à 90 boucles suffiront pour dépasser les 1000ms

    b) sans le mode débug activé, IE arrive a déclencher environ 64 boucles, soit un temps d'éxécution d'environ 15ms pour chaque boucle

    c) sans le mode débug activé, FF arrive a déclencher environ 95 boucles, soit un temps d'éxécution d'environ 10ms pour chaque boucle (donc semble bien + rapide que IE!)

    d) setTimeout devrait (si chaque boucle pouvait s'éxécuter en 1ms) afficher le même résultat que celui donné par le timestamp

    ======

    #test B :
    Y=60
    x=-1
    t=1000
    b=60

    (soit, un décompte de 1, toutes les 1000ms... une minuterie, quoi, )
    a) j'obtient des valeurs très bonnes avec IE (à partir d'un intervalle = 500ms, les temps de boucles sont plutôt réguliers !)

    b) avec FF, c'est nettement moins précis ! Firefox me donne des résultats assez aléatoires sur les temps de boucle (générallement, entre 1ms à 3 ms d'écart par boucle, pour chaque intervalle de 1000ms. Soit sur 10 sec (10 boucles de 1000ms) environ 19ms d'écart (soit pour une minute: 114ms / pour une heure: 6840ms [=presque 7 sec !] )

    ======

    après test, je trouve que IE s'en sort mieux à partir d'un intervalle de 1000ms.
    (donc tous les scripts affichant une heure actualisée par un setTimeout, avec comme intervalle 1000ms, sont assez fiables avec IE.)
    pour firefox, je dirais que c'est plus délicat & moins précis !

    avec un intervalle de 100ms il faut ajuster pour les 2 navigateurs : IE semble plus lent & FF + rapide !

    encore une fois, nous sommes d'accord, les temps d'éxécution d'une boucle varient selon les processeurs & la machine client, de même que ça doit probablement dépendre de la teneur/longueur du code éxécuté pendant la boucle.
    mais le script devrait permettre de corriger/ajuster une valeur variant dans le temps,

    si ça peut en aider certains...

    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
    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
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    <html>
    <title>Test du temps d'éxécution de script & des timestamp</title>
    <body>
    Que fais cette page ?
    <br>==> un script s'éxécute en lançant " Test "
    <br>1) le script calcule les temps d'éxécution d'une boucle, & va comparer les intervalles obtenus avec ce qu'ils devraient être selon la fonction javascript setTimeout
    <br>2) on incrémente ou décrémente une variable <b>Y</b> (qui varie selon le temps, par ex: une consommation, ou un chronomètre) selon 2 méthodes (setTimeout + différence des timestamp) & on affiche les résultats obtenus
     
    <br>
    <br>Utilité ?
    <br>==> afficher une valeur + exacte sur un chronomètre / une consommation horaire que celle affichée via un 'setTimeout normal'
     
    <br>__________________________________________________<br><br>
    <input type="button" value="Test" onclick="calc();">
     
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Activer le débug : <input id="debug_mode" type="checkbox" onclick="Active_debug();">
    <br>
    <br>
    valeur de départ pour Y = <input id="val_y" type="text" value="0">
     
    <span id="deb1" style="display:none;">
    <!-- Création d'un container pour afficher les valeurs arrondies données par setTimeout -->
    <br>valeur arrondie pour Y selon setTimeout = <div id="container0" style="display:inline" ></div>
     
    <!-- Création d'un container pour afficher les valeurs données par setTimeout -->
    &nbsp;&nbsp;&nbsp;/&nbsp;&nbsp;&nbsp;valeur réelle pour Y selon setTimeout = (<div id="container1" style="font-style:italic;display:inline" ></div>)
     
    <!-- Création d'un container pour afficher les valeurs arrondies données par la différence des timestamp -->
    <br><br>valeur arrondie pour Y selon les timestamp = <div id="container3" style="display:inline" >1000</div>
     
    <!-- Création d'un container pour afficher les valeurs données par la différence des timestamp -->
    &nbsp;&nbsp;&nbsp;/&nbsp;&nbsp;&nbsp;valeur réelle pour Y selon la différence des timestamp = (<div id="container2" style="font-style:italic;display:inline" ></div>)
    </span>
     
    <br><br>
    <i>x</i> = valeur pour augmenter notre valeur Y à chaque intervalle (peut être négatif) / <b><i>x</i></b> = <input id="val_x" type="text" value="1">
     
    <br>
    valeur de l'intervalle (on éxécute la boucle toutes les <b><i>t</i></b> millisecondes) / <b><i>t</i></b> = <input id="val_t" type="text" value="1000">
    <br>
    nombre de boucles <b><i>b</i></b> = <input id="val_b" type="text" value="10">
    <br>
    <span id="deb2" style="display:none;">
    nombre de boucles effectuées = <div id="count" style="display:inline;" >0</div>
    </span>
     
    <br><br>
    <div id="debug1" >&nbsp;</div>
     
    <div id="debug2" >&nbsp;</div>
     
    <script>
     
    compteur=0;
     
    function calc()
    {
    if (compteur==0)
    	{
    	document.getElementById('debug2').innerHTML="";
    	document.getElementById('debug1').innerHTML="";
    	//test des valeurs
    	x=document.getElementById('val_x').value;
    	if (isNaN(x))
    		{
    		alert('nombre x non choisi!');
    		return false;
    		}
    	y=document.getElementById('val_y').value;
    	if (isNaN(y))
    		{
    		alert('nombre y non choisi!');
    		return false;
    		}
    	t=document.getElementById('val_t').value;
    	if (isNaN(t))
    		{
    		alert('nombre t non choisi!');
    		return false;
    		}
    	b=document.getElementById('val_b').value;
    	if (isNaN(b))
    		{
    		alert('nombre b non choisi!');
    		return false;
    		}
     
    	//début du test: on initialise les valeurs
    	now=new Date();
    	t1=now.getTime();
    	t0=t1;
     
    	//temps du test
    	after_test=new Date();
    	end_test=t0+(b*t);
    	after_test.setTime(end_test);
    	temps_ideal=after_test.getTime();
     
    	var time0_report=now.getHours()+":"+now.getMinutes()+":"+now.getSeconds()+":"+now.getMilliseconds();
    	var time1_report=after_test.getHours()+":"+after_test.getMinutes()+":"+after_test.getSeconds()+":"+after_test.getMilliseconds();
     
    	// valeurs correctes, on lance le test
    	document.getElementById('container0').innerHTML=y;
    	document.getElementById('container1').innerHTML=y;
    	document.getElementById('container2').innerHTML=y;
    	document.getElementById('container3').innerHTML=y;
     
    	x=eval(document.getElementById('val_x').value);
     
    	// facteur d'augmentation ou diminution de Y par milliseconde
    	ratio_ms=x/t;
     
    	retard_t=0;
     
    	// on récupère les 2 valeurs actuelles de y
    	y_setTimout=eval(document.getElementById('container1').innerHTML);
    	y_timestamp=eval(document.getElementById('container2').innerHTML);
     
    	if (debug==0)
    		{
    		document.getElementById('debug2').innerHTML="<br><b>Test en cours ! patientez...<b>";
    		document.getElementById('deb1').style.display="none";
    		document.getElementById('deb2').style.display="none";
    		document.getElementById('debug1').innerHTML="à la fin du test, le timestamp idéal devrait être: "+temps_ideal+" (test démarré à "+time0_report+" & normalement finit à "+time1_report+") / durée du test: "+b*t+" millisecondes";
    		timer=setTimeout("do_calc()",t);
    		}
    	else
    		{
    		document.getElementById('deb1').style.display="block";
    		document.getElementById('deb2').style.display="block";
    		document.getElementById('debug2').innerHTML="";
    		document.getElementById('debug1').innerHTML="à la fin du test, le timestamp idéal devrait être: "+temps_ideal+" (test démarré à "+time0_report+" & normalement finit à "+time1_report+") / durée du test: "+b*t+" millisecondes";
    		timer=setTimeout("do_calc_debug()",t);
    		}
    	}
    }
     
    // fonction du test
    function do_calc()
    {
    // on récupère le timestamp correspondant à l'éxécution de la boucle actuelle
    var now=new Date();
    var t2=now.getTime();
     
    // temps réel écoulé entre 2 intervalles
    delay=t2-t1;
     
    // temps écoulé depuis le début du test
    total_time=t2-t0;
     
    // on calcule par rapport au temps écoulé entre 2 intervalles
    fix_value=ratio_ms*(delay);
     
    y2=y_timestamp+fix_value;
    y_timestamp=y2;
     
    if (y2<0)
    	{
    	y3=Math.floor(y2);
    	}
    else
    	{
    	y3=parseInt(y2);
    	}
     
    // la valeur donnée par setTimeout est :
    y1=y_setTimout+x;
    y_setTimout=y1;
     
    if (y1<0)
    	{
    	y0=Math.floor(y1);
    	}
    else
    	{
    	y0=parseInt(y1);
    	}
    compteur=compteur+1;
     
    // on garde la valeur actuelle du timestamp pour tester le prochain intervalle
    t1=t2;
     
    retard_p=delay-t;
    retard_t=retard_t+retard_p;
     
    if (t2>=temps_ideal || compteur>=b)
    	{
    	//temps ou boucle dépassés, on stoppe la boucle
    	ecart=t2-temps_ideal;
    	document.getElementById('debug2').innerHTML="<br>temps total d'éxécution: "+total_time+" ms (retard total: "+retard_t+") / nouvelle valeur selon le timestamp: "+y2;
    	document.getElementById('debug1').innerHTML=document.getElementById('debug1').innerHTML+"<br>__________________________________________________<br><br>###Fin du test : le timestamp vaut "+t2+" & l'écart entre le temps idéal est de "+ecart+" ms<br>__________________________________________________<br>";
     
    	stop_timer(timer);
    	return false;
    	}
    else
    	{
    	//on relance la boucle
    	timer=setTimeout("do_calc()",t);
    	}
    }
     
    // même fonction, mais en mode debug
    function do_calc_debug()
    {
    // on récupère le timestamp correspondant à l'éxécution de la boucle actuelle
    var now=new Date();
    var t2=now.getTime();
     
    // temps réel écoulé entre 2 intervalles
    delay=t2-t1;
     
    // temps écoulé depuis le début du test
    total_time=t2-t0;
     
    // la valeur donnée par setTimeout est :
    y1=y_setTimout+x;
    y_setTimout=y1;
     
    document.getElementById('container1').innerHTML=y1;
     
    if (y1<0)
    	{
    	y0=Math.floor(y1);
    	}
    else
    	{
    	y0=parseInt(y1);
    	}
     
    document.getElementById('container0').innerHTML=y0;
     
    // on calcule par rapport au temps écoulé entre 2 intervalles
     
    fix_value=ratio_ms*(delay);
     
    y2=y_timestamp+fix_value;
    y_timestamp=y2;
     
    document.getElementById('container2').innerHTML=y2;
     
    if (y2<0)
    	{
    	y3=Math.floor(y2);
    	}
    else
    	{
    	y3=parseInt(y2);
    	}
     
    document.getElementById('container3').innerHTML=y3;
     
    compteur=compteur+1;
     
    document.getElementById('count').innerHTML=compteur;
     
    // on garde la valeur actuelle du timestamp pour tester le prochain intervalle
    t1=t2;
     
    retard_p=delay-t;
    retard_t=retard_t+retard_p;
     
    document.getElementById('debug2').innerHTML=document.getElementById('debug2').innerHTML+"<br>valeur de l'intervalle : "+delay+" ms (devrait être: "+t+" / retard actuel: "+retard_p+") / temps total d'éxécution: "+total_time+" ms (retard total: "+retard_t+") / nouvelle valeur selon le timestamp: "+y2;
     
    if (t2>=temps_ideal || compteur>=b)
    	{
    	//temps ou boucle dépassés, on stoppe la boucle
    	ecart=t2-temps_ideal;
     
    	document.getElementById('debug1').innerHTML=document.getElementById('debug1').innerHTML+"<br>__________________________________________________<br><br>###Fin du test : le dernier timestamp vaut "+t2+" & l'écart entre le temps idéal est de "+ecart+" ms<br>__________________________________________________<br>";
    	document.getElementById('debug1').innerHTML=document.getElementById('debug1').innerHTML+"<br>temps total d'éxécution: "+total_time+" ms (retard total: "+retard_t+") / nouvelle valeur selon le timestamp: "+y2;
     
    	stop_timer(timer);
    	return false;;
    	}
    else
    	{
    	//on relance la boucle
    	timer=setTimeout("do_calc_debug()",t);
    	}
    }
     
    function Active_debug()
    {
    if (document.getElementById('debug_mode').checked==true)
    	{
    	debug=1;
    	}
    else
    	{
    	debug=0;
    	}
    }
     
    function stop_timer(value)
    {
    if (debug==0)
    	{
    	document.getElementById('container1').innerHTML=y1;
    	document.getElementById('container0').innerHTML=y0;
    	document.getElementById('container2').innerHTML=y2;
    	document.getElementById('container3').innerHTML=y3;
    	document.getElementById('count').innerHTML=compteur;
     
    	document.getElementById('deb1').style.display="block";
    	document.getElementById('deb2').style.display="block";
    	}
    clearTimeout(value);
    compteur=0;
    }
     
    debug=0;
    document.getElementById('debug_mode').checked=false;
     
    document.getElementById('container1').innerHTML="";
    document.getElementById('container0').innerHTML="";
    document.getElementById('container2').innerHTML="";
    document.getElementById('container3').innerHTML="";
    document.getElementById('count').innerHTML="";
     
    </script>
     
    </body>
    </html>
    vos commentaires sont les bienvenus,

    & bon script à tous,

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    juin 2009
    Messages
    313
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : juin 2009
    Messages : 313
    Points : 330
    Points
    330
    Par défaut
    Intéressant, mais tu devrais utiliser DOM
    (Blague à part).

    L'estimation de la fin et le déclenchement de la boucle me fait dire que beaucoup de temps se perd. Les sorties textes sont très couteuses en réalité.
    Chose remarquable : Mieux vaut un gros innerHTML que plusieurs petits...

    J'ai fait le test, et j'ai un retard de .004 ms sous Safari et FF.
    C'est pas énorme.

    Intéressant d'essayer de redresser l'écart. Peut-être faudrait-il prévoir un déclenchement prématuré + boucle de temporisation avant déclenchement.
    Soit, un Timeout plus faible qu'envisagé suivit d'un wait (re-Timeout plus sérré ?) sur timestamp.


  14. #14
    Membre à l'essai
    Inscrit en
    août 2009
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : août 2009
    Messages : 15
    Points : 11
    Points
    11
    Par défaut
    je ferais des tests avec DOM !

    pour redresser l'écart, c'était ma 1ère idée, dans ma réponse précédente,
    j'ai testé, mais le script n'y arrive pas, en fait... il "redresse mal"... ^^

    par ex, pour un intervalle de 1000ms :
    a) intervalle 1er = 995ms [Durée Totale=995]
    on stoppe la boucle & la relance avec +5, soit 1005
    b) intervalle 2nd = 1008 [DT=2003]
    donc, on re-stoppe la boucle & on ajoute -3 (car le total sur 3 boucles doit être de 3000)
    c) intervalle 3ème= 997 [DT=3000] < okay, on est bon !
    d) intervalle 4ème= 1003 < faut refaire l'ajustement,...

    etc,.... bref, ça me semble lourd, à l'usage,

    & puis ce qui m'intéressait plus, c'était d'avoir la valeur réelle Y, à un instant précis t... donc le résultat me semble mieux convenir, avec le script actuel !

Discussions similaires

  1. valeur d'un objet différent suivant les affichages
    Par Nnahaa dans le forum Général Java
    Réponses: 8
    Dernier message: 11/05/2014, 02h53
  2. Comportement différent suivant les navigateurs
    Par baggie dans le forum Langage
    Réponses: 6
    Dernier message: 11/10/2012, 10h59
  3. Liste déroulante avec comportement différent suivant les navigateurs
    Par smfoa dans le forum Bibliothèques & Frameworks
    Réponses: 1
    Dernier message: 30/01/2011, 12h55
  4. probleme menu et css suivant les navigateurs...
    Par emile13 dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 27/01/2006, 05h04
  5. Action différente suivant les droits
    Par JMLD dans le forum XMLRAD
    Réponses: 2
    Dernier message: 27/04/2005, 18h25

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