Starting second javascript when the first one is finished - javascript

I'm working on a progress bar. It has a label. I want to adjust that label a certain script is finished. After finding some answers of probable solution, I came up with the following script. The first initiates and works as expected. However, the second one doesn't. What's wrong with it? Here's the code:
HTML:
<form method ="post">
<input class=generate type="submit" value="Upload" onclick="move();finalize()"/>
</form>
Javascript:
<script>
function move() {
var elem = document.getElementById("myBar");
var myFunc01 = function() {
var i = 1;
while (i < 101) {
(function(i) {
setTimeout(function() {
i++;
elem.style.width = i + '%';
elem.innerHTML = i + '%';
}, 600 * i)
})(i++)
}
};
myFunc01();
}
</script>
<script>
function finalize() {
var elem = document.getElementById("myBar");
var myFunc02 = function() {
elem.innerHTML = 'Finalizing...';
};
setTimeout(myFunc02, 600);
}
</script>

var elem = document.querySelector('#myBar');
function done() {
elem.innerText = 'UPLOAD HAS FINISHED';
}
var upload = function(callback) {
var width = 1;
var id;
var frame = function() {
if (width >= 100) {
clearInterval(id);
callback();
} else {
width++;
elem.style.width = width + '%';
}
};
id = setInterval(frame, 10);
};
/*
upload(function() {
elem.innerText = 'UPLOAD HAS FINISHED';
});
*/
#myProgress {
width: 100%;
background-color: grey;
}
#myBar {
width: 1%;
height: 30px;
background-color: green;
text-align: center;
line-height: 27px;
}
<button onclick="upload(done)">START UPLOAD</button>
<div id="myProgress">
<div id="myBar"></div>
</div>

You could use a callback. A callback is a function that runs upon completion.
function move(callback) {
//code you want to happen first
}
move(function(){
//code you want to have happen after completion
})
thats the basic idea of how a simple callback works

Thanks James, that's it!
After some re-arranging, this is what the second script looks like. And it works as expected.
<script>
function finalize() {setTimeout(function(){
var elem = document.getElementById("myBar");
var myFunc02 = function() {
elem.innerHTML = 'Finalizing...';
};
myFunc02();
}
, 600);}
</script>

Related

How to wait for the function to end before start the function again

