setInterval, click something then clearInterval, and then few seconds setInterval again - javascript

i want to create a slider image that running uses setInterval, when i click on the thumbail, the image slider stops, but after a few seconds i want it continues to run setInterval again, i'm stuck here. I don't know how to write the code so that setInterval runs again
//auto animate
let counter = 0;
function imageChange() {
bigImage.src = thumb[counter++].src;
if(counter >= thumb.length) {
counter = 0;
}
}
let gallery = setInterval(imageChange, 1000);
//click thumb stop Animate then runs again
for(t of thumb) {
t.addEventListener('click', (e) => {
bigImage.src = e.target.src;
clearInterval(gallery);
//I'm stuck here :(
});
}

pause = setTimeout(() => { gallery = setInterval(imageChange, 1000)} ,3000);
like this
let pause;
//auto animate
let counter = 0;
function imageChange() {
bigImage.src = thumb[counter++].src;
if(counter >= thumb.length) {
counter = 0;
}
}
let gallery = setInterval(imageChange, 1000);
//click thumb stop Animate then runs again
for(t of thumb) {
t.addEventListener('click', (e) => {
bigImage.src = e.target.src;
clearInterval(gallery);
clearTimeout(pause);
pause = setTimeout(() => { gallery = setInterval(imageChange, 1000)} ,3000);
});
}
I would delegate though
let pause;
//auto animate
let counter = 0;
function imageChange() {
bigImage.src = thumb[counter++].src;
if(counter >= thumb.length) {
counter = 0;
}
}
let gallery = setInterval(imageChange, 1000);
//click thumb stop Animate then runs again
document.getElementById('thumbContainerId').addEventListener('click',function(e) {
bigImage.src = e.target.src;
clearInterval(gallery);
clearTimeout(pause);
pause = setTimeout(() => { gallery = setInterval(imageChange, 1000)} ,3000);
});

You cannot PAUSE the setInterval function, you can either STOP it (clearInterval), or let it run.
When you click on, just set isPaused as true. When close a thumbnail set isPaused as false.
//auto animate
let counter = 0;
let isPaused = false;
function imageChange() {
if(isPaused){
return;
}
//Your code
}
let gallery = setInterval(imageChange, 1000);
//click thumb stop Animate then runs again
for(t of thumb) {
t.addEventListener('click', (e) => {
bigImage.src = e.target.src;
isPaused = true;
});
}
function closeThumnail(){
isPaused = false;
}

Related

Unable to pause audio after eventListener end

When first loading the code, the pause button works fine, it pauses the audio and changes the HTML class of the button inside, the button continues to work after using the previous/next buttons to go to another song, however after the eventListener is triggered the pause button stops working, it doesn't pause the songs but the HTML inside still changes.
Edit: After a little bit of further debugging I found that the pause button is only able to pause the first time a track is loaded, once the audio.addEventListener('ended', nextTrack); is triggered it is unable to pause/play any audio.
let audio = new Audio;
let playing = false;
let playpause = document.getElementById('play-pause');
let root = document.documentElement;
let songname = document.getElementById('name');
let next = document.getElementById('next');
let prev = document.getElementById('previous');
let index = 0;
songlist = [
{"name":"Love Again"
,"artist":"The Kid LAROI",
"path":"resources/music/love-again.mp3",
},
{
"name":"Always Do",
"artist":"The Kid LAROI",
"path":"resources/music/always-do.mp3",
},
{
"name":"Bye Bye",
"artist":"Juice WRLD",
"path":"resources/music/bye-bye.mp3",
},
{
"name":"Understand",
"artist":"BoyWithUke",
"path":"resources/music/understand.mp3",
}
]
function progress_animation(){
var currentTime = audio.currentTime;
var duration = audio.duration;
$('#progbar').stop(true, true).animate({ 'width': (currentTime + .25) / duration * 100 + '%' }, 250, 'linear');
window.requestAnimationFrame(progress_animation);
};
function load(index){
songname.textContent = `${songlist[index].artist} - ${songlist[index].name}`;
audio.src = songlist[index].path;
audio.load()
};
audio.addEventListener('ended', nextTrack);
$('#play-pause').click(function (){
if (!playing) {
Play()
playing = true
} else {
Pause()
playing = false
}
});
function nextTrack(){
if (index < songlist.length - 1) {
index++;
} else {
index = 0;
}
load(index);
};
function prevTrack(){
if (index > 0) {
index--;
} else {
index = songlist.length - 1;
}
load(index);
};
function Play() {
audio.play();
playing = true;
playpause.innerHTML = '<i class="fa-solid fa-pause"></i>';
};
function Pause() {
audio.pause()
playing = false;
playpause.innerHTML = '<i class="fa-solid fa-play"></i>';
};
The pause button still changes its HTML class and sets the "playing" variable to false/true depending on the state of "playing" but doesn't actually pause the song

