Door
The Ultimate
op 19-12-2010 13:46
gewijzigd op 19-12-2010 14:58
9.522 views
Hallo,
Ik ben een total noob als het aankomt op javascript. So bare with me please...
Ik ben bezig met een website. Deze website maakt gebruik van een database. In deze database staan entries met geldbedragen. Deze geldbedragen laat ik de database bij elkaar optellen en dat is dus het bedragTotaal (o.i.d.). Het script en de database hiervoor moet ik nog maken.
Op deze website wil ik graag een realtime teller tonen (javascript?) die iedere seconde controleert wat het bedragTotaal is. Wanneer dit omhoog is gegaan dient de teller naar boven te worden bijgesteld. Het liefst zie ik dan de cijfers naar boven 'wegrollen' zoals je bij een gasmeter ook hebt. Dit zal dus een soort transitie of animatie moeten zijn.
Wie kan mij op weg helpen want ik heb gezocht, maar kom geen script tegen waar ik iets mee kan.
Helaas werkt het nog niet. Vreemd, want op de developers page werkt het uitstekend. Maar hoe kan ik er voor zorgen dat het script iedere seconde het bedragTotal controleert en optelt vanaf het huidige bedragTotal naar het nieuwe bedragTotal? En is het dan mogelijk om een soort van transitie toe te voegen? Bijvoorbeeld dat de eerste en laatste cijfers langzamer gaan dan de middelste?
<!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>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Untitled Document</title>
</head>
<body>
<h1>Jquery Number Ticker - By Damien Howley</h1>
<div class="counter-wrap">
<div class="counter-number">
</div>
</div>
<div>
<style>
.counter-wrap {
height:18px;
overflow:hidden;
}
.counter-number {
height:198px;
width:12px;
position:relative;
background-image:url(img/counter_ticker_bg.gif);
float:left;
}
</style>
<a href="#" onclick="loadticker(0786554)">load ticker - 786554</a><br/><br/>
<a href="#" onclick="loadticker(01767697234789837)">load ticker - 1767697234789837</a><br/><br/>
<a href="#" onclick="loadticker(01988989)">load ticker - 1988989</a><br/><br/>
</div>
<script src="js/jquery-1.4.4.min.js" type="text/javascript"></script>
<script type="text/javascript">
Deki.$(".counter-number").each( function(i) {
Deki.$(this).attr('id','num'+i);
});
function loadinput() {
var newval = Deki.$("#numgo").val();
loadticker(newval);
}
function loadticker(ticnum) {
var fticnum = add_commas(ticnum);
var numheight=18;
addticker(fticnum);
if (ticnum && ticnum != 0) {
var s = String(fticnum);
for (i=s.length;i>=0; i--)
{
var onum=s.charAt(i);
Deki.$("#num"+i).attr('value',onum);
}
Deki.$(".counter-number").each( function() {
var nval=Deki.$(this).attr("value");
if (!isNaN(nval)) {
var nheight = Number(nval)*numheight*-1;
Deki.$(this).animate({ top: nheight+'px'}, 1500 );
}
if (nval==','){
Deki.$(this).animate({ top: '-180px'}, 1500 );
}
});
}
}
function addticker(newnum) {
var digitcnt = Deki.$(".counter-number").size();
var nnum = String(newnum).length;
var digitdiff = Number(nnum - Number(digitcnt));
if (digitdiff <0) {
var ltdig = (Number(nnum)-1);
Deki.$(".counter-number:gt(" + ltdig + ")").remove();
}
for(i=1;i<=digitdiff;i++) {
Deki.$(".counter-wrap").append('<div class="counter-number" id="num' + (Number(digitcnt+i-1)) + '"> </div>');
}
}
function add_commas(nStr) {
nStr += '';
x = nStr.split('.');
x1 = x[0];
x2 = x.length > 1 ? '.' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + ',' + '$2');
}
return x1 + x2;
}
</script>
</body>
</html>
Nog even een detail omwille van de schoonheid en het overzicht:
$(document).ready(function() {
startCount();
});
Aangepast. Krijg nu 'NaN' te zien bij de #displayCounter.
[quote="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.
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)
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:
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):
<!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>
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.
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();
}
}
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)
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:
<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>