2 Javascript Timeouts occur simultaneously - javascript

I have 2 Javascript Timeouts which should make an animation, but the happen simultaneously, even if they have as timeout 1s.
JavaScript:
$( document ).ready(function() {
let filter = document.querySelector('.filter');
let body = document.querySelector('body');
setTimeout(moveRight, 1000);
setTimeout(scaleRotate, 1000);
function moveRight() {
filter.style.marginLeft="10%";
body.style.overflow = "hidden";
}
function scaleRotate() {
let deg = 90;
filter.style.webkitTransform = 'rotate('+deg+'deg)';
filter.style.width = "100vh";
}
});
HTML
<div class="header">
<div class="filter"></div>
<div class="header-text ml-5">
<h2 class="font-weight-bold">Andrei Bunea</h2>
<h3 class="mt-3">full stack developer</h3>
</div>
</div>

You set them similar delay. If you want scaleRotate to work 1 second after moveRight, you can set scaleRotate timer in moveRight timer:
setTimeout(moveRight, 1000);
function moveRight() {
console.log("moveRight");
setTimeout(scaleRotate, 1000);
}
function scaleRotate() {
console.log("scaleRotate");
}

Related

Stop timeout when user click and hold the picture

I have a gallery, that will show pictures to user for 5 to 5 seconds.
function slideSwitch() {
var current = $('#slideshow .active');
current.removeClass('active');
if (current.next().length) {
current.next().addClass('active');
myInterval = setTimeout(slideSwitch, 5000);
bar();
}
}
http://jsfiddle.net/6hcste51/
I'd like to pause the timeout when user click and hold the click on div holder.
For example, the timeout is in 3 seconds, if user click and hold the holder div I'd like to stop in 3 seconds until the hold ends, and then go to 4 and 5 seconds to call the function again.
I saw this function but I don't know how to add it in my slideSwitch(). any ideas?
selector.addEventListener('mousedown', function(event) {
// simulating hold event
setTimeout(function() {
// You are now in a `hold` state, you can do whatever you like!
}, 500);
}
you need to set timer function it can support pause and resume
need to set anmatin can support pause and resume and reset (i use jquery queue &
animations)
At last the code will be :
jsfiddle Link
//--------------------------global variables----------------
var isfirst= true;
var cycle_remaining = null;
var anim_time = 5000;//in mil sec
var downtime = null;
var myTimer = null;
var is_down = false;//is down event
var is_SpeedClick_getnext = false;//set to true you want to set click to get next image
//---------------------------timer-------------------------
function Timer(callback, delay) {
var timerId, start, remaining = delay;
cycle_remaining = remaining;
this.pause = function() {
window.clearTimeout(timerId);
remaining -= new Date() - start;
cycle_remaining = remaining;
};
this.resume = function() {
start = new Date();
window.clearTimeout(timerId);
timerId = window.setTimeout(callback, remaining);
cycle_remaining = remaining;
};
this.resume();
}
function slideSwitch() {
var current = $('#slideshow .active');
if (current.next().length) {
current.removeClass('active');
current.next().addClass('active');
myTimer = new Timer(slideSwitch, 5000);
resetanim();
startanim();
}
}
//--------------------- mouse control functions----------------------
$(document).on( "click", ".holder", function() {
if(isfirst){
isfirst = false;
slideSwitch();
}
});
$('.holder').on('mouseout mouseup', function(e) {
if(is_down && !isfirst){
is_down = false;
//set this if if you want to set click to get next image
if(downtime > new Date() - 100 && is_SpeedClick_getnext){
slideSwitch();
}else{
myTimer.resume();
startanim();
}
}
});
$(".holder").mousedown(function() {
if(!isfirst){
downtime = new Date();
is_down = true;
myTimer.pause();
puseanim();
}
});
//--------------------- animation control functions----------------------
//start or resume animation
function startanim() {
var myDiv = $( ".bottom_status" );
myDiv.show( "slow" );
myDiv.animate({
width:"100%"
},cycle_remaining );
myDiv.queue(function() {
var that = $( this );
//that.addClass( "newcolor" );
that.dequeue();
});
}
function rutanim() {
var myDiv = $( ".bottom_status" );
myDiv.show( "slow" );
myDiv.animate({
width:"100%"
}, anim_time );
myDiv.queue(function() {
var that = $( this );
//that.addClass( "newcolor" );
that.dequeue();
});
}
//to puse animation
function puseanim() {
var myDiv = $( ".bottom_status" );
myDiv.clearQueue();
myDiv.stop();
}
// to reset animation
function resetanim() {
var myDiv = $( ".bottom_status" );
myDiv.animate({
width:"1%"
}, 200 );
myDiv.queue(function() {
var that = $( this );
that.dequeue();
});
}
.holder{
display:none;
}
.active{
display:block;
}
.bottom_status{
position:absolute;
bottom:0;
background:blue;
width:0%;
height:10px;
left: 0;
margin-left: 0;
padding: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div id=slideshow>
<div class='holder active'>
Click here to start counting and click and hold to stop.
</div>
<div class='holder'>
text 2
</div>
<div class='holder'>
text 3
</div>
<div class='holder'>
text 4
</div>
</div>
<div class=bottom_status></div>
There is a Var called is_SpeedClick_getnext set to true you want to set click to get next
Note : the explanation in code comment
As mentioned you cant pause a setTimeout, but I have a solution which I think you might find useful.
I've created a second timer function that effectively stores the remaining time before a slide in the #slideshow element as an attribute every 500ms. If the user clicks on an image then it will cancel the original setTimeout and pauses the changing of the #slideshow attribute until the mouseup event. After the mouseup event is fired a new setTimeout is started using the remaining time stored in the attribute.
I also added a line of code to restart from the first image at the end of the slideshow (not sure if that's what you planned).
Hope this helps
// Start slider
slideSwitch();
// Start independent timer
timer();
function slideSwitch() {
// Select active slide and remove active status
var current = $('#slideshow .active');
current.removeClass('active');
// Check if there is a 'next' element and give active class, or return to first
if (current.next().length) {
current.next().addClass('active');
} else {
$("#slideshow img").first().addClass("active");
}
// Reset timer for the slide, store time and reset timer stop
myInterval = setTimeout(slideSwitch, 3000);
$("#slideshow").attr("time", "3000");
$("#slideshow").attr("timeStop", "false");
}
function timer() {
// Check if the slide countdown has been stopped
if ($("#slideshow").attr("timeStop") != "true") {
// Get last saved time and reduce by 500ms
tempTime = parseInt($("#slideshow").attr("time") - 500);
// Save time to slideshow attribute
$("#slideshow").attr("time", tempTime)
// Show countdown on label
$("#timerLabel").text(tempTime);
}
// Continue timer
myTimer = setTimeout(timer, 500);
}
// Add event for mousedown which cancels timer
$("#slideshow img").mousedown(function() {
// Stop timer and clear countdown for slide
$("#slideshow").attr("timeStop", "true");
window.clearTimeout(myInterval);
});
// Start timer on mouse up
$("#slideshow img").mouseup(function() {
// Restart a new countdown for slide using stored time remaining value
tempTime = parseInt($("#slideshow").attr("time"));
myInterval = setTimeout(slideSwitch, tempTime);
$("#slideshow").attr("timeStop", "false");
});
img {
display: none;
border: 5px solid black;
}
img.active {
display: inherit;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="slideshow" time="">
<img src="https://via.placeholder.com/150/fff">
<img src="https://via.placeholder.com/150/000" class="active">
<img src="https://via.placeholder.com/150/f00">
<img src="https://via.placeholder.com/150/0f0">
<img src="https://via.placeholder.com/150/00f">
</div>
<p>Remaining: <span id="timerLabel"></span> ms</p>

setTimeout functions double even when cleared first

I have images in the img/ directory (1-13.jpg) and I need to loop through them. the #next_container is supposed to stop(); the loop if it already start();ed and change the src to the next(); image then start(); it again, but when I click on #next_container it runs the next(); function as expected but for some reason stop(); doesn't stop the old timeout and I end up with two start(); functions running which causes the images to change faster and when it's stop();ed the #next_container is supposed to only get the next(); image but for some reason the loop start();s. the same happens for #prev_container.
HTML code:
<div class="container">
<img id="imgs" src="img/1.jpg" onload="start();">
<div id="next_container" style="display: none;">
<span id="next">❱</span>
</div>
<img id="player" src="" style="display: none;">
<div id="prev_container" style="display: none;">
<span id="prev">❰</span>
</div>
<p id="count">1 / 13</p>
</div>
JavaScript code:
// the images array holds sources for all the images
function next(){
var element = document.getElementById("imgs");
var num = Number(element.src.split("/").slice(-1)[0].split(".")[0]);
if (num == images.length){
element.src = "img/1.jpg";
document.getElementById("count").innerHTML = "1 / 13";
} else {
num++;
element.src = images[num-1];
document.getElementById("count").innerHTML = num.toString()+" / 13";
}
}
function prev(){
var element = document.getElementById("imgs");
var num = Number(element.src.split("/").slice(-1)[0].split(".")[0]);
if (num == 1){
element.src = "img/13.jpg";
document.getElementById("count").innerHTML = "13 / 13";
} else {
num--;
element.src = images[num].src;
document.getElementById("count").innerHTML = num.toString()+" / 13";
}
}
function start(){
window.timeout = setTimeout("next()", 3000);
document.getElementById("player").src = "img/pause.png";
document.getElementById("player").onclick = function(){ stop(); };
document.getElementById("next_container").onclick = function(){ stop(); next(); start(); };
document.getElementById("prev_container").onclick = function(){ stop(); prev(); start(); };
}
function stop(){
clearTimeout(window.timeout);
document.getElementById("player").src = "img/play.png";
document.getElementById("player").onclick = function(){ start(); };
document.getElementById("next_container").onclick = function(){ next(); };
document.getElementById("prev_container").onclick = function(){ prev(); };
}
Because the onload fires for each image you load. Example showing it.
function start() {
console.log("I AM CALLED");
}
function loadNext () {
document.querySelector("img").src = "http://placekitten.com/400/300"
}
window.setTimeout(loadNext, 2000);
<img src="http://placekitten.com/200/300" onload="start()" />
So you call next(); start();, next changes the source so it will cause the "onload="start()" to fire and than you call start(). There is your two timers. Remove the start() after the next and prev calls.

close div for the first time and it will not show up again at 10 minutes

this is the situation:
1) We need to have a box (div) that only shows up when the user has scrolled half the page.
2) We want the box to remember if the user closes the box for the first time.
It will not show up again for the user for at least 10 minutes.
Can you help me, i made some code,
i can close/hide the box but when i scroll down again, it show up again, the box its not really disappear.
Help me complete this without using jquery, pure javascript
my code for close box:
function hide()
{
document.getElementById('popup').style.display = 'none';
};
my code for show box when scroll down:
window.addEventListener("scroll",function()
{
if (window.pageYOffset >= 800 )
{
document.getElementById('popup').style.display = "block";
}
}, false);
if u need the e.g. of html code:
<div id="popup" class="popup-container">
<form action="#" class="popup-form">
</form>
<div class="popup-close">
<span class="fa fa-close" onclick="hide()"></span>
</div>
</div>
let isClicked = false;
window.addEventListener("scroll", function () {
if (!isClicked && window.pageYOffset >= 800) {
document.getElementById('popup').style.display = "block";
}
}, false);
function hide() {
document.getElementById('popup').style.display = 'none';
isClicked = true;
setTimeout(() => {
isClicked = false;
}, 10 * 60 * 1000);
};
<div style="background-color: #f2f2f2; height: 1200px;">
Content div
</div>
<div id="popup" class="popup-container">
<form action="#" class="popup-form">
POP UP
</form>
<div class="popup-close">
<span onclick="hide()">X</span>
</div>
</div>
You can do the following things-
Keep a variable to store if the box was closed.
let isClosed = false;
Set its value to true inside hide() function.
While checking for scroll offset, also check for the value of isClosed.
if(!isClosed && window.pageYOffset >= 800 ){...
Use setTimeout() to reset the value of isClosed once a timeout is over.
Here is an example of script-
let isClosed = false;
function hide() {
document.getElementById('popup').style.display = 'none';
isClosed = true;
setTimeout(function() {
isClosed = false;
}, 10 * 60 * 1000);
};
window.addEventListener("scroll",function(){
if(!isClosed && window.pageYOffset >= 800 ){
document.getElementById('popup').style.display = "block";
}
}, false);
Keep a last view time, check that and when it elapses you can reset to visible. When you click the hide, it resets.
Note your scroll will fire a LOT, probably want to de-bounce or throttle that - other questions answer how to do that.
This is not a super fancy version of code to do this...I set this to 1 minute so I could see it work, revise as needed.
var timeLastView;
var hasDelayElapsed = false;
var baseDelay = 1; //minutes to delay
function setViewTime() {
// convert milliseconds to seconds.
timeLastView = (new Date().getTime()) / 1000;
}
function hasTimeElapsed(minutes) {
var timeCheck = minutes * 60;
var currentTime = (new Date().getTime()) / 1000;
if (currentTime - timeLastView >= timeCheck) {
// then more than 10 minutes elapsed.
hasDelayElapsed = true;
} else {
hasDelayElapsed = false;
}
return hasDelayElapsed;
}
function hide() {
setViewTime();
document.getElementById('popup').style.display = 'none';
};
window.addEventListener("scroll", function() {
// lots of logging, probably want to de-bounce this console.log("scrolling");
if (window.pageYOffset >= 800 && hasTimeElapsed(baseDelay)) {
document.getElementById('popup').style.display = "block";
}
}, false);
.usespace {
height: 1000px;
}
.popup {
background-color: #aaaaaa;
}
<div class="usespace">Above the thing</div>
<div id="popup" class="popup-container">
<form action="#" class="popup-form"> something to see here
</form>
<div class="popup-close">
<span class="fa fa-close" onclick="hide()">closer</span>
</div>
</div>
<div class="usespace">Howdy below </div>
let localStorage = {};
let minTimeDiffSeconds = 5;
// let minTimeDiffSeconds = 10 * 60;
window.addEventListener("scroll",function(){
if(window.pageYOffset >= 800 ){
let currentTimeSeconds = Math.round((new Date()).getTime() / 1000);
//let timeLastClosed = localStorage.getItem('closedTime')
let timeLastClosed = localStorage.closedTime;
let timeDiffSeconds = currentTimeSeconds - timeLastClosed;
if (timeDiffSeconds > minTimeDiffSeconds) {
document.getElementById('popup').style.display = "block";
}
}
},false);
function hide() {
let currentTimeSeconds = Math.round((new Date()).getTime() / 1000);
//localStorage.setItem('closedTime', currentTimeSeconds);
localStorage.closedTime = currentTimeSeconds;
document.getElementById('popup').style.display = 'none';
};
.container {
height: 2000px;
width: 200px;
position: relative;
}
.popup-container {
position: fixed;
top: 0;
}
<div class="container">
<div>
Permanent Content
</div>
<div id="popup" class="popup-container">
<form action="#" class="popup-form">
</form>
<div class="popup-close">
<span class="fa fa-close" onclick="hide()">Popup</span>
</div>
</div>
</div>
You can use localstorage for this. Store the timestamp when the user closes it, and when the user scrolls, you check if enough time has passed. If yes, then show the popup. Stackoverflow does not allow the use of localstorage, so I have created a localstorage for demo. You can use the browser's localstorage, or the code as is.
Note: For the snippet, I have set the minimum time to be 5 seconds
After hiding it, you can use setTimeOut to avoid showing div again for 10 mins. Watch out,
setTimeOut() params uses miliseconds.
Check it out: https://www.w3schools.com/jsref/met_win_settimeout.asp
Was that your problem?

jQuery - interval not executed for the last slide - animation malfunction

I'm creating a slider but using a bunch of divs instead of images. I have 3 divs in total, the first two can move pretty well, but the last one just flies away really fast - it shows for a moment and then moves back to the first div. I just want it to show the same amount of time as the first two. Here's my html code:
<div id="ibToShow">
<div id='sliderWrapper'>
<div class="infoBox" id="infob1">
blablabla
</div>
<div class="infoBox" id="infob2">
blablabla
</div>
<div class="infoBox" id="infob3">
blablabla
</div>
</div>
</div>
And here's my jQuery code:
$(function () {
var width = '55vw';
var showTime = 2000;
var animationSpeed = 500;
var currentDiv = 1;
var $slider = $('#ibToShow');
var $sliderWrapper = $slider.find('#sliderWrapper');
var $infoBox = $sliderWrapper.find('.infoBox');
var interval;
function startSlider() {
interval = setInterval(function () {
$sliderWrapper.animate({'margin-left': '-=' + width}, animationSpeed, function(){
currentDiv++;
if (currentDiv === $infoBox.length){
currentDiv = 1;
$sliderWrapper.css('margin-left', 0);
}
})
}, showTime);
}
function stopSlider() {
clearInterval(interval);
}
$sliderWrapper.on('mouseenter', stopSlider).on('mouseleave', startSlider);
startSlider();
});
I sensed it might be because the animation stopped immediately after the third div showed up. But shouldn't it be waiting for what's set up in showTime?
This problem is still not fixed. Any takers?
You are changing margin left to 0 right after the previous animation ends.
I think this would work better :
function startSlider() {
interval = setInterval(function () {
if(currentDiv++ <== $infoBox.length) {
$sliderWrapper.animate({'margin-left': '-=' + width}, animationSpeed);
}
else {
$sliderWrapper.animate({'margin-left': '0'}, animationSpeed);
currentDiv = 0;
}
}, showTime);
}

Stop a javascript timer and animation and resume them

I have to stop a timer and an animation of a bar which width is decreasing dependently on a time variable and then resume both if pressed a button, so that the bar animation will continue from where it stopped and the same for the timer. How can I do that?
I can execute a function on button press, it's just the stopping and resuming functions that I don't know.
$("#timebar") is the animated bar.
function startTimer() {
timer = setTimeout(function(){
barAnimation();
}, time);
}
function stopTimer() {
$('#timebar').stop();
$('#timebar').css("width","100%");
clearTimeout(timer);
}
function barAnimation() {
$("#timebar").animate({ width: "0%" }, time, "linear");
}
This doesn't have the animation, but it does offer a start/stop and progress indicator.
var time = 0;
var timer = 0;
var running = false;
function startTimer() {
running = true;
timer = setInterval(function() {
barAnimation();
}, 1000);
}
function stopTimer() {
running = false;
clearInterval(timer);
}
function barAnimation() {
time++;
$("#count").text(time);
$("#timebar").prop("value", time);
}
$("#go").on("click", function(evt) {
if (running) {
stopTimer();
} else {
startTimer();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button id="go">Go</button>
<progress id="timebar" value="0" max="100"></progress>
<div id="count"></div>
I think something like this is what you're looking for:
var time = 0;
var remaining = 15000;
var interval;
$('#start').click(startTimer);
$('#stop').click(stopTimer);
function startTimer() {
if (!interval) {
interval = setInterval(function(){
if (remaining % 1000 === 0)
$('#time').html(time++);
remaining -= 100;
}, 100); // 100 w/ modulo instead of 1000 for better precision
barAnimation();
}
}
function stopTimer() {
$('#timebar').stop();
clearInterval(interval);
interval = false;
}
function barAnimation() {
$("#timebar").animate({ width: "0%" }, remaining, "linear");
}
#timebar {
background-color: black;
width: 100%;
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="start">Start</button>
<button id="stop">Stop</button>
<div id="time">0</div>
<div id="timebar"></div>

Categories