Timer mit JavaScript?

3 Antworten

oh Gütiger... mit while und anderem Kram brauchst Du es garnicht erst versuchen...
Sowas ist totaler Humbug in Javascript.

Für derartige Sachen hat Javascript die asynchronen Funktionen setInterval() und setTimeout().

Asynchron bedeutet , das alles was innerhalb dieser Funktionen deklariert ist parallel zum restlichen Code abläuft. so kann man auch mehrere auch unterschiedliche Timer und anderen Kram nebeneinander laufen lassen.
zB einer zählt hoch , der andere runter etc.

ich habe es mal ganz einfach gehalten...

Die Umrechnerei Minuten in Sekunden wirst Du wohl selber hinbekommen , genau wie einen Button...

<script>
function countDown(seconds) {
    var timer = seconds;
    
    interval=setInterval(function () {
              // schreibe timer in element mit der ID "time"
        document.getElementById('time').innerHTML = timer; 
            //variable timer solange um 1 reduzieren bis 0 
        if (--timer < 0) {clearInterval(interval); //wenn timer <0 interval stoppen
        }
    }, 1000); // tue das alle 1000 Millisekunden
};

window.onload = function () {
    countDown(10);
};
</script>
<body>
    <div id="time"></div>
</body>

https://www.w3schools.com/jsref/met_win_setinterval.asp

https://www.w3schools.com/jsref/met_win_settimeout.asp


Sonnenschauer 
Fragesteller
 07.05.2018, 10:06

den Button hab ich ja schon und alles. Bin bis jetzt halt nur am verzweifeln, weil ich eben nicht weiß, wie ich es so machen kann, dass dann der User seine Zeit einstellen kann und es dann in Stunden, Minuten und Sekunden runter zählt. Aber ich versuche es definitiv mal mit deinem Aufbau. Dann hab ich erstmal ne grundstruktur

Vielen dank!

0
timlg07  08.05.2018, 22:46
@Sonnenschauer

Hab den Kommentar hier leider jetzt erst gelesen. Wenn du Stunden nicht als 60 Minuten sondern wirklich als Stunden angeben willst, wärs warscheinlich am besten du ersetzt bei meiner Lösung den jetzigen input durch 3 andere input Felder (mit type=number).

Falls du dabei Hilfe brauchst, sag Bescheid.

0

Wenn du das script am Ende der Antwort unter timer.js abspeicherst kannst du das ja so laden:

<script src="timer.js"></script>

Dann kannst du an jeder Stelle in deinem document ein Div mit der Klasse timer erstellen um einen einfachen Timer einzufügen.

<div class="timer"></div>

Die Größe des Timers kannst du selbstständig anpassen. Ich hab zum testen im leeren document das hier genommen:

<style>div.timer{width:30vw; height:20vh; margin:20vw;}</style>

Natürlich kannst du mit CSS auch noch den Style der inneren Timer-Elemente ändern.

Die Zeit kannst du im input Feld in MIN:SEC angeben.

timer.js:

window.addEventListener('load', function()
{
    document.querySelectorAll("div.timer").forEach( function(t)
    {
        // create elements //
        var text = document.createElement("p"     );
        var inpt = document.createElement("input" );
        var bttn = document.createElement("button");
        // add elements //
        t.appendChild(text);
        t.appendChild(inpt);
        t.appendChild(bttn);
        // attributes //
        inpt.setAttribute("type","time");
        inpt.setAttribute("value","00:00")
        bttn.innerHTML = "STARTEN";
        // style //
        text.style.width        =  '100%';
        text.style.marginBottom =    '6%';
        text.style.fontSize     =  '200%';
        text.style.fontFamily   = 'Arial';
        text.style.textAlign    ='center';
        inpt.style.width        =   '50%';
        bttn.style.width        =   '50%';
        // init timer //
        new Timer(t,text,inpt,bttn);
    });
});

function Timer(div,txt,inp,btn)
{
    var that = this;
    
    this.nodes = new Array();
    
    this.nodes['container'] = div;
    this.nodes['output'   ] = txt;
    this.nodes['input'    ] = inp;
    this.nodes['button'   ] = btn;
    
    this.value = 0;
    this.fps   =60;
    
    this.nodes['output'].innerHTML = this.getFormattedValue();
    
    this.nodes['input' ].addEventListener('input', function(){
        that.setValue(that.nodes['input'].value);
    }, false );
    
    this.nodes['button'].addEventListener('click', function(){
        that.start();
    }, false );
}

Timer.prototype.start = function()
{
    var that = this;
    this.timerID = setInterval(function(){
        that.value -= 1000 / that.fps;
        if(that.value<=0)
        {
            clearInterval(that.timerID);
            that.onExpire();
            that.value  = 0;
        }
        that.update();
    }, 1000 / this.fps)
}

Timer.prototype.update = function()
{
    this.nodes ['output'] .innerHTML = this.getFormattedValue();
}

