Stop watch java script without using Date.getTime() - javascript

As a java script beginner, I wanted to try my hand at writing stop watch code and I wrote the following:
<!DOCTYPE html>
<html>
<body>
<p>A script on this page starts a stopwatch:</p>
<p id="demo"></p>
<button id="start-stop" onclick="myTimerFunction()">Start time</button>
<button id="resetter" style="visibility:hidden" onclick="resetTimer()">Reset</button>
<script>
var timer = new Object();
timer.hours = 0;
timer.minutes = 0;
timer.seconds = 0;
timer.milliseconds = 0;
timer.add = add;
function add() {
timer.milliseconds+=10;
if(timer.milliseconds == 1000) {
timer.seconds++;
timer.milliseconds = 0;
}
if(timer.seconds == 60) {
timer.minutes++;
timer.seconds = 0;
}
if(timer.minutes == 60) {
timer.hours++;
timer.minutes = 0;
}
}
timer.display = display;
function display () {
var str = "";
if(timer.hours<10) {
str += "0";
}
str += timer.hours;
str += ":";
if(timer.minutes<10) {
str += "0";
}
str += timer.minutes;
str += ":";
if(timer.seconds<10) {
str += "0";
}
str += timer.seconds;
str += ":";
/*var x = timer.milliseconds/10;
if(x < 10) {
str += "0";
}*/
if(timer.milliseconds<10) {
str += "0";
}
if(timer.milliseconds<100) {
str += "0";
}
str += timer.milliseconds;
return str;
}
timer.reset = reset;
function reset() {
timer.hours = 0;
timer.minutes = 0;
timer.seconds = 0;
timer.milliseconds = 0;
}
var myVar;
function start() {
timer.add();
var d = new Date();
var t = d.toLocaleTimeString();
document.getElementById("demo").innerHTML = timer.display() + "\t" + t;
}
function stop() {
clearInterval(myVar);
}
function resetTimer() {
stop();
timer.reset();
document.getElementById("demo").innerHTML = timer.display();
document.getElementById("start-stop").innerHTML="Start time";
document.getElementById("resetter").style.visibility="hidden";
}
function myTimerFunction() {
var x = document.getElementById("start-stop");
if(x.innerHTML.match("Start time")) {
document.getElementById("resetter").style.visibility="visible";
myVar = setInterval(function(){start()},10);
x.innerHTML="Stop time";
}
else if(x.innerHTML.match("Stop time")) {
stop();
x.innerHTML="Start time";
}
}
</script>
</body>
</html>
But, the problem is when I put the delay in setInterval(func,delay) as 1 and doing corresponding changes, it is not giving reliable timing for seconds. It is slower than a normal clock. It gives 'kind of' reliable timing for delay >= 10.
I checked for stop watch js scripts online but all of them use some or other form of Date() and set "delay" as "50", which I do not understand why, as of now. There is an answer here in SO which doesn't use Date() but it also has the same problem as mine. I could not comment there as I do not have enough reputation so I am asking a question instead.
So, my question is: Is it impossible to achive normal clock reliability, if we don't use Date() function? Else if it is possible, please help me improve this piece of code or please provide some pointers.
Thanks.

Here's how you'd do it without getTime, which you really shouldn't...
var ms = 0;
var intervalID;
function start() {
var freq = 10; // ms
intervalID = setInterval(function () {
ms += 10;
var myDate = new Date(ms);
document.getElementById('watch').innerHTML = myDate.getUTCHours() + ":" + myDate.getMinutes() + ":" + myDate.getSeconds() +
":" + myDate.getMilliseconds();
}, freq);
}
function stop() {
clearInterval(intervalID);
}
function reset() {
ms = 0;
myDate = new Date(ms);
document.getElementById('watch').innerHTML = myDate.getUTCHours() + ":" + myDate.getMinutes() + ":" + myDate.getSeconds() +
":" + myDate.getMilliseconds();
}
Fiddle