Resetting a Timer Back to 0 from Counter?

I have been googling for a solution for this problem, but many suggestions that I have found either freezes the counter or does nothing. counter.innerHTML = 0 just resumes where it left off after a second.
Here is my code:
let reset = document.getElementById('reset')
let counter = document.getElementById('counter')
let num = 0;
let timer = setInterval(countUp, 1000);
function countUp() {
counter.innerHTML = num++
}
//Reset timer
reset.addEventListener('click', stuff)
function stuff() {
clearInterval(timer)
}
What you have is mostly working, you just need to
clear the internal
reset the innerHtml to 0
let reset = document.getElementById('reset')
let counter = document.getElementById('counter')
let num = 0;
let timer = setInterval(countUp, 1000);
function countUp() {
counter.innerHTML = num++
}
//Reset timer
reset.addEventListener('click', stuff)
function stuff() {
counter.innerHTML = 0;
clearInterval(timer)
}
<button id="reset">reset</button>
<div id="counter" />
It's probably useful to put the logic that changes what you see in the page content in its own function: this will help you think about each part of the problem independently:
let resetBtn = document.getElementById('reset');
let counter = document.getElementById('counter');
let num = 0;
// Start the timer
let timer = setInterval(countUp, 1000);
// Use this to update the DOM (page content)
function updateUI () {
counter.textContent = num;
}
function countUp () {
// Increment the number
num += 1;
// Update the DOM
updateUI();
}
function reset () {
// Stops the interval
clearInterval(timer);
// Reset the number
num = 0;
// Update the DOM
updateUI();
}
// Update the UI the first time (before the counter reaches 1)
updateUI();
// Add the reset functionality to the button
resetBtn.addEventListener('click', reset);
<div id="counter"></div>
<button id="reset">Reset</button>

Vanilla JS image slideshow play/pause button