How to wait for my first function to end before I can click "Click me" button again. I have been searching for a way to let my function end first before I can let the new function run again.
document.getElementById("myBtn").addEventListener("click", myFunction);
setTimeout(function() {
myFunction();
}, 3000);
var id = null;
function myFunction() {
var elem = document.getElementById("myAnimation");
var pos = 0;
clearInterval(id);
id = setInterval(frame, 10);
function frame() {
if (pos == 350) {
clearInterval(id);
} else {
pos++;
elem.style.top = pos + 'px';
elem.style.left = pos + 'px';
}
}
}
#myContainer {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#myAnimation {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}
<h2>JavaScript addEventListener()</h2>
<button id="myBtn">Click Me</button>
<div id="myContainer">
<div id="myAnimation"></div>
If we disable and enable the button in the correct place, it will work quite nicely
I also cleaned up the code a bit to make it more contained.
window.addEventListener('DOMContentLoaded', () => {
const myBtn = document.getElementById("myBtn");
const elem = document.getElementById("myAnimation");
let id = null;
let pos = 0;
const frame = () => {
if (pos == 350) {
clearInterval(id);
myBtn.disabled = false;
} else {
pos++;
elem.style.top = pos + 'px';
elem.style.left = pos + 'px';
}
}
const myFunction = () => {
pos = 0;
clearInterval(id);
id = setInterval(frame, 10);
myBtn.disabled = true;
}
id = setTimeout(myFunction, 3000);
myBtn.addEventListener("click", myFunction);
});
#myContainer {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#myAnimation {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}
<h2>JavaScript addEventListener()</h2>
<button id="myBtn">Click Me</button>
<div id="myContainer">
<div id="myAnimation"></div>
</div>
As a first implementation you could disable the button before you start the animation, and you only enable it after you are done
var myBtn = document.getElementById("myBtn")
myBtn.addEventListener("click", myFunction);
setTimeout(function() {
myFunction();
}, 3000);
var id = null;
function myFunction() {
var elem = document.getElementById("myAnimation");
var pos = 0;
clearInterval(id);
id = setInterval(frame, 10);
// disable the button
myBtn.disabled = true;
function frame() {
if (pos == 350) {
clearInterval(id);
// enable the button again
myBtn.disabled = false;
} else {
pos++;
elem.style.top = pos + 'px';
elem.style.left = pos + 'px';
}
}
}
#myContainer {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#myAnimation {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}
<h2>JavaScript addEventListener()</h2>
<button id="myBtn">Click Me</button>
<div id="myContainer">
<div id="myAnimation"></div>
You should disable your button during your function.
edited: If you don't want to disable maybe with a lock.
document.getElementById("myBtn").addEventListener("click", myFunction);
setTimeout(function() {
myFunction();
}, 3000);
var id = null;
var lock = false;
function myFunction() {
if(!lock){
lock = true;
var elem = document.getElementById("myAnimation");
var pos = 0;
clearInterval(id);
id = setInterval(frame, 10);
function frame() {
if (pos == 350) {
clearInterval(id);
lock = false;
} else {
pos++;
elem.style.top = pos + 'px';
elem.style.left = pos + 'px';
}
}
}
}
#myContainer {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#myAnimation {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}
<h2>JavaScript addEventListener()</h2>
<button id="myBtn">Click Me</button>
<div id="myContainer">
<div id="myAnimation"></div>
edited: Try making your animation with CSS it's a better practice.
let sum = 0;
const x = 10;
async function firstFunction() {
for (i = 0; i < x; i++) {
sum = sum + i;
}
return sum;
}
async function secondFunction() {
await firstFunction();
console.log('After firstFunction executed sum is', sum);
}
secondFunction();

JavaScript animation scroll up and down

How do you make JavaScript animation scroll both to the bottom of an element and back to the top? I am still learning about JavaScript and found an example code from w3schools, which, when I modified it to scroll back to the top, worked in the Tryit Editor, using the exact same code for the myUP function I have below. Though I know that in its current state, combined with the other function, this same code is not currently working.
I have a hunch that there was something not good about the code, even when it worked fine by itself in the Tryit Editor. I feel that in the future it would not work properly. Am I right to assume this, and, if so, what should I be doing to achieve this in JavaScript instead?
<html>
<style>
#myContainer {
width: 500px;
height: 500px;
position: relative;
background: black;
}
#tester {
width: 500px;
height: 50px;
position: absolute;
background-color: gray;
}
</style>
<body>
<p>
<button onmousedown="myMove()">DOWN</button>
</p>
<p>
<button onmousedown="myUP()">UP</button>
</p>
<div id ="myContainer">
<div id ="tester"></div>
</div>
<script>
function myMove() {
var elem = document.getElementById("tester");
var pos = 0;
var id = setInterval(frame, 20);
function frame() {
if (pos == 500) {
clearInterval(id);
} else {
pos++;
elem.style.top = pos + 'px';
}
}
}
function myUP() {
var elem = document.getElementById("tester");
var pos = 0;
var id = setInterval(frame, 20);
function frame() {
if (pos == 500) {
clearInterval(id);
} else {
pos++;
elem.style.bottom = pos + 'px';
}
}
}
</script>
</body>
Check the working code now,
Your code were making problem in UP function.
function myUP() {
var elem = document.getElementById("tester");
var pos = 500;// Changed the max position.
var id = setInterval(frame, 20);
function frame() {
console.log(pos);
if (pos == 0) { //reverse condition to 0
clearInterval(id);
} else {
pos--; // reverse the position
elem.style.top = pos + 'px'; // that should be back to top
}
}
}
<html>
<style>
#myContainer {
width: 500px;
height: 500px;
position: relative;
background: black;
}
#tester {
width: 500px;
height: 50px;
position: absolute;
background-color: gray;
}
</style>
<body>
<p>
<button onmousedown="myMove()">DOWN</button>
</p>
<p>
<button onmousedown="myUP()">UP</button>
</p>
<div id ="myContainer">
<div id ="tester"></div>
</div>
<script>
function myMove() {
var elem = document.getElementById("tester");
var pos = 0;
var id = setInterval(frame, 20);
function frame() {
if (pos == 500) {
clearInterval(id);
} else {
pos++;
elem.style.top = pos + 'px';
}
}
}
function myUP() {
var elem = document.getElementById("tester");
var pos = 500;
var id = setInterval(frame, 5);
function frame() {
console.log(pos);
if (pos == 0) {
clearInterval(id);
} else {
pos--;
elem.style.top = pos + 'px';
}
}
}
</script>
</body>