As you've found out setInterval/setTimeout is not reliable. You must use a native time library to get a reliable time.
Since you can't keep the time in JavaScript the idea is that you poll the time, and poll it often so that it looks close enough.
If you naively do:
setInterval(function () {
console.log((new Date()).getTime();
}, 1000); // 1 second
you will see that it will skip seconds.
A better approach is something like:
var last = 0;
setInterval(function () {
var now = Math.floor((new Date()).getTime() / 1000); // now in seconds
if (now !== last) {
console.log(now);
last = now;
}
}, 10); // 10ms

If you want more information as too why JavaScript timers are unreliable, read this great article.
http://ejohn.org/blog/how-javascript-timers-work/

Related

Issue linking images to dynamically created jquery elements

So, I'm very new, so apologies if this is a silly question. I have worked out a Trivia Quiz for my learning to code classes I'm taking. I want to display an image on the confirmation screen that shows whether the user was right or wrong. I think the code is correct-ish? I'm not sure what isn't working.
I left out the main Question and answer object for space. Sorry if I didn't format this ideally? I'm still kinda figuring out how things work here.
Here is my code for reference:
//array to help me iterate and insert images
var imgArray = ["question1", "question2", "question3", "question4", "question5", "question6", "question7", "question8", "question9", "question10", "question11", "question12", "question13"];
var currentQuestion = 0;
var win = 0;
var lose = 0;
var unanswered = 0;
var time = 30;
//set up divs to contain our info
var rightDiv = $("<div class='rightAns'></div>");
var timerDiv = $("<div class='countdown'><h3></h3></div>");
var questionDiv = $("<div class='question'><h1></h1></div><br>");
var answerDiv = $("<div class='answers'></div>");
//object keys to return questions in order
var keys = Object.keys(questions);
var key = keys[n];
var n = 0;
//function to setup and restart game
function reset() {
$("#start-button").hide("slow");
$("#start-here").hide("slow");
win = 0;
lose = 0;
unanswered = 0;
n = 0;
key = keys[n];
currentQuestion = 0;
$("#question-block").empty();
var reset = function () {
time = 30;
$(".rightAns").empty();
$(".rightAns").remove();
// $("#image").empty();
$("#time-remaining").append(timerDiv);
$(".countdown h3").html("Time Remaining: " + time);
$("#question-block").append(questionDiv);
$("#question-block").append(answerDiv);
}
reset();
//function to show questions
function showQuestion() {
$(".question h1").html(questions[key].question);
for (var i = 0; i < questions[key].answers.length; i++) {
$(".answers").append("<button class='answer btn btn-danger btn-lg m-1'>" + questions[key].answers[i] + "</button>");
}
$(".answers button").on("click", function () {
var selected = $(this).text();
//if then to check question correctness
if (selected === questions[key].correct) {
clearInterval(counter);
$(timerDiv).remove();
$(questionDiv).remove();
$(".answers button").remove();
$(answerDiv).remove();
$("#correct-answer").append(rightDiv);
$(".rightAns").text("That's Correct!!");
$("#image").html('<img src = ".assets/images/' + imgArray[currentQuestion] + '" width = "400px">');
win++;
currentQuestion++;
} else {
clearInterval(counter);
$(timerDiv).remove();
$(questionDiv).remove();
$(".answers button").remove();
$(answerDiv).remove();
$("#correct-answer").append(rightDiv);
$(".rightAns").text("Nope! The correct answer was: " + questions[key].correct);
$("#image").html('<img src = ".assets/images/' + imgArray[currentQuestion] + '" width = "400px">');
lose++;
currentQuestion++;
}
n++;
key = keys[n];
//checking to see if there are more questions left
if (checkForLast()) {
finalScore();
} else {
setTimeout(countReset, 3 * 1000);
setTimeout(reset, 3 * 1000);
setTimeout(showQuestion, 3 * 1000);
}
});
}
showQuestion();
var counter = setInterval(count, 1000);
//show time remaining for each question
function count() {
time--;
$(".countdown h3").html("Time Remaining: " + time);
if (time < 1) {
clearInterval(counter);
$(timerDiv).remove();
$(questionDiv).remove();
$(".answers button").remove();
$("#correct-answer").append(rightDiv);
$(".rightAns").html("You took too long! The correct answer was: " + questions[key].correct);
unanswered++;
n++;
key = keys[n];
if (checkForLast()) {
finalScore();
} else {
setTimeout(countReset, 3 * 1000);
setTimeout(reset, 3 * 1000);
setTimeout(showQuestion, 3 * 1000);
}
}
}
function checkForLast() {
if (key === undefined) {
return true;
}
return false;
}
//timer for the message after you choose your answer
function countReset() {
counter = setInterval(count, 1000);
}
//showthe final score screen
function finalScore() {
$(".rightAns").remove();
$("#image").empty();
$("#question-block").prepend("<h2>Unanswered: " + unanswered + "</h2>");
$("#question-block").prepend("<h2>Incorrect: " + lose + "</h2>");
$("#question-block").prepend("<h2>Correct: " + win + "</h2>");
$("#start-button").show();
$("#start-here").show();
}
};
//function to start game on button click
$(document).on("click", "#start-button", reset);
});
After tinkering for a bit, I dropped the "." at the beginning of the call and added the .jpg to the section after imgArray[currentQuestion]. That solved it. Thanks for the suggestions.