My play/pause button works the first time I press pause and the first time I press play. But after that if I want to pause the slideshow again, it just plays the slideshow at a faster speed and I am no longer able to pause it.
I am thinking maybe it is to do with the fact I have two separate functions: one for the play/pause button icon toggle, and another for the actual play pause behaviour? (update: this has now been fixed, but still doesn't work)
Sorry, I am struggling with javascript, I have a lot to learn.
My script:
const playPause = document.querySelector('.pause');
let slideId;
// FUNCTION TO MOVE TO NEXT SLIDE
const moveToNextSlide = () => {
slides = getSlides();
if (index >= slides.length - 1) return;
index++;
slideGroup.style.transform = `translateX(${-slideWidth * index}px)`;
slideGroup.style.transition = '.8s';
}
// FUNCTION TO START SLIDESHOW
const startSlide = () => {
slideId = setInterval(() => {
moveToNextSlide();
}, interval);
playing = true;
};
// START AUTOMATIC SLIDESHOW UPON ENTERING THE PAGE
startSlide();
//PLAY PAUSE BUTTON - slideshow start/stop
playPause.addEventListener('click', () => {
if(!slideId) {
slideId = startSlide();
console.log('started');
} else {
clearInterval(slideId);
slideId = null;
console.log('stopped');
}
});
//PLAY PAUSE BUTTON - image change
function toggle(button) {
if (button.className != 'pause') {
button.src = 'img/pause.png';
button.className = 'pause';
}
else if (button.className == 'pause') {
button.src = 'img/play.png';
button.className = 'play';
}
return false;
}
HTML:
<input type='image' src='img/pause.png' class='pause' onclick='toggle(this);' />
This is what the console looks like when I try to pause the slideshow for a second time:
There are some details in your code that are missing and would be helpful to have, but I guess that you can get rid of the onclick handler and attach two event listeners:
let slideId;
// FUNCTION TO START SLIDESHOW
const startSlide = () => {
let interval = 2000; // using just as sample
playing = true;
return setInterval(() => {
console.log('moveToNextSlide();') // replaced just to test without missing code
}, interval);
};
//PLAY PAUSE BUTTON - slideshow start/stop
playPause.addEventListener('click', () => {
if(!slideId) {
slideId = startSlide();
console.log('started');
} else {
clearInterval(slideId);
slideId = null;
console.log('stopped');
}
});
//PLAY PAUSE BUTTON - image change
playPause.addEventListener('click', function toggle() { // the arrow function would not work in this case
var button = this;
if (button.className != 'pause') {
button.src = 'img/pause.png';
button.className = 'pause';
}
else if (button.className == 'pause') {
button.src = 'img/play.png';
button.className = 'play';
}
return false;
});

how to get slide indicator to match current slide?

I have made this vanilla js image slider with three images. In the html i have three indicator dots at the bottom of the slider and a css active class for the active indicator. Can't figure out how to get the class to add to the current slide of the slide show, any help?
let sliderImages = document.querySelectorAll('.slides'),
prevArrow = document.querySelector('#prevBtn'),
nextArrow = document.querySelector('#nextBtn'),
dots = document.querySelectorAll('.indicator__dot'),
current = 0;
reset = () => {
for(let i = 0; i <sliderImages.length; i++) {
sliderImages[i].style.display = 'none';
}
}
startSlide = () => {
reset();
sliderImages[0].style.display = 'block'
}
prevSlide = () => {
reset();
sliderImages[current - 1].style.display = 'block';
current -- ;
}
nextSlide = () => {
reset();
sliderImages[current + 1].style.display = 'block';
current++;
}
prevArrow.addEventListener('click', () => {
if(current === 0 ) {
current = sliderImages.length;
}
prevSlide();
});
nextArrow.addEventListener('click', () => {
if(current === sliderImages.length - 1 ) {
current = -1
}
nextSlide();
});
startSlide()
No sorry I should have been more clear and included some html. I have 3 dots at the bottom of the slider. When slide one is the current image the first dot will have the css class added to it, when the second image is showing the second do will have the active class and the first dot wont any more. Hope that makes more sense?
<div class="indicator">
<span class="indicator__dot">&nbsp</span>
<span class="indicator__dot">&nbsp</span>
<span class="indicator__dot">&nbsp</span>
</div>
Haven't tested this so may have some bugs. setAnchor() function resets all the dots and add active class to the current dot.
setAnchor = () => {
for(let i = 0; i <dots.length; i++) {
sliderImages[i].classList.remove("active");
if(current === i){
sliderImages[i].classList.add("active");
}
}
}
startSlide = () => {
reset();
sliderImages[current].style.display = 'block'
setAnchor();
}
prevSlide = () => {
reset();
current -- ;
sliderImages[current].style.display = 'block';
setAnchor();
}
nextSlide = () => {
reset();
current++;
sliderImages[current].style.display = 'block';
setAnchor();
}

Javascript Countdown Timer Repeat and Count total that repeat

I have javascript countdown timer from 25 -> 0.
var count=25;
var counter=setInterval(timer, 1000); //1000 will run it every 1 second
function timer()
{
count=count-1;
if (count <= 0)
{
clearInterval(counter);
return;
}
document.getElementById("timer").innerHTML=count; // watch for spelling
}
div HTML
<span id="timer">25</span>
Now I want the countdown is repeat automatically after wait 5 seconds then it start again from 25 -> 0. And I want to count how many times that countdown repeat. Is it possible for that?
Please help.
You can try wrapping the entire code into a function (countTimers() in the example below) that runs every 30 seconds (5 seconds after each timer). Then, set a counter (timersCount in the example below) to count how many times that will run.
See the example below:
var timersCount = 0, stopped = false, count, counter; // make count, counter global variables so buttons can access them
var timerCounter = setInterval(countTimers, 30000);
countTimers(); // run countTimers once to start
function timer() {
count = count-1;
document.getElementById("timer").innerHTML=count;
if(count <= 0) {
clearInterval(counter);
return;
}
}
function countTimers() {
timersCount++;
// as per request in the comments, you can set a timer counter as well:
document.getElementById("totalcounter").innerHTML = timersCount;
count = 25;
counter = setInterval(timer, 1000);
}
// button code:
document.getElementById("reset").addEventListener("click", function() {
clearInterval(timerCounter);
clearInterval(counter);
count = 25;
document.getElementById("timer").innerHTML=count;
timersCount = 0;
document.getElementById("totalcounter").innerHTML = timersCount;
stopped = true;
});
document.getElementById("stop").addEventListener("click", function() {
if(stopped)
return;
clearInterval(counter);
stopped = true;
});
document.getElementById("start").addEventListener("click", function() {
if(!stopped)
return;
stopped = false;
counter = setInterval(timer, 1000);
setTimeout(function() {
clearInterval(counter);
timerCounter = setInterval(countTimers, 30000);
countTimers();
}, count*1000);
});
Timer: <span id="timer">25</span><br>
Number of times run: <span id="totalcounter">1</span>
<br><br>
<button id="reset">Reset</button>
<button id="stop">Stop</button>
<button id="start">Start (if stopped)</button>
var count=25;
var counter = null;
// reset count and timer
function reset_timer()
{
count = 25;
counter=setInterval(timer, 1000); //1000 will run it every 1 second
}
// init timer for first time
reset_timer();
function timer()
{
count--;
if (count <= 0)
{
clearInterval(counter);
setTimeout(reset_timer, 5000);
return;
}
document.getElementById("timer").innerHTML=count; // watch for spelling
}
setTimeout is a timer that runs one time and stop.
This approach uses Promises to the countdown work and generate an infinite loop,
if for some reason you need to stop/resume your counter you can reject the Promise chain and have a boolean to control the state:
let secondsCounter =
document.querySelector('#secondsCounter'),
totalCount =
document.querySelector('#totalCount'),
ttc = 1,
actualSecond = 25,
isPaused = false,
interval;
let countDown = time => new Promise( (rs, rj) => interval = setInterval( ()=>{
if (isPaused) {
return rj('Paused');
}
secondsCounter.textContent = --actualSecond;
if (actualSecond == 0){
actualSecond = time + 1;
clearInterval(interval);
rs();
}
}, 1000));
let loop = time => countDown(time).then( ()=>{
totalCount.textContent = ++ttc;
return Promise.resolve(null);
});
let infinite = () => loop(25)
.then(infinite)
.catch(console.log.bind(console));
let stop = () => {
clearInterval(interval);
isPaused = true;
}
let resume = () => {
console.log('Resumed');
isPaused = false;
loop(actualSecond).then(infinite);
}
let start_stop = () => isPaused ?
resume() : stop();
infinite();
Seconds : <div id="secondsCounter">25</div>
Times : <div id="totalCount">1</div>
<button onclick="start_stop()">Start/Stop</button>

Categories