Realtime javascript teller

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Pagina: « vorige 1 2

Bas Cost Budde

Bas Cost Budde

20/12/2010 12:25:05
Quote Anchor link
Nog even een detail omwille van de schoonheid en het overzicht:
niet
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<script type="text/javascript">
// Uitvoeren
window.onload=startCount();

</script>
maar in de bovenste javascript
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
$(document).ready(function() {
  startCount();
});


Ik kom zometeen op de flow. ('t wordt iets drukker op het werk nu)


Toevoeging op 20/12/2010 12:39:23:

Kijk met Firefox/firebug/Net-panel mee met de XHR-requests, om te zien wanneer je server wordt aangeroepen. Dat vertelt je iets over wat er gebeurt.
 
PHP hulp

PHP hulp

03/01/2025 03:27:50
 
The Ultimate

The Ultimate

20/12/2010 12:56:53
Quote Anchor link
Bas Cost Budde op 20/12/2010 12:25:05:
Nog even een detail omwille van de schoonheid en het overzicht:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
$(document).ready(function() {
  startCount();
});
Aangepast. Krijg nu 'NaN' te zien bij de #displayCounter.

Bas Cost Budde op 20/12/2010 12:25:05:
Ik kom zometeen op de flow. ('t wordt iets drukker op het werk nu)
Yup. Geen vakantie begrijp ik? Balen man!

Bas Cost Budde op 20/12/2010 12:25:05:
Kijk met Firefox/firebug/Net-panel mee met de XHR-requests, om te zien wanneer je server wordt aangeroepen. Dat vertelt je iets over wat er gebeurt.
Goed idee. Heb ik aanstaan. Ik zie nu dat er netjes iedere 10 seconden een request wordt gezonden naar get_amount.php. Dat gaat dus iig al goed. Nu nog de counter zien te laten lopen.
Gewijzigd op 20/12/2010 12:57:14 door The Ultimate
 
Bas Cost Budde

Bas Cost Budde

20/12/2010 13:14:02
Quote Anchor link
NaN?
wijzig
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
var cStart;
var cEnd;
in
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
var cStart = 0;
var cEnd = 0;
 
The Ultimate

The Ultimate

20/12/2010 13:20:09
Quote Anchor link
Ja, dat heeft geholpen. Nu wordt het cijfer '1' weergegeven. Dat komt natuurlijk van cStart = cStart + 1;

Maar waarom wordt er 1 weergegeven en niet de SUM + 1? Dit zou 55 moeten zijn. We hebben toch eerder al cStart gevuld? cStart=54;
 
Bas Cost Budde

Bas Cost Budde

20/12/2010 13:26:54
Quote Anchor link
timerStartValue() doet een verzoek naar de server; het antwoord zal de waarde in cStart zetten (en weergeven in #startValue). Straks. Als de server terugkomt.
Intussen racet javascript verder. timerEndValue(), timerCounterValue(), timedCount() -> toon de waarde van cStart in #displayCounter. Ehm, die waarde ken ik wel, die is 0.

Asynchroon! startCount doet teveel. timedCount mag pas gaan lopen als de callback van timerEndValue gearriveerd is. Verplaats dus de oproep naar de callback van timerEndValue.

(timerStartValue zou je mogen weglaten; wanneer je de eindwaarde binnenkrijgt in timerEndValue, en er is nog geen cStart gezet, is dit kennelijk de eerste aanroep, en zet je cStart)
 
The Ultimate

The Ultimate

20/12/2010 13:43:35
Quote Anchor link
Bas Cost Budde op 20/12/2010 13:26:54:
timerStartValue() doet een verzoek naar de server; het antwoord zal de waarde in cStart zetten (en weergeven in #startValue). Straks. Als de server terugkomt.
Intussen racet javascript verder. timerEndValue(), timerCounterValue(), timedCount() -> toon de waarde van cStart in #displayCounter. Ehm, die waarde ken ik wel, die is 0.
Ok, duidelijk de waarde is nog niet binnen op het moment dat deze wordt gezet.

Bas Cost Budde op 20/12/2010 13:26:54:
Asynchroon! startCount doet teveel. timedCount mag pas gaan lopen als de callback van timerEndValue gearriveerd is. Verplaats dus de oproep naar de callback van timerEndValue.
Bedoel je zoiets:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function startCount()
{
    // Beginwaarde en eindwaarde ophalen
    timerStartValue();
    this.callback = timerEndValue();

    if(this.callback > 0)
    {
        // Timer starten
        timedCount();
    }

    // Na 10 seconden controleren of de cEnd is gewijzigd.
    setTimeout("checkEndValue()",10000);
}
Vergeef me als ik er helemaal naast zit.

Bas Cost Budde op 20/12/2010 13:26:54:
(timerStartValue zou je mogen weglaten; wanneer je de eindwaarde binnenkrijgt in timerEndValue, en er is nog geen cStart gezet, is dit kennelijk de eerste aanroep, en zet je cStart)
Ok, een if/else-statement gebruiken dan?

Is het trouwens een idee om mijn script met het volgende te combineren (aangezien van het script hieronder de teller wel werkt):
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Timer Class</title>

    <script language="javascript" type="text/javascript">
    <!--
    
    // http://www.dailycoding.com/Posts/object_oriented_programming_with_javascript__timer_class.aspx
    
    // Declaring class "Timer"
    var Timer = function()
    {        
        // Property: Frequency of elapse event of the timer in millisecond
        this.Interval = 1000;
        
        // Property: Whether the timer is enable or not
        this.Enable = new Boolean(false);
        
        // Event: Timer tick
        this.Tick;
        
        // Member variable: Hold interval id of the timer
        var timerId = 0;
        
        // Member variable: Hold instance of this class
        var thisObject;
        
        // Function: Start the timer
        this.Start = function()
        {
            this.Enable = new Boolean(true);
    
            thisObject = this;
            if (thisObject.Enable)
            {
                thisObject.timerId = setInterval(
                function()
                {
                    thisObject.Tick();
                }, thisObject.Interval);
            }
        };
        
        // Function: Stops the timer
        this.Stop = function()
        {            
            thisObject.Enable = new Boolean(false);
            clearInterval(thisObject.timerId);
        };
    
    };

    var obj = new Timer();
    var startValue = 30; // This is the value the counter will start with
    var endValue = 200;
//    var endValue = $.get('get_amount.php',function(data){    // WERKT NIET...!!
//        var endValue = data;                                // WERKT NIET...!!
//    });                                                        // WERKT NIET...!!
    obj.Interval = 30;
    obj.Tick = timer_tick;
    obj.Start();

    function timer_tick()
    {
        startValue  = startValue + 1;
        document.getElementById("div1").innerHTML = startValue;
        
        if (startValue == endValue)
        {
            obj.Stop();
        }
    }

    </script>

</head>
<body>

    <style>
    #div1{
        font-size:20px;
        font-weight:bold;
    }
    </style>

    <div id="div1">
    </div>

</body>
</html>
Gewijzigd op 20/12/2010 14:05:38 door The Ultimate
 
Bas Cost Budde

Bas Cost Budde

20/12/2010 14:08:20
Quote Anchor link
Nee, je zit er inderdaad helemaal naast. startCount draait in 1 ruk van begin tot eind; het antwoord op je timerEndValue komt in een ander proces terecht. Binnen startCount kom je niet te weten of de server reageert.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function timedCount()
{
    $("#displayCounter").html(cStart); // Waarde in HTML object plaatsen

    cStart=cStart+1; // Wat moet er met de waarde gebeuren
    
    if(cStart<=cEnd) // Stoppen wanneer de Timer op cEnd staat
    {
        // Functie aanroepen (oneindige loop)
        t=setTimeout("timedCount()",1000);
    }
    // ### nieuw ###
    else
    {
        timedCount();
    }
}

en de timedCount in startCount moet vervallen.
 
The Ultimate

The Ultimate

20/12/2010 14:21:34
Quote Anchor link
Snap er nu helemaal niets meer van. Mijn code is inmiddels een grote gatenzooi en er klopt volgens mij geen ene bal meer van... zucht
 
Bas Cost Budde

Bas Cost Budde

20/12/2010 14:30:45
Quote Anchor link
Firebug is je vriend! Zie ook het paneel Console.

In het script dat ik van je heb, staat een oproep naar timerCounterValue die niet bestaat. Als ik die weghaal, en verder de verplaatsing van timedCount uitvoer, doet je script het bij mij. (ik heb zelf een stubje geschreven voor get_amount.php)
 
The Ultimate

The Ultimate

20/12/2010 14:42:23
Quote Anchor link
Bas Cost Budde op 20/12/2010 14:30:45:
In het script dat ik van je heb, staat een oproep naar timerCounterValue die niet bestaat.
Ik heb timerCounterValue weggehaald.

Bas Cost Budde op 20/12/2010 14:30:45:
Als ik die weghaal, en verder de verplaatsing van timedCount uitvoer, doet je script het bij mij. (ik heb zelf een stubje geschreven voor get_amount.php)
Wat doet het script dan precies? Zie je ook de teller lopen?

Ik krijg een error via Firebug "Too much recursion". Op deze manier (zie hieronder) loopt timedCount toch ook eindeloos door?

Dit is mijn script tot nu toe:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<html>
<head>
<script src="js/jquery-1.4.4.min.js" type="text/javascript"></script>
<script type="text/javascript">

$(document).ready(function() {
  startCount();
});

var t;
//var timer_is_on=0;
var cStart=0
var cEnd=0;

function startCount()
{
    // Beginwaarde en eindwaarde ophalen
    timerStartValue();
    timerEndValue();

    // Timer starten
    timedCount();

    // Na 10 seconden controleren of de cEnd is gewijzigd.
    setTimeout("checkEndValue()",10000);
}

function checkEndValue()
{
    // Oude timerEndValue opslaan
    cEndOld=cEnd;
    
    // Nieuwe timerEndValue opvragen
    timerEndValue();

    // Oude en nieuw timerEndValue met elkaar vergelijken
    if(cEndOld!=cEnd){
        // Teller opnieuw starten
        timedCount();
    } else {
        // Over 10 seconden weer controleren
        setTimeout("checkEndValue()",10000);
    }
}

function timedCount()
{
    $("#displayCounter").html(cStart); // Waarde in HTML object plaatsen

    cStart=cStart+1; // Wat moet er met de waarde gebeuren
    
    if(cStart<=cEnd) // Stoppen wanneer de Timer op cEnd staat
    {
        // Functie aanroepen (oneindige loop)
        t=setTimeout("timedCount()",1000);
    }
    // ### nieuw ###
    else
    {
        timedCount();
    }
}

function timerStartValue()
{
    $.get('get_amount.php',
        function(data)
        {
            cStart = data - 10;

            // Beginwaarde tonen
            $("#startValue").html(cStart);
        }
    );
}

function timerEndValue()
{
    $.get('get_amount.php',
        function(data)
        {
            cEnd = data;

            // Eindwaarde tonen
            $("#endValue").html(cEnd);
        }
    );
}

</script>
</head>

<body>

<p>De startwaarde is <span id="startValue"></span></p>
<p>De eindwaarde is <span id="endValue"></span></p>
<p>De timer staat nu op: <span id="displayCounter"></span></p>

</body>
</html>
Gewijzigd op 20/12/2010 14:47:10 door The Ultimate
 
Bas Cost Budde

Bas Cost Budde

20/12/2010 15:00:22
Quote Anchor link
Dit het mijne (ik ben iets zuiniger met whitespace :) )
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<html>
<head>
<script src="jquery.js" type="text/javascript"></script>
<script type="text/javascript">

$(document).ready(function() { startCount(); });

var cStart = 0;
var cEnd = 0;

function startCount() {
    // Beginwaarde en eindwaarde ophalen
    timerStartValue();
    timerEndValue(); // start meteen de gasmeter-teller
}

// wachtlus-teller
function checkEndValue() {
    // Oude timerEndValue opslaan
    cEndOld = cEnd;
    // Nieuwe timerEndValue opvragen
    timerEndValue();
    // Oude en nieuw timerEndValue met elkaar vergelijken
    if (cEndOld < cEnd) {
        // Teller opnieuw starten
        timedCount();
    } else {
        // Over 10 seconden weer controleren
        setTimeout("checkEndValue()",1000);
    }
}

function timedCount() {
    cStart=cStart+1; // Wat moet er met de waarde gebeuren
    $("#displayCounter").html(cStart); // Waarde in HTML object plaatsen
    // Stoppen wanneer de Timer op cEnd staat
    if (cStart < cEnd) { // zolang we er nog niet zijn, doortellen
        setTimeout("timedCount()",300);
    } else {
        checkEndValue();
    }
}

function timerStartValue() {
    $.get('get_amount.php',
        function(data) {
            cStart = data - 10;
            cEnd = data;
            // Beginwaarde tonen
            $("#startValue").html(cStart);
            $("#endValue").html(cEnd);
            // Timer starten
            timedCount();
        }
    );
}

function timerEndValue() {
    $.get('get_amount.php',
        function(data) {
            cEnd = data;
            // Eindwaarde tonen
            $("#endValue").html(cEnd);
        }
    );
}

</script>
</head>

<body>

<p>De startwaarde is <span id="startValue"></span></p>
<p>De eindwaarde is <span id="endValue"></span></p>
<p>De timer staat nu op: <span id="displayCounter"></span></p>

</body>
</html>
 
The Ultimate

The Ultimate

20/12/2010 15:09:09
Quote Anchor link
Wow, zeer wazig. Jouw script ziet er (zo zonder al die whitespace) een stuk beter uit en werkt om de een of andere vage reden bij mij wel. Super!

Oh man, ik had het bijna aan de kant gesmeten....

Nog een vraagje:
Je kent ongetwijfeld die transitions (easyInOut,etc) die ze bij foto-albums vaak gebruiken. Zou het denk je mogelijk zijn om een dergelijke transitie in het optellen te verwerken, zodat de eerste en laatste cijfers langzaam wegtikken terwijl de middelste snel? Dus stel dat je van 1 naar 100 gaat dan gaat 1 supertraag, 2 al iets minder traag, 3 traag, 4 langzaam, 5 normaal, 6 t/m 10 snel, 10 t/m 80 supersnel, 80 t/m 96 snel, 97 langzaam, 98, zeer langzaam en uiteindelijk 100 superlangzaam.

Als je tips hebt om het netter te maken dan hoor ik het uiteraard graag!

Edit:
Trouwens, als je een waarde in de database toevoegt gaat de teller niet opnieuw lopen, terwijl er wel iedere 5 sec wordt gecontroleerd op nieuwe waardes. Weet jij hoe dit komt?
Gewijzigd op 20/12/2010 15:11:37 door The Ultimate
 
Bas Cost Budde

Bas Cost Budde

20/12/2010 15:48:39
Quote Anchor link
Hmm... dat kun je bereiken door de setTimeout in timedCount() een variabel interval mee te geven. Bereken het interval bijvoorbeeld door het domein van de doorteller in drie stukken te verdelen; het middelste stuk krijgt een kort interval, de twee randstukken ofwel een langer interval, ofwel zelfs een verlopende waarde (voor extra vloeiende overgang).

0. detecteer een oploop-verzoek: in checkEndValue en timerStartValue, helaas dus op twee plaatsen. Refactor.
1. markeer eenmaal het domein en de segmenten:
var dist = cEnd - cStart;
var seg0 = cStart + dist/10; // 10% aan de randen
var seg1 = cEnd - dist/10;
Let op de scope van de variabelen!
2. beslis in elke stap (if cStart < cEnd) je intervalgrootte:
timediff = 30; // supersnel
if (cStart < seg0) timediff = 300 - (seg0 - cStart)*270/seg0;
if (cStart > seg1) timediff = 300 + (cStart - seg1)*270/seg1;
3. Go!
setTimeout(timedCount, timediff);

De 'air code' waarschuwing is van overeenkomstige toepassing. Ik heb wel wat wiskunde toegepast voor de timediff-vergelijkingen :)
 
The Ultimate

The Ultimate

20/12/2010 16:44:57
Quote Anchor link
Ja, aan zo'n soort oplossing zat ik zelf ook al te denken. Dat zou ik dan zelf nog uit kunnen breiden met meer verdeling zodat het vloeiender loopt.

Is het jou ook opgevallen dat wanneer de totale SUM van de database veranderd dat de teller dan niet opnieuw begint te tellen? Heb je enig idee hoe dat komt?
 
Bas Cost Budde

Bas Cost Budde

20/12/2010 16:51:04
Quote Anchor link
Edit: Zelfde probleem met de asynchrone oproep. Je vraagt wel om een nieuwe eindwaarde, maar die komt niet in diezelfde functie al binnen.

Dat betekent dat er nog een stukje verbouwd moet. En ik heb meteen de wiskunde kunnen checken...

Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<html>
<head>
<script src="jquery.js" type="text/javascript"></script>
<script type="text/javascript">

$(document).ready(function() { startCount(); });

var cStart = 0;
var cEnd = 0;
var idleTimeout;
var upcounting = false;
var idletime = 5000;
var slowtime = 500;
var fasttime = 50;
var nul, dist, seg0, seg1;

function startCount() {
    // Beginwaarde en eindwaarde ophalen
    timerStartValue();
    checkEndValue(); // start meteen de gasmeter-teller
}

// wachtlus-teller
function checkEndValue() {
    // Nieuwe timerEndValue opvragen
    timerEndValue();
    idleTimeout = setTimeout("checkEndValue()", idletime);
}

function timedCount() {
    $("#displayCounter").html(cStart);
    if (cStart < cEnd) { // zolang we er nog niet zijn, doortellen
        if (idleTimeout) {
            window.clearTimeout(idleTimeout);
            idleTimeout = null;
        }
        if (!upcounting) {
            nul = cStart;
            dist = cEnd - cStart;
            seg0 = cStart + dist/10; // 10% aan de randen
            seg1 = cEnd - dist/10;
            upcounting = true;
        }
        cStart++; // Wat moet er met de waarde gebeuren
        timediff = fasttime; // supersnel
        if (cStart < seg0) {
            timediff = fasttime + (cStart-seg0)*(fasttime-slowtime)/(dist/10);
        }
        if (cStart > seg1) {
            timediff = fasttime - (cStart-seg1)*(fasttime-slowtime)/(dist/10);
        }
        setTimeout(timedCount, timediff);
    } else {
        upcounting = false;
        checkEndValue();
    }
}

function timerStartValue() {
    $.get('get_amount.php',
        function(data) {
            cStart = data - 10;
            // Beginwaarde tonen
            $("#startValue").html(cStart);
        }
    );
}

function timerEndValue() {
    $.get('get_amount.php',
        function(data) {
            cEnd = data;
            // Eindwaarde tonen
            $("#endValue").html(cEnd);
            if (cEnd > cStart) {
                // Timer starten
                timedCount();
            }
        }
    );
}

</script>
</head>

<body>

<p>De startwaarde is <span id="startValue"></span></p>
<p>De eindwaarde is <span id="endValue"></span></p>
<p>De timer staat nu op: <span id="displayCounter"></span></p>

</body>
</html>
 
The Ultimate

The Ultimate

20/12/2010 17:14:04
Quote Anchor link
Hahaha, werkt als een trein! Wow, had vanmiddag even niet gedacht dat dit nog zou gaan lukken. Nou moet ik wel zeggen dat jij het mij zo ongeveer voorgekauwd hebt aangeleverd, maar toch...

Mijn dank is groot en mijn bewondering (voor het getoonde geduld) ook. Ondanks dat ik er nog veel moeite mee heb is dit wel de eerste goede stap richting meer javascripts voor mij!

Trouwens, die versnelling en verlangzaming (is dit een woord?) werkt echt supersmooth!
Gewijzigd op 20/12/2010 17:20:41 door The Ultimate
 
Bas Cost Budde

Bas Cost Budde

20/12/2010 19:17:32
Quote Anchor link
vertraging (verlangzaming :) ik reken het goed, maar dat is meer mijn ervaring met Esperanto)