setInterval wont work if timing is too short

I have a setInterval function that wont execute if the increment is less than 101ms. The timing will go any number above 100ms. I want to be able to increment the function by 10ms. offY and strtPos also become undefined when the timing goes below 101ms. How do I make it work the same as it is, but instead, have it incremented by 10ms?
var strtPos;
var offY;
var offX;
var hold = true;
var obj = document.getElementById('obj');
var st = function() {
offY = obj.offsetTop;
}
var init = setInterval(function() {
other()
}, 101); //<-- When I change that value to below 101, it prevents the code from working
var other = function() {
if (hold) {
strt();
hold = false
};
console.log(offY)
console.log(strtPos)
if (strtPos - 100 <= offY) {
obj.style.top = (offY - 11) + "px";
} else {
clearInterval(init);
hold = true;
}
}
var strt = function() {
strtPos = offY
}
setInterval(st, 100)
body {
margin: 0;
}
#obj {
width: 50px;
height: 100px;
background-color: red;
position: fixed;
}
<div id="obj"></div>
The short answer is you need to give offY a value that is not undefined initially, so I've rearranged the variables at the top of your code.
Originally, offY only gets a value after ~100ms (setInterval(st, 100)), and without a value that is not undefined the otherfunction's calculations won't work. So you needed the st function to execute first, hence requiring a value > 100.
var strtPos;
var offX;
var hold = true;
var obj = document.getElementById('obj');
var offY = obj.offsetTop;
var st = function() {
offY = obj.offsetTop;
}
var init = setInterval(function() {
other()
}, 10);
var other = function() {
if (hold) {
strt();
hold = false
};
console.log(offY)
console.log(strtPos)
if (strtPos - 100 <= offY) {
obj.style.top = (offY - 11) + "px";
} else {
clearInterval(init);
hold = true;
}
}
var strt = function() {
strtPos = offY
}
setInterval(st, 100)
body {
margin: 0;
}
#obj {
width: 50px;
height: 100px;
background-color: red;
position: fixed;
}
<div id="obj"></div>

Javascript - Animation only working the first time the button is pressed

