Is there a way to toggle a setInterval - javascript

I am just playing around with the setInterval function in JavaScript.
I am wondering if there is a way to toggle the setInterval with an HTML button
This is my code.
let x = 0;
const listener = document.getElementById('listener');
const numberPlace = document.getElementById('numberPlace');
const numberCounter = setInterval(() => {
x++;
numberPlace.innerHTML = x;
}, 100);
listener.addEventListener('click', numberCounter);
The problem is that the number starts counting when the page loads and not on a button click.
Please help

const numberCounter = () => setInterval(() => {
x++;
numberPlace.innerHTML = x;
}, 100);

setInterval can be cancelled using clearInterval and the integer identifier returned when setInterval was called.
To toggle a setInterval-based counter, you simply need to toggle on the presence (or absence) of this identifier.
let counter = 0;
let intervalId = null;
const btn = document.getElementById('btn');
const numberPlace = document.getElementById('numberPlace');
const numberCounter = () => intervalId === null
? intervalId = setInterval(() => numberPlace.innerHTML = ++counter, 100)
: (clearInterval(intervalId), intervalId = null)
btn.addEventListener('click', numberCounter);
<button id="btn">toggle</button>
<div id="numberPlace"></div>

Related

Increase and decrease number while pressing

I have two clickable spans that can increase and decrease number inside a input
by saving the opreation inside them using an id then loop on them and do the opreation using eval() , i want to increase the number and decrease it while pressing not only on click
(Long Press)
<span id="--">-</span>
<input class="num" type="number" max="50" value="0" min="1" disabled />
<span id="++">+</span>
let num = document.querySelector(".num");
let controllers = document.querySelectorAll(".control span");
controllers.forEach((c) => {
c.onclick = function (e) {
let op = e.target.id;
eval("num.value" + op);
};
});
You should use the mousedown event instead of click, and set some interval that does your logic at some rate of time.
Also I'm not sure why you're using the id property and not some data property maybe, this isn't a safe usage of this property. Also you should use event listeners instead of directly adding the function on the property.
<span data-op="--">-</span>
<input class="num" type="number" max="50" value="0" min="1" disabled />
<span data-op="++">+</span>
let num = document.querySelector(".num");
let controllers = document.querySelectorAll(".control span");
controllers.forEach((c) => {
let interval
c.addEventListener('mousedown',function (e) { // mouse down - start ticking
let op = e.target.getAttribute('data-op'); // get data property
interval = setInterval(() => {
eval("num.value" + op);
}, 100) // set interval tick time here
});
c.addEventListener('mouseup',function (e) { // mouse up - stop ticking
clearInterval(interval)
});
});
Are you trying to achieve something like this?
let score = 0;
let status = false;
const scoreEl = document.querySelector('#score');
const btnEl = document.querySelector('#btn');
let interval = null;
btnEl.addEventListener('mousedown', e => {
status = true;
update();
});
btnEl.addEventListener('mouseup', e => {
status = false;
update();
});
const update = () => {
if (status) {
interval = setInterval(() => {
score++;
scoreEl.innerHTML = score;
}, 100);
} else {
if (interval) clearInterval(interval);
}
}
<div id="score">0</div>
<button id="btn">Increment</button>

Why won't my timer function in JS start countdown?