Timer.prototype.onExpire = function()
{
    var that = this;
    for(var i=0; i<10; i++)
    {
        setTimeout(function(){that.nodes['container'].style.backgroundColor = '#f00';},   i*200);
        setTimeout(function(){that.nodes['container'].style.backgroundColor = 'inherit';},i*200 +100);
    }
}
    
Timer.prototype.getFormattedValue = function()
{
    return this.f(this.getHour()) + ':' + this.f(this.getMins()) + ':' + this.f(this.getSecs()) + ':' + this.f(this.getMSec());
}

Timer.prototype.f = function(v) // returns the value with 2 decimals
{
    if(v.toString().length<2) return '0'+v; 
    if(v.toString().length>2) return v.toString().substring(0,2);
    return v;
}

Timer.prototype.setValue = function(v)
{
    this.value  = v.split (':',2) [0] *60 *1000;
    this.value += v.split (':',2) [1]     *1000;
    this.update()
}

Timer.prototype.getHour = function(){return Math.floor( Math.floor( this.value / 60 / 60 / 1000 ) %    1);}
Timer.prototype.getMins = function(){return Math.floor( Math.floor( this.value      / 60 / 1000 ) %   60);}
Timer.prototype.getSecs = function(){return Math.floor( Math.floor( this.value           / 1000 ) %   60);}
Timer.prototype.getMSec = function(){return Math.floor( Math.floor( this.value                  ) % 1000);}

~Tim


Erzesel  09.05.2018, 07:28

.... dicke Kanonen für kleine Spatzen ....
ich hätte bestenfalls ein Form mit zwei Inputfeldern einegrichtet... Stunden Minuten und die Eingaben mit 3600 bzw 60 multpliziert... (vielleicht 10 Zeilen)

Bei solchen Monstern verstehe ich , warum wir Glasfasernetze brauchen... *rolfl*
mein altes 2400er Modem hätte allein zum laden dieses Monsters eine gefühlte Stunde nötig gehabt... (1 minute Internet kostete damals 14 Pfennige)

0
timlg07  09.05.2018, 22:21
@Erzesel

Meinst du das erstellen der Elemente mit JS? Wollte ich nur mal ausprobieren, weil ich's cool find in die html nur <div class='...'> packen zu müssen um so etwas einzufügen. Aber hast recht, für nen kleinen Timer ist es vielleicht doch etwas ausgeartet ^^

Und ein Form wäre auch deutlich verständlicher, da man angeben kann welcher Wert Stunde/Minute/Sekunde ist. Werd ich nachher mal umschreiben.

0
Erzesel  09.05.2018, 07:38

PS: Bei der Anzahl von Zeilen für ein kleines Inputfeld hätten meine Rheumafinger wohl eine Physiotherapiesitzung nötig gehabt...

Am Rande... kommst Du am 2.Juni zum GutefrageTreffen? (wäre sicher mal interessant sich RL zu begegnen)

0
timlg07  09.05.2018, 22:23
@Erzesel

Vom GutefrageTreffen hab ich gar nichts mitbekommen ... wo ist das denn?

0
timlg07  09.05.2018, 22:24

Hier noch mal die Version mit start & stop:

window.addEventListener('load', function()
{
    document.querySelectorAll("div.timer").forEach( function(t)
    {
        // create elements //
        var text = document.createElement("p"     );
        var inpt = document.createElement("input" );
        var bttn = document.createElement("button");
        // add elements //
        t.appendChild(text);
        t.appendChild(inpt);
        t.appendChild(bttn);
        // attributes //
        inpt.setAttribute("type","time");
        inpt.setAttribute("value","00:00")
        bttn.innerHTML = "START";
        // style //
        text.style.width        =  '100%';
        text.style.marginBottom =    '6%';
        text.style.fontSize     =  '200%';
        text.style.fontFamily   = 'Arial';
        text.style.textAlign    ='center';
        inpt.style.width        =   '50%';
        bttn.style.width        =   '50%';
        // init timer //
        new Timer(t,text,inpt,bttn);
    });
});

function Timer(div,txt,inp,btn)
{
    var that = this;
    
    this.isRunning = 0;
    this.nodes = new Array();
    
    this.nodes['container'] = div;
    this.nodes['output'   ] = txt;
    this.nodes['input'    ] = inp;
    this.nodes['button'   ] = btn;
    
    this.value = 0;
    this.fps   =60;
    
    this.nodes['output'].innerHTML = this.getFormattedValue();
    
    this.nodes['input' ].addEventListener('input', function(){
        that.setValue(that.nodes['input'].value);
    }, false );
    
    this.nodes['button'].addEventListener('click', function(){
        if(that.isRunning)
        {
            that.stop();
        }
        else
        {
            that.start();
        }
    }, false );
}

Timer.prototype.start = function()
{
    var that = this;
    this.timerID = setInterval(function(){
        that.value -= 1000 / that.fps;
        if(that.value<=0)
        {
            that.stop();
            that.onExpire();
            that.value  = 0;
        }
        that.update();
    }, 1000 / this.fps);
    this.nodes['button'].innerHTML = 'STOP';
    this.isRunning = !this.isRunning;
}