What is wrong with countdown timer program?

I'm trying to make a countdown timer to go from 15 minutes 0 seconds to 0 minutes 0 seconds but it appears that it doesn't want to display in JsFiddle. Another program is that my date variable isn't actually set to 15 minutes and 0 seconds. How can I fix this?
var date = new Date();
var sec = date.getSeconds();
var min = date.getMinutes();
var handler = function() {
sec--;
if (sec == 60) {
sec = 0;
min--;
else if (sec < 0) {
date.setSeconds(0);
} else if (min < 0) {
date.setMinutes(0);
}
}
document.getElementById("time").innerHTML = (min < 10 ? "0" + min : min) + ":" + (sec < 10 ? "0" + sec : sec);
};
handler();
setInterval(handler, 1000);
<b>Offer Ends In:</b>
<h1 id="time" style="text-align: center"></h1>
Well, for one thing, you don't have a closing brace before the else, so it won't even run as is.
In addition, I'm not sure why you need to fiddle around with date objects for a countdown timer, since the current date/time is irrelevant.
You should start with something like:
function pad2(s) {
return ("00" + s).slice(-2);
}
var handler = function() {
if (--sec < 0) {
sec = 59;
if (--min < 0) {
min = 0;
sec = 0;
}
}
document.getElementById("time").innerHTML = pad2(min) + ":" + pad2(sec);
};
var sec = 1;
var min = 15;
handler();
setInterval(handler, 1000);
You'll notice I've refactored out the padding code since it's "questionable" whether you should ever violate the DRY principle. You certainly shouldn't violate it twice on a single line :-)
In terms of testing, you can create a simple static page which runs the timer as follows.
I've also reduced starting time to a little over ten minutes and accelerated time ten-fold so you don't have to wait around for a full quarter hour to test the whole thing (it should take a smidgen more than a minute to complete).
<html>
<body>
<b>Offer Ends In:</b>
<h1 id="time" style="text-align: left"></h1>
<script type="text/javascript">
function pad2(s) {
return ("00" + s).slice(-2);
}
var handler = function() {
if (--sec < 0) {
sec = 59;
if (--min < 0) {
min = sec = 0;
}
}
document.getElementById("time").innerHTML = pad2(min) + ":" + pad2(sec);
};
var sec = 6;
var min = 10;
handler();
setInterval(handler, 100); // 10x normal speed, use 1000 for reality
</script>
</body>
</html>
For starters, you do not have a closing brace before the else if and you need to remove the brace before your document.getElementById
1) Closed your curly-bracket for your if condition.
2) Your code failed to load properly because your JavaScript loads before the page recognizes the time DIV element. Since you didn't use an event listener for the page loading first, I added that... and it seems to be working.
3) Important note... The timer logic needs a lot of work... You're better off using a time DIFF statement otherwise you've got about 200-300 lines more to write just on calculating seconds, minutes, hours, days etc.
Looking at the page as it stands has this... 15:0-289
** Update ** adding the padding technique rectified the above note...
Here's a solution for that.
Check time difference in Javascript
<html>
<head>
<script type="text/javascript">
var date = new Date();
var sec = date.getSeconds();
var min = date.getMinutes();
document.addEventListener("DOMContentLoaded", function(event) {
var myTimer = setInterval(handler, 1000);
});
function pad2(s) {
return ("00" + s).slice(-2);
}
var handler = function() {
if (--sec < 0) {
sec = 59;
if (--min < 0) {
min = 0;
sec = 0;
}
}
document.getElementById("time").innerHTML = pad2(min) + ":" + pad2(sec);
};
</script>
</head>
<body>
<b>Offer Ends In:</b>
<h1 id="time" style="text-align: center"></h1>
</body>
</html>
I just made this StopWatch. You can use it without a button and it will work like you want.
//<![CDATA[
/* external.js */
var doc, bod, htm, C, E, T, MillisecondConverter, StopWatch; // for use on other loads
addEventListener('load', function(){
var doc = document, bod = doc.body, htm = doc.documentElement;
C = function(tag){
return doc.createElement(tag);
}
E = function(id){
return doc.getElementById(id);
}
T = function(tag){
return doc.getElementsByTagName(tag);
}
MillisecondConverter = function(milliseconds, displayMilliseconds){
var ms = milliseconds, rh = ms/3600000, hp = Math.pow(10, rh.toString().length-2);
this.hours = Math.floor(rh);
var rm = (rh*hp-this.hours*hp)/hp*60, mp = Math.pow(10, rm.toString().length-2);
this.minutes = Math.floor(rm);
var rs = (rm*mp-this.minutes*mp)/mp*60, sp = Math.pow(10, rs.toString().length-2);
if(displayMilliseconds){
this.seconds = Math.floor(rs);
this.milliseconds = Math.round((rs*sp-this.seconds*sp)/sp*1000);
}
else{
this.seconds = Math.round(rs);
}
this.convert = function(){
return this.hours.toString().replace(/^([0-9])$/, '0$1')+':'+this.minutes.toString().replace(/^([0-9])$/, '0$1')+':'+this.seconds.toString().replace(/^([0-9])$/, '0$1');
}
}
StopWatch = function(displayNode, millisecondInterval){
this.hours = this.minutes = this.seconds = this.milliseconds = 0;
this.millisecondInterval = millisecondInterval || 1000;
this.displayNode = displayNode; this.began = false; this.paused = false;
var t = this, ms, iv, fi;
this.begin = function(doneFunc, context){
var c = context || this;
ms = this.hours*3600000+this.minutes*60000+this.seconds*1000+this.milliseconds;
var mc = new MillisecondConverter(ms), dn = this.displayNode, cv = mc.convert();
if(dn.innerHTML || dn.innerHTML === ''){
dn.innerHTML = cv;
}
else{
dn.value = cv;
}
this.began = true;
fi = function(mi){
var nd = new Date, bt = nd.getTime(), ii = t.millisecondInterval;
ms = mi;
iv = setInterval(function(){
var nd = new Date, ct = nd.getTime(), tl = ct-bt;
var mc = new MillisecondConverter(mi-tl), dn = t.displayNode;
if(tl >= mi){
clearInterval(iv); doneFunc.call(c); cv = '00:00:00';
if(dn.innerHTML || dn.innerHTML === ''){
dn.innerHTML = cv;
}
else{
dn.value = cv;
}
t.began = false;
return;
}
cv = mc.convert(); ms -= ii;
if(dn.innerHTML || dn.innerHTML === ''){
dn.innerHTML = cv;
}
else{
dn.value = cv;
}
}, ii);
}
fi(ms);
}
this.pause = function(){
clearInterval(iv); iv = undefined; this.paused = true;
return this;
}
this.resume = function(){
fi(ms); this.paused = false;
return this;
}
}
var cd = new StopWatch(E('remain')), out = E('out');
cd.seconds = 30;
E('btn').addEventListener('click', function(){
if(!cd.began){
out.innerHTML = '';
cd.begin(function(){
out.innerHTML = 'Countdown Complete';
});
}
else{
cd.paused ? cd.resume() : cd.pause();
}
});
});
//]]>
/* external.css */
html,body{
padding:0; margin:0;
}
.main{
width:980px; margin:0 auto;
}
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
<meta http-equiv='content-type' content='text/html;charset=utf-8' />
<title>StopWatch</title>
<link type='text/css' rel='stylesheet' href='external.css' />
<script type='text/javascript' src='external.js'></script>
</head>
<body>
<div class='main'>
<div id='remain'>00:00:30</div>
<input id='btn' type='button' value='StopWatch' />
<div id='out'></div>
</div>
</body>
</html>