My countdown timer does not work. I ideally I want it to start when the start buttons is clicked, am I missing something? I've done the event listener on click to the startButton variable, which has a document.getElementById("start-button") to the HTML. I'm not sure why it isn't working.
let countdownDisplay = document.getElementById("countdown-timer");
let startButton = document.getElementById("start-button");
let timer = 60; //document.getElementsByClassName("countdown");
let startGame = document.getElementsByClassName("button");
function countDown () {
setInterval(function(){
if (timer <= 0) {
clearInterval(timer = 0)
}
countdownDisplay.innerHTML = timer
timer -= 1
}, 1000)
}
startButton.addEventListener('click', countDown)
<div id="start-game">
<a class="button" id="start-button" href="quiz.html">Start Game - Kick Off</a>
</div>
Do not use a <a> tag with href attribute since your page will reload to the new url path. Instead just use a button:
As #Scott Marcus said, do not use .innerHTML when the text is not HTML as .innerHTML has security and performance implications. Use .textContent instead.
As #Dave Newton said, the argument to clearInterval should be an interval reference returned by setInterval. So relate the interval to a variable.
let countdownDisplay = document.getElementById("countdown-timer");
let startButton = document.getElementById("start-button");
let timer = 60; //document.getElementsByClassName("countdown");
let startGame = document.getElementsByClassName("button");
function countDown () {
let mytimer = setInterval(function(){
if (timer <= 0) {
clearInterval(mytimer)
}
countdownDisplay.textContent = timer
timer -= 1
}, 1000)
}
startButton.addEventListener('click', countDown)
<div id="start-game">
<button type="button" class="button" id="start-button">Start Game - Kick Off</button>
<br>
<label id="countdown-timer">Start number</label>
</div>
Remove the href attribute from the anchor - it's causing you to leave/reload the page.
let countdownDisplay = document.getElementById("countdown-timer");
let startButton = document.getElementById("start-button");
let timer = 60;
let startGame = document.getElementsByClassName("button");
let t;
function countDown() {
t = setInterval(function() {
if (timer <= 0) {
clearInterval(t)
}
countdownDisplay.innerHTML = timer
timer -= 1
}, 1000)
}
startButton.addEventListener('click', countDown)
<div id="start-game">
<a class="button" id="start-button">Start Game - Kick Off</a>
</div>
seems to be ok to me. I adjusted the html to remove link, add element to display countdown and added log.
I removed link because if you click on link you are navigating away from page.
also you should learn how the snippets work on stack overflow, you will get more answers.
let countdownDisplay = document.getElementById("countdown-timer");
let startButton = document.getElementById("start-button");
let timer = 60; //document.getElementsByClassName("countdown");
let startGame = document.getElementsByClassName("button");
function countDown() {
setInterval(function() {
if (timer <= 0) {
clearInterval(timer = 0);
}
//countdownDisplay.innerHTML = timer;
timer -= 1;
countdownDisplay.innerHTML = timer;
console.log(timer);
}, 1000)
}
startButton.addEventListener('click', countDown)
<div id="start-game">
<a class="button" id="start-button">Start Game - Kick Off</a>
</div>
<div id="countdown-timer" />

Why does function clearInterval() not working? I used setInterval too