Timer.prototype.stop = function()
{
    clearInterval(this.timerID);
    this.nodes['button'].innerHTML = 'START';
    this.isRunning = !this.isRunning;
}

Timer.prototype.update = function()
{
    this.nodes ['output'] .innerHTML = this.getFormattedValue();
}

Timer.prototype.onExpire = function()
{
    var that = this;
    for(var i=0; i<10; i++)
    {
        setTimeout(function(){that.nodes['container'].style.backgroundColor = '#f00';},   i*200);
        setTimeout(function(){that.nodes['container'].style.backgroundColor = 'inherit';},i*200 +100);
    }
}
    
Timer.prototype.getFormattedValue = function()
{
    return this.f(this.getHour()) + ':' + this.f(this.getMins()) + ':' + this.f(this.getSecs()) + ':' + this.f(this.getMSec());
}

Timer.prototype.f = function(v) // returns the value with 2 decimals
{
    if(v.toString().length<2) return '0'+v; 
    if(v.toString().length>2) return v.toString().substring(0,2);
    return v;
}

Timer.prototype.setValue = function(v)
{
    this.value  = v.split (':',2) [0] *60 *1000;
    this.value += v.split (':',2) [1]     *1000;
    this.update()
}

Timer.prototype.getHour = function(){return Math.floor( Math.floor( this.value / 60 / 60 / 1000 ) %    1);}
Timer.prototype.getMins = function(){return Math.floor( Math.floor( this.value      / 60 / 1000 ) %   60);}
Timer.prototype.getSecs = function(){return Math.floor( Math.floor( this.value           / 1000 ) %   60);}
Timer.prototype.getMSec = function(){return Math.floor( Math.floor( this.value                  ) % 1000);}


0
timlg07  09.05.2018, 22:29
@timlg07

@Erzesel so viel Code ist es gar nicht, passt ja alles in eine Zeile ;P

function Timer(t,e,n,i){var o=this;this.isRunning=0,this.nodes=new Array,this.nodes.container=t,this.nodes.output=e,this.nodes.input=n,this.nodes.button=i,this.value=0,this.fps=60,this.nodes.output.innerHTML=this.getFormattedValue(),this.nodes.input.addEventListener("input",function(){o.setValue(o.nodes.input.value)},!1),this.nodes.button.addEventListener("click",function(){o.isRunning?o.stop():o.start()},!1)}window.addEventListener("load",function(){document.querySelectorAll("div.timer").forEach(function(t){var e=document.createElement("p"),n=document.createElement("input"),i=document.createElement("button");t.appendChild(e),t.appendChild(n),t.appendChild(i),n.setAttribute("type","time"),n.setAttribute("value","00:00"),i.innerHTML="START",e.style.width="100%",e.style.marginBottom="6%",e.style.fontSize="200%",e.style.fontFamily="Arial",e.style.textAlign="center",n.style.width="50%",i.style.width="50%",new Timer(t,e,n,i)})}),Timer.prototype.start=function(){var t=this;this.timerID=setInterval(function(){t.value-=1e3/t.fps,t.value<=0&&(t.stop(),t.onExpire(),t.value=0),t.update()},1e3/this.fps),this.nodes.button.innerHTML="STOP",this.isRunning=!this.isRunning},Timer.prototype.stop=function(){clearInterval(this.timerID),this.nodes.button.innerHTML="START",this.isRunning=!this.isRunning},Timer.prototype.update=function(){this.nodes.output.innerHTML=this.getFormattedValue()},Timer.prototype.onExpire=function(){for(var t=this,e=0;e<10;e++)setTimeout(function(){t.nodes.container.style.backgroundColor="#f00"},200*e),setTimeout(function(){t.nodes.container.style.backgroundColor="inherit"},200*e+100)},Timer.prototype.getFormattedValue=function(){return this.f(this.getHour())+":"+this.f(this.getMins())+":"+this.f(this.getSecs())+":"+this.f(this.getMSec())},Timer.prototype.f=function(t){return t.toString().length<2?"0"+t:t.toString().length>2?t.toString().substring(0,2):t},Timer.prototype.setValue=function(t){this.value=60*t.split(":",2)[0]*1e3,this.value+=1e3*t.split(":",2)[1],this.update()},Timer.prototype.getHour=function(){return Math.floor(Math.floor(this.value/60/60/1e3)%1)},Timer.prototype.getMins=function(){return Math.floor(Math.floor(this.value/60/1e3)%60)},Timer.prototype.getSecs=function(){return Math.floor(Math.floor(this.value/1e3)%60)},Timer.prototype.getMSec=function(){return Math.floor(Math.floor(this.value)%1e3)};
0

Var timer = 60

timer = timer - 1

Dann zählt er von 60 runter

Dann nur noch eine if Anweisung

if(timer == 0) {

//hier die Anweisung was passieren soll, wenn er 0 erreicht hat

}


timlg07  08.05.2018, 22:47

ohne setInterval zählt er da nicht runter...

0