Confused about SetInterval and closures

How can we repeatedly update the contents of a div using setInterval
I am using the question from this link as a reference How to repeatedly update the contents of a <div> by only using JavaScript?
but i have got few questions here
Can we do it without anonymous functions,using closures. I have tried but could not end up with any workable solution.
How can we make it run infinitely, with the following code it gets stopped once i reaches 10.
window.onload = function() {
var timing = document.getElementById("timer");
var i = 0;
var interval = setInterval(function() {
timing.innerHTML = i++;
if (i > 10) {
clearInterval(interval);
i = 0;
return;
}
}, 1000);
}
<div id="timer"></div>
I am confused about setIntervals and closures
can some one help me here
Thanks
You could do something like this with a closure. Just reset your i value so, you will always be within your given range.
window.onload = function() {
var updateContent = (function(idx) {
return function() {
if (idx === 10) {
idx = 0;
}
var timing = document.getElementById("timer");
timing.innerHTML = idx++;
}
})(0);
var interval = setInterval(updateContent, 1000);
}
<div id="timer"></div>
This one should be clearer.
function updateTimer() {
var timer = document.getElementById("timer");
var timerValue = parseInt(timer.getAttribute("data-timer-value")) + 1;
if (timerValue == 10) {
timerValue = 0;
}
timer.setAttribute("data-timer-value", timerValue);
timer.innerHTML = "the time is " + timerValue;
}
window.onload = function() {
setInterval(updateTimer, 1000);
}
<div id="timer" data-timer-value="0"></div>