I'm creating a product hover effect where I used mouseover and mouseleave functions. However, I'm currently having problems with the clearInterval function on Javascript.
Do I miss on something? The structure is also aligned.
Here's my code:
<script>
document.addEventListener("DOMContentLoaded", ()=>{
// //get img url from span
// const src = spanElem.attr('data-original');
// //change span to img using the value from data-original
// spanElem.replaceWith('<img class="product-img-toadd w3-animate-fading" src="' + src + '"/>');
const imgGallery = document.querySelectorAll('.product-img-gallery');
const imageDiv = document.querySelectorAll('.product-tile__image');
let interval
imageDiv.forEach(el=>{
//img
const imgGalleryItem = el.querySelectorAll('.product-img-gallery__item')
el.addEventListener("mouseenter", ()=>{
imgGalleryItem.forEach(item=>{
const src = item.getAttribute('data-original')
const img = `<img class="product-img-toadd w3-animate-fading" src="${src}"/>`
item.insertAdjacentHTML('beforeend',img)
//slider
const imgSlides = el.querySelectorAll('.product-img-toadd');
let currentIndex = 0
interval = setInterval(() => {
imgSlides.forEach((item) => {
item.style.opacity = 0;
});
imgSlides[currentIndex].style.opacity = 1;
if (currentIndex === imgSlides.length - 1) {
currentIndex = 0;
} else {
currentIndex = currentIndex + 1;
}
console.log("tick")
}, 750);
})
})
el.addEventListener("mouseleave", ()=>{
const imgSlides = el.querySelectorAll('.product-img-toadd');
imgSlides.forEach((item) => {
item.style.opacity = 0;
});
clearInterval(interval);
})
})
})
You're assiging interval in a loop, overriding each previous element with the next.
A possible solution would be to push each interval to a array, then iterate through all elements and clear it's elements.
let intervals = [];
intervals.push( setInterval(() => { ... });
...
intervals.forEach((iv) => clearInterval(iv));

Reset function by button

I have a button that disappears by a function after one second.
if I click on the button, I want the function will reset and I will get one another second to click. And-I want the button will disappeared if I did not click this second.
(if I click in a second, the button doesn't disappeared, if I miss one second, it is disappeared, but if I click, I'll get another second, and so on...)
This is my code:
HTML:
<button id="btn">click
</button>
JavaScript:
let btn = document.querySelector('#btn');
btn.addEventListener('click', ()=>{
click();
})
setTimeout(function click() {
btn.style.display = ('none');
}, 1000);
That code doesn't work.
I am an absolute beginner, so any feedback will help me.
If my question is not understood, please write to me in the comments or edit the question.
This is my suggestion:
var c = 10;
var timer;
clock();
function clock() {
timer = setInterval(countdown, 1000);
}
function countdown() {
counter.innerHTML = --c;
if (c === 0) {
btn.style.display = 'none';
clearInterval(timer);
}
}
btn.onclick = function() {
clearInterval(timer);
c = 10;
counter.innerHTML = c;
clock();
};
<button id="btn">Click me before it's too late (<span id="counter">10</span>)</button>
Change your javascript to the following:
let btn = document.querySelector('#btn');
btn.addEventListener('click', ()=>{
click();
})
function click() {
setTimeout(function() {
btn.style.display = 'none';
}, 1000);
}
Click was not defined properly :)
You should try jQuery, it'll make your learning a lot easier!
Also press f12 on Google Chrome to show developer console, errors will show up there.
You need to apply the display:none inside setTimeout. Here is an example.
let btn = document.querySelector('#btn');
let time = document.querySelector('#time');
const timeLimit = 10;
let timeoutId, intervalId;
time.innerText = timeLimit;
let startTime;
window.onload = () => {
startTime = Date.now();
startTimer();
removeButton();
}
btn.addEventListener('click', stop);
function stop() {
intervalId && clearInterval(intervalId);
timeoutId && clearTimeout(timeoutId);
}
function startTimer() {
let count = 1;
intervalId = setInterval(() => {
if(count === 10) clearInterval(intervalId);
time.innerText = timeLimit - count;
count++;
}, 1000);
}
function removeButton() {
timeoutId = setTimeout(() => {
btn.style.display = 'none';
}, timeLimit*1000);
}
<button id="btn">Click me. I am disappearing ⏳ <span id="time"></span></button>

Wait until user is finished clicking | JavaScript

I want to count the clicks while the user keeps clicking.
After about half a second when there are no more clicks on a specific button, the function should return the accumulated clicks.
I've tried it with this but, doesn't really work:
HTML:
Next
JavaScipt:
cntNav(element){
let btn = element.target
let cnt = 0
let t = setTimeout(function(){
console.log(cnt)
}, 1000)
btn.addEventListener("click", function(){
cnt++
})
}
Console Output (after 5x clicking):
4
3
2
1
0
You could create a timeout to delay returning the clicks.
const main = () => {
new Clicker('#click-me', {
timeout: 500,
callback: (clicks) => console.log(`Clicks: ${clicks}`)
});
};
class Clicker {
constructor(selector, options) {
this.reference = typeof selector === 'string' ?
document.querySelector(selector) : selector;
let opts = Object.assign({}, Clicker.defaultOptions, options);
this.timeout = opts.timeout;
this.callback = opts.callback;
this.initialize();
}
initialize() {
this.__clickCount = 0;
this.__activeId = null;
this.reference.addEventListener('click', e => this.handleClick())
}
handleClick() {
this.__clickCount += 1;
clearTimeout(this.__activeId); // Reset the timeout
this.__activeId = setTimeout(() => {
this.callback(this.__clickCount);
this.__clickCount = 0; // Reset clicks
}, this.timeout);
}
}
Clicker.defaultOptions = {
timeout: 1000
};
main();
<button id="click-me">Click me!</button>
HTML:
<button onclick="cntNav();">Click Me!</button>
JS:
var cnt = 0;
var myTimeOut;
cntNav = function(){
clearTimeout(myTimeOut);
myTimeOut = setTimeout(function(){
console.log(cnt);cnt=0;
}, 1000)
cnt++;
}
This removes the timeout whenever someone clicks, so if someone clicks before the timeout has called, then it will be cleared. It will only call when someone leaves enough time in-between clicks. This then also sets the count back to zero.

Categories

Resources