De berekening is nog lineair, en het snelheidsverloop krijgt daardoor een schok op de overgang naar het 'supersnel'-gedeelte. Je ziet het nauwelijks.

Er valt nog wel wat te winnen op de struktuur van de javascript; dit is een vrij oude stijl van programmeren, het kan ook meer object-georienteerd. Vaak komt dat de onderhoudbaarheid ten goede.
 
The Ultimate

The Ultimate

21/12/2010 08:17:09
Quote Anchor link
Bas Cost Budde op 20/12/2010 19:17:32:
vertraging (verlangzaming :) ik reken het goed, maar dat is meer mijn ervaring met Esperanto)
Thanks

Bas Cost Budde op 20/12/2010 19:17:32:
De berekening is nog lineair, en het snelheidsverloop krijgt daardoor een schok op de overgang naar het 'supersnel'-gedeelte. Je ziet het nauwelijks.
Nee, valt nauwelijks op. Vooral wanneer je de snelheden verandert naar 30 en 300.

Bas Cost Budde op 20/12/2010 19:17:32:
Er valt nog wel wat te winnen op de struktuur van de javascript; dit is een vrij oude stijl van programmeren, het kan ook meer object-georienteerd. Vaak komt dat de onderhoudbaarheid ten goede.
Moet je er - om het te moderniseren - een classe van maken (heet dit classe in javascript?). Dus bijv:
var Timer = function(){ hier he script }
En dan uiteraard de functies aanpassen naar this.functie() =
Zoiets?
 

Pagina: « vorige 1 2



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.