Where do I place my "document.getElementById("").innerHTML = "";" Within my Javascript?

At the moment I am creating an on screen timer in javascript. This is the code for my timer:
var i = 30;
function startTimer() {
var countdownTimer = setInterval(function() {
console.log(i);
i = i - 1;
if (i < 0) {
clearInterval(countdownTimer);
}
}, 1000);
}
I am just wondering where I should place my document.getElementById("time-remaining").innerHTML = "Time Remaining:" + i;
I am also wondering if the above document.getElementById is correct (will it be displayed as a onscreen timer or will it fail or something)?
Thanks in advanced.
Try this:
var i = 30;
function startTimer() {
var countdownTimer = setInterval(function () {
console.log(i);
i = i - 1;
if (i < 0) {
clearInterval(countdownTimer);
return; //This will prevent -1 to be written to html
}
document.getElementById("time-remaining").innerHTML = "Time Remaining:" + i;
}, 1000);
}
startTimer();
Dont forget to call the function.
Demo: http://jsfiddle.net/GCu2D/842/
You can put the
document.getElementById("time-remaining").innerHTML = "Time Remaining:" + i;
After the startTimer function or really anywhere.
And yes thedocument.getElementById is correct, if your html id is the same one as in javascript.

Pure JavaScript fade in function

Hi friends i want to fade in a div when i click on another div and for that i am using following code. Code1 works fine but i require to use the Code2.
I know there is jQuery but i require to do this in JavaScript
Can you guide me that what kind of mistake i am doing or what i need change...
Code1 --- Works Fine
function starter() { fin(); }
function fin()
{
for (i = 0; i <= 1; i += 0.01)
{
i=Math.round(i*100)/100;
setTimeout("seto(" + i + ")", i * 1000);
}
}
function seto(opa)
{
var ele = document.getElementById("div1");
ele.style.opacity = opa;
}
Code2 --- Does not work
function starter()
{
var ele = document.getElementById("div1");
fin(ele);
}
function fin(ele)
{
for (i = 0; i <= 1; i += 0.01)
{
i=Math.round(i*100)/100;
setTimeout("seto(" + ele + "," + i + ")", i * 1000);
}
}
function seto(ele,opa)
{
ele.style.opacity = opa;
}
Based on this site
EDIT-1
Added the functionality so that user can specify the animation duration(#Marzian comment)
You can try this:
function fadeIn(el, time) {
el.style.opacity = 0;
var last = +new Date();
var tick = function() {
el.style.opacity = +el.style.opacity + (new Date() - last) / time;
last = +new Date();
if (+el.style.opacity < 1) {
(window.requestAnimationFrame && requestAnimationFrame(tick)) || setTimeout(tick, 16);
}
};
tick();
}
var el = document.getElementById("div1");
fadeIn(el, 3000); //first argument is the element and second the animation duration in ms
DEMO
Update:
It seems that people enjoy my minimalistic and elegant approach, Updated for 2022:
No need for complex mechanisms. Just use CSS, which has it out of the box and has better performance overall.
Basically you achieve it with CSS by setting a transition for the opacity. In JavaScript that would be:
const div = document.querySelector('#my-div');
div.style.transition='opacity 1s';
and as a trigger you just set opacity to 0:
div.style.opacity=0;
This will create a 1 second fade out effect and you can use the trigger anywhere. The inverse can also be done to achieve a fade in effect.
Here's a working example:
const div = document.querySelector('#my-div');
div.style.transition='opacity 1s';
// set opacity to 0 -> fade out
setInterval(() => div.style.opacity=0, 1000);
// set opacity to 1 -> fade in
setInterval(() => div.style.opacity=1, 2000);
#my-div { background-color:#FF0000; width:100%; height:100%; padding: 10px; color: #FFF; }
<div id="my-div">Hello!</div>
Seems like your attempting to convert your element, to a string. Try this instead
function starter()
{
var ele = document.getElementById("div1");
fin(ele);
}
function fin(ele)
{
for (i = 0; i <= 1; i += 0.01)
{
i=Math.round(i*100)/100;
setTimeout(function() { setto(ele,i); }, i * 1000);
}
}
function seto(ele,opa)
{
ele.style.opacity = opa;
}
What happens here is, that i call a anonnymous function when the timer hits, and from that function, execute my functioncall to setto.
Hope it helps.
Jonas
The problem here is you are using the pass-a-string method of using setTimeout. Which is basically just a hidden eval.
It's worth noting that this is a bad practice, slow performer, and security risk.
(see questions such as this: setTimeout() with string or (anonymous) function reference? speedwise)
The reason this is causing your problem is because "seto(" + ele + "," + i + ")" is going to evaluate to "seto('[object HTMLDivElement]', 1)". You really want to pass reference to the ele object -- but the value's being cast to a string when you tried concatenating an object onto a string. You can get around this by using the pass-a-function method of using setTImeout.
setTimeout(function() { seto(ele, i); }, i * 1000);
I believe making this change will make your Code2 behavior equivalent to Code1.
Below are the complete answers to my question
ANS1 --- DEMO
function fin() {
var i = 0;
var el = document.getElementById("div1");
fadeIn(el,i);
}
function fadeIn(el,i) {
i = i + 0.01;
seto(el,i);
if (i<1){setTimeout(function(){fadeIn(el,i);}, 10);}
}
function seto(el,i) {
el.style.opacity = i;
}
ANS2 --- DEMO
function fin(){
var i = 0;
var el = document.getElementById("div1");
fadeIn(el,i);
}
function fadeIn(el,i) {
var go = function(i) {
setTimeout( function(){ seto(el,i); } , i * 1000);
};
for ( i = 0 ; i<=1 ; i = i + 0.01) go(i);
}
function seto(el,i)
{
el.style.opacity = i;
}
My version
function fadeIn($element){
$element.style.display="block";
$element.style.opacity=0;
recurseWithDelayUp($element,0,1);
}
function fadeOut($element){
$element.style.display="block";
$element.style.opacity=1;
recurseWithDelayDown($element,1,0);
}
function recurseWithDelayDown($element,startFrom,stopAt){
window.setTimeout(function(){
if(startFrom > stopAt ){
startFrom=startFrom - 0.1;
recurseWithDelayDown($element,startFrom,stopAt)
$element.style.opacity=startFrom;
}else{
$element.style.display="none"
}
},30);
}
function recurseWithDelayUp($element,startFrom,stopAt){
window.setTimeout(function(){
if(startFrom < stopAt ){
startFrom=startFrom + 0.1;
recurseWithDelayUp($element,startFrom,stopAt)
$element.style.opacity=startFrom;
}else{
$element.style.display="block"
}
},30);
}
function hide(fn){
var hideEle = document.getElementById('myElement');
hideEle.style.opacity = 1;
var fadeEffect = setInterval(function() {
if (hideEle.style.opacity < 0.1)
{
hideEle.style.display='none';
fn();
clearInterval(fadeEffect);
}
else
{
hideEle.style.opacity -= 0.1;
}
}, 20);
}
function show(){
var showEle = document.getElementById('myElement');
showEle.style.opacity = 0;
showEle.style.display='block';
var i = 0;
fadeIn(showEle,i);
function fadeIn(showEle,i) {
i = i + 0.05;
seto(showEle,i);
if (i<1){setTimeout(function(){fadeIn(showEle,i);}, 25);}
}
function seto(el,i)
{
el.style.opacity = i;
}
}
hide(show);
I just improved on laaposto's answer to include a callback.
I also added a fade_out function.
It could be made more efficient, but it works great for what i'm doing.
Look at laaposto's answer for implementation instructions.
You can replace the JS in his fiddle with mine and see the example.
Thanks laaposto!
This really helped out for my project that requires zero dependencies.
let el = document.getElementById( "div1" );
function fade_in( element, duration, callback = '' ) {
element.style.opacity = 0;
let last = +new Date();
let tick = function() {
element.style.opacity = +element.style.opacity + ( new Date() - last ) / duration;
last = +new Date();
if ( +element.style.opacity < 1 )
( window.requestAnimationFrame && requestAnimationFrame( tick ) ) || setTimeout( tick, 16 );
else if ( callback !== '' )
callback();
};
tick();
}
function fade_out( element, duration, callback = '' ) {
element.style.opacity = 1;
let last = +new Date();
let tick = function() {
element.style.opacity = +element.style.opacity - ( new Date() - last ) / duration;
last = +new Date();
if ( +element.style.opacity > 0 )
( window.requestAnimationFrame && requestAnimationFrame( tick ) ) || setTimeout( tick, 16 );
else if ( callback !== '' )
callback();
};
tick();
}
fade_out( el, 3000, function(){ fade_in( el, 3000 ) } );
Cheers!

Categories

Resources