I have an animation which is called using onmousedown. I have another function which stops the animation (onmouseup).
The problem is that it only works the first time. By that I mean when I hold the button, it works and then stops when I stop pressing down but if I try to use either of the buttons after that first time nothing happens. It just won't move.
This is my HTML code (index.htm):
<html>
<head><link rel='stylesheet' href='style.css'></head>
<body>
<img id='player' src='img/player.png' style='height:64px;'></img>
<div class='buttons'>
<button id='moveleft' onmousedown="OnButtonDownl (this)" onmouseup="OnButtonUpl (this)"><--</button>
<button id='moveright' onmousedown="OnButtonDownr (this)" onmouseup="OnButtonUpr (this)">--></button>
</div>
</body>
</html>
<script type='text/javascript' src='move.js'></script>
This is my javascript code (move.js):
var elem = document.getElementById("player");
function OnButtonDownl (button) {
var posl = document.getElementById("player").style.left;
window.idl = setInterval(framel, 5);
function framel() {
posl--;
elem.style.left = posl + 'px';
}}
function OnButtonUpl (button) {
clearInterval(idl);
}
var elem = document.getElementById("player");
function OnButtonDownr (button) {
var posr = document.getElementById("player").style.left;
window.idr = setInterval(framer, 5);
function framer() {
posr++;
elem.style.left = posr + 'px';
}}
function OnButtonUpr (button) {
clearInterval(idr);
}
Probably not important but here is my css (style.css):
body {
width: 100%;
height: 100%;
position:relative;
margin:0;
overflow:hidden;
}
#player {
position: absolute;
left:0;
bottom:0;
}
.buttons {
position:absolute;
right:0;
bottom:0;
}
Thanks for any help in advance.
You're running into 2 issues.
When you first get posl and posr, you're getting an empty string that JS is coercing to 0.
The -- and ++ won't work after you append the px (thus making posl and posr into string values)
Your posl-- (and posr++) can increment that coerced 0. That's why it works the first time through. The next time you mousedown the document.getElementById("player").style.left is a string — like "-1px" — that isn't interpreted as falsy (won't be coerced into 0). You can get around that by using parseInt() when you cache posl|posr but you have to provide a fallback of 0 because parseInt("") returns NaN…
You can work around that like so (with similar changes when you get posr):
var posl = parseInt( document.getElementById("player").style.left, 10 ) || 0;
var elem = document.getElementById("player");
function OnButtonDownl(button) {
//var posl = document.getElementById("player").style.left;
var posl = parseInt(document.getElementById("player").style.left, 10) || 0;
window.idl = setInterval(framel, 5);
function framel() {
posl--;
elem.style.left = posl + 'px';
}
}
function OnButtonUpl(button) {
clearInterval(idl);
}
var elem = document.getElementById("player");
function OnButtonDownr(button) {
//var posr = document.getElementById("player").style.left;
var posr = parseInt(document.getElementById("player").style.left, 10) || 0;
window.idr = setInterval(framer, 5);
function framer() {
posr++;
elem.style.left = posr + 'px';
}
}
function OnButtonUpr(button) {
clearInterval(idr);
}
body {
width: 100vw;// changed for example only
height: 100vh;// changed for example only
position: relative;
margin: 0;
overflow: hidden;
}
#player {
position: absolute;
left: 0;
bottom: 0;
}
.buttons {
position: absolute;
right: 0;
bottom: 0;
}
<img id='player' src='//placekitten.com/102/102' />
<div class='buttons'>
<button id='moveleft' onmousedown="OnButtonDownl (this)" onmouseup="OnButtonUpl (this)">Left</button>
<button id='moveright' onmousedown="OnButtonDownr (this)" onmouseup="OnButtonUpr (this)">Right</button>
</div>
I was rewrite your code and it work (for me).
function Move(elem){
this.interval;
var posr = parseInt(getComputedStyle(document.getElementById("player")).left);
this.handleEvent = function(event) {
switch (event.type) {
case 'mousedown':
this.interval = setInterval(function() {
if (event.target.id == 'moveright') {
posr++;
} else if (event.target.id == 'moveleft'){
posr--;
}
document.getElementById("player").style.left = posr + 'px';
},5);
break;
case 'mouseup':
clearInterval(this.interval);
break;
}
}
elem.addEventListener('mousedown', this, false);
elem.addEventListener('mouseup', this, false);
}
var button_right = document.getElementById("moveright");
var button_left = document.getElementById("moveleft");
Move(button_right);
Move(button_left);
And in html you can remove js event listeners (this need only id).
First of all it is good practice to put your script tag inside your html tags:
<html>
<head>...</head>
<body>...</body>
<script type='text/javascript' src='move.js'></script>
</html>
Done that check this solution:
HTML:
<html>
<head><link rel='stylesheet' href='style.css'></head>
<body>
<img id='player' src='https://placeimg.com/54/45/any' style='height:64px;'></img>
<div class='buttons'>
<button id='moveleft' onmousedown="OnButtonDown('left')" onmouseup="OnButtonUp()"><--</button>
<button id='moveright' onmousedown="OnButtonDown('right')" onmouseup="OnButtonUp()">--></button>
</div>
<script type='text/javascript' src='move.js'></script>
</body>
</html>
And js:
var nIntervId;
var b;
var elem = document.getElementById("player");
var posl = document.getElementById("player").style.left;
function OnButtonDown(button) {
b = button;
nIntervId = setInterval(frame, 5);
}
function frame() {
if(b==='left'){
posl--;
elem.style.left = posl + 'px';}
else{
posl++;
elem.style.left = posl + 'px';
}
}
function OnButtonUp() {
clearInterval(nIntervId);
}
http://output.jsbin.com/varaseheru/

I get [Object Error] When I use a timer in IE Mobile

I am trying to display 1 image after another in IE Mobile. The following code works in IE Desktop but I get an [Object error] If I run it in IE Mobile.
This is the code:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/javascript">
var interval = 30;
var _timer;
var _index = 0;
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<a href="#" title="Play Motion Clip from Beginning" onclick="test();">
<img alt="Play Motion" src="../Images/play_green_controls.png" style="border-style: none; width: 32px; height: 32px; background-color: #000000; cursor: pointer;" id="btnPlay" />
</a>
<img alt="" src="../0000.jpg" id="imgLive" />
<div id="divImage" style="width: 352px; height: 288px; display: none; background-image: url('Portal/Catalogues/000EC902F17F/3/2013/10/6/10/60b01a71-27f9-4122-ae8e-674e65a8b4dd/20131006102041027x75x0.04x0.40x.img00001.jpg');
background-repeat: no-repeat;">
</div>
<div id="divImageCache1" style="width: 352px; height: 288px; display: none;">
<img alt="" src="../0000.jpg" id="imgCached" />
</div>
</div>
</form>
<script type="text/javascript">
function test() {
try {
_timer = setInterval(swapImages(), interval);
}
catch (e) {
alert(e);
}
}
var imgCached = document.getElementById('imgCached');
var imgLive = document.getElementById('imgLive');
function OnImgLoaded() {
imgLive.src = imgCached.src;
}
function swapImages() {
imgCached.onload = OnImgLoaded();
imgCached.src = 'my irl/' + '0000' + _index + '.jpg';
_index = _index + 1;
if (_index == 10) {
_index = 0;
clearTimeout(_timer);
}
}
</script>
</body>
</html>
To debug I changed the javascript to this:
<script type="text/javascript">
function test() {
try {
alert('hi1');
_timer = setInterval(swapImages(), interval);
alert('hi2');
}
catch (e) {
alert(e);
}
}
var imgCached = document.getElementById('imgCached');
var imgLive = document.getElementById('imgLive');
function OnImgLoaded() {
imgLive.src = imgCached.src;
}
function swapImages() {
alert('hi3');
imgCached.onload = OnImgLoaded();
imgCached.src = 'http://www.url.co.uk/Cloud/test/' + '0000' + _index + '.jpg';
_index = _index + 1;
if (_index == 10) {
_index = 0;
clearTimeout(_timer);
}
alert('hi4');
}
</script>
What happened was that I got 'hi1', 'hi3', 'hi4' then object error. the image DID change once.
You are not assining a function to setInterval, you are calling the function and assigning what every it returns.
Your code
_timer = setInterval(swapImages(), interval);
is actually doing this
_timer = setInterval(undefined, interval);
Your code needs to drop the () so you are not calling the function.
_timer = setInterval(swapImages, interval);
You also did it here:
imgCached.onload = OnImgLoaded();
Personally I would not use an interval, your images are NOT going to load in 30 ms. You a timeout after the images are loaded. Something like this would work.
var isRunning,
timer,
intervalMS = 30,
imgLive = document.getElementById('imgLive');
function test() {
_index = 0;
isRunning = true;
if (timer) window.clearTimeout(timer);
swapImages();
}
function setImageSrc (src) {
imgLive.src = src;
if(isRunning) timer = window.setTimeout(swapImages, intervalMS);
}
function swapImages() {
var imgCached = new Image();
imgCached.onload = function() {
setImageSrc(this.src);
};
imgCached.onerror = function() {
setImageSrc("Error.jpg");
};
imgCached.src = 'http://www.informedmotion.co.uk/Cloud/test/' + '0000' + _index + '.jpg';
_index = _index + 1;
if (_index == 10) {
isRunning = false;
}
}

Categories

Resources