Start and stop interval on button click - javascript

I have this code here and i want the background to stop changing when i click the same button (the interval to stop). But i cannot work my way around it.(The else part works because in the console isCicked changes it's value).
let btn = document.querySelector('#btn');
let body = document.querySelector('body');
let isClicked = false;
btn.addEventListener('click', function(){
let x;
let y;
if(isClicked == false){
isClicked = true;
x= setInterval(function(){
let r,g,b;
r = Math.round(Math.random() * 255);
g = Math.round(Math.random() * 255);
b = Math.round(Math.random() * 255);
body.style.backgroundColor = `rgb(${r},${g},${b})`;
btn.classList.toggle('button-style')
},1000)
}else{
isClicked = false;
clearInterval(x);
}
console.log(isClicked);
})
<button type="button" id="btn">Click</button>

To fix your current code you need to declare x outside the event listener since as it stands you redeclare it on each click and overwrite your stored interval id.
let isClicked = false;
let x;
btn.addEventListener('click', function(){
if(isClicked == false){
isClicked = true;
x = setInterval(function(){
...
}
But you can actually simplify a little by combining isClicked and x and just checking if an interval is stored.
let btn = document.getElementById('btn');
let body = document.querySelector('body');
let interval = null;
btn.addEventListener('click', function () {
if (interval === null) {
interval = setInterval(function () {
let r, g, b;
r = Math.round(Math.random() * 255);
g = Math.round(Math.random() * 255);
b = Math.round(Math.random() * 255);
body.style.backgroundColor = `rgb(${r},${g},${b})`;
btn.classList.toggle('button-style');
}, 1000);
} else {
clearInterval(interval);
interval = null;
}
console.log(interval);
});
<button type="button" id="btn">Click</button>

Rather then trying to manage the state of setInterval, you could use setTimeout and recursion (a function calling itself) to create an interval. Likewise, rather than using variable mutation, since you're toggling a class on the button, you can just use the button itself as the exit condition for the recursion.
let btn = document.querySelector('#btn'),
body = document.querySelector('body');
function ChangeBackground() {
if (btn.classList.contains('button-style')) { //check exit condition
body.style.backgroundColor = '#' + Math.random().toString(16).slice(-6);
setTimeout(ChangeBackground, 1000); //recursion
}
}
btn.addEventListener('click', function(){
this.classList.toggle('button-style'); //toggle exit condition
ChangeBackground(); //start recursion
});
<button type="button" id="btn">Click</button>

Related

Touchscreen Press & Hold

I want the user to be able to touch and hold a button, and after a certain period of time, a function is called.
E.g. the button text starts as black, turns orange after 0.2s of pressing, and then green after 0.5s of pressing. If it is green, a function, myFunction(), is triggered.
I have made a start on it, more help would be appreciated. Thanks :)
var btn = document.getElementById("pressBtn");
var pressedTime = 0;
var elaspedHoldTime;
btn.onmousedown = function() {
if (pressedTime != 0) {
pressedTime = performance.now();
} else {
elaspedHoldTime = performance.now() - pressedTime;
}
if (elaspedHoldTime > 200) {
btn.style.color = "orange";
}
if (elaspedHoldTime > 1000) {
btn.style.color = "green";
}
};
btn.addEventListener("mouseup", function() {
elaspedHoldTime = performance.now() - pressedTime;
btn.style.color = "black";
if (elaspedHoldTime > 500) {
console.log("Call Function Here");
}
pressedTime = 0;
elaspedHoldTime = 0;
});
<button id="btn">Button Text</button>
(It also has a bug for some reason)
UPDATED
for not fully functioanlity I edited the code and also changed the logic
I come up with variable timerValue which increases in every 0.1s when mouse is pressed and when that timerValue reaches 2, button changes color to orange and on 5 changes on red and prints triggered as well
and on mouseup which will be called after user picks up finger from mouse, timerValue backs to 0 and resets also button class
interval is variable where are I store setInterval function and on mouse release I clear it
I included also paragpraph tag where is shown the timer to understand how it works
const btn = document.querySelector(".btn")
const timer = document.querySelector("p") //can be deleted
let timerValue = 0
let interval;
const mousePress = () => {
interval = setInterval(() => {
timerValue++
timer.innerHTML = timerValue //can be deleted
if(timerValue === 2) btn.classList.toggle("orange")
if(timerValue === 5) {
btn.classList.toggle("red")
console.log("triggered")
}
}, 100)
}
const mouseRelease = () => {
clearInterval(interval)
timerValue = 0
timer.innerHTML = timerValue //can be deleted
btn.className = "btn"
}
btn.addEventListener("mousedown", mousePress)
btn.addEventListener("mouseup", mouseRelease)
.btn.orange{
color: orange;
}
.btn.red{
color: red;
}
<button class="btn">Click</button>
<p></p>
mousedown, mouseup, touchstart, touchend triggers just once when the key is pressed.
To check, if the user is still holding it, you can check for a truly variable inside a setTimeout() function-call, stop the timeout on release or use a setInterval()-function-call that only runs when it's pressed.
For example:
let pressed = false;
button.addEventListener("mousedown", () => {
pressed = true;
setTimeout(() => {
if (pressed) { ... }
}, 200);
});
button.addEventListener("mouseup", () => { pressed = false; });
let timer = null;
button.addEventListener("mousedown", () => {
pressed = true;
timer = setTimeout(() => { ... }, 200);
});
button.addEventListener("mouseup", () => { clearTimeout(timer) });
As there is already an answer with setTimeout(), here is another solution with setInterval().
let vars = {
interval: null, // used to store the interval id
start: 0, // changes to Date.now() on every start.
// used to avoid myFunction be called more than once per "hold"
myFunctionCalled: false
}, myFunction = () => console.log("Yes...?");
button.addEventListener("mousedown", (event) => {
// avoid start w/ rightclick
if (event.which == 1) {
vars.start = Date.now();
vars.myFunctionCalled = false;
vars.interval = setInterval(() => {
let dur = Date.now() - vars.start;
if (dur > 1000) {
button.style.color = "green";
if (!vars.myFunctionCalled) {
vars.myFunctionCalled = true;
myFunction();
}
} else if (dur > 500) {
button.style.color = "orange";
} else if (dur > 100) {
button.style.color = "red";
}
}, 10);
}
});
// using window, so the user can move the mouse
window.addEventListener("mouseup", (event) => {
// checking again for the mouse key, to avoid disabling it on rightlick
if (vars.interval && event.which == 1) {
// stop the interval and reset the color to default
clearInterval(vars.interval);
button.style.color = "";
vars.interval = null;
}
})
<button id="button">Hold me</button>
If you're making it for a touchscreen, you need to use TouchEvents:
ontouchstart -> when a target is being pressed by a finger
ontouchmove -> the active finger moves off the target
ontouchcancel -> when the the target has lost focus of a touch event
ontouchend -> lifting the finger off of the target
MouseEvents are reserved for mouse / trackpad-controlled devices, such as Computers.
TouchEvents are reserved for touch-screen devices, such as tablets and phones.
Also read this answer for code.

click on button not execute function

I try to click on btn3 ( kashef) and it's not triggering my function
kashef()
My code is here: https://jsfiddle.net/erezdav12/gn8shkrm/100/
I need that by clicking on button kashef, my running counter (its a
money counter) will subtract by, lets say, 300$ (cost of clicking
to get the feature) e.g: if money roller is in 1000$ on the
moment of clicking event on "kashef" button, money counter reduce
to 700 $ and continue running until the next clicking.
Here is the code:
let start;
const el = document.getElementById('count');
const final = parseInt(el.textContent, 10);
const duration = 100000;
const kashefButton= document.getElementById("btn3");
kashefButton.addEventListener("click", kashef);
function kashef(){
document.getElementById('count').innerHTML=1000-300;
}
const step = ts => {
if (!start) {
start = ts;
}
let progress = (ts - start) / duration;
el.textContent = Math.floor(progress * final) * 100 ;
time = +el.textContent;
if( progress < 1){
requestAnimationFrame(step);
}
var btn1 = document.getElementById('btn1');
var btn2 = document.getElementById('btn2');
var btn3 = document.getElementById('btn3');
const OpentButtons = 200;
if (time <= OpentButtons) {
btn1.disabled = true;
btn2.disabled = true;
btn3.disabled = true;
} else {
btn1.disabled = false;
btn2.disabled = false;
btn3.disabled = false;
}
}
requestAnimationFrame(step);
big thanks !!!!
This is a scoping issue. The definition of kashdef is not defined in a scope that the event listener can find it in. Move the definition of kashef outside of the ts block (right after "const duration = 100001;" ) and it works (verified in your fiddle).

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>

How detect a click on a given period of time and made manipulation with element in this period

may be some one can help me. I try to write some "Dote game": 1. at a specified time interval a random square on the field is highlighted in blue. 2. If the user managed to click on the square during this time - it turns green if not it turns red. I am stuck with the second part. Here is my code:
let btn = document.getElementById('btn');
let lower = 1,
upper = 10,
uniqueN = [];
while (uniqueN.length < upper) {
let random = Math.floor(Math.random() * upper + lower);
if (uniqueN.indexOf(random) == -1) {
uniqueN.push(random);
}
}
btn.addEventListener('click', function() {
setTimeout(function loop() {
let square = document.getElementById(uniqueN.shift());
square.style.backgroundColor = 'lightblue';
if (uniqueN.length) {
setTimeout(loop, 3000);
}
square.addEventListener('click', function() {
// pseudo code:
// if I click this square in the next 2 seconds
// background color change to the green,
// if I don't click,
// or click after 2 seconds color change to red
//
});
}, 3000);
});
You need to store a couple bits of state with the items. In this case, you can use ready for when the button is ready to be clicked on and clicked when the button has been clicked.
let btn = document.getElementById('btn');
let lower = 1,
upper = 10,
items = [];
while (items.length < upper) {
let random = Math.floor(Math.random() * upper + lower);
if (!items.find(u => u.id === random)) {
items.push({
id: random,
ready: false,
clicked: false,
});
}
}
btn.addEventListener('click', function() {
setTimeout(function loop() {
let item = items.shift();
let square = document.getElementById(item.id);
square.style.backgroundColor = 'lightblue';
// mark the item ready
item.ready = true;
setTimeout(() => {
// hasn't been clicked within 2 seconds
if (!item.clicked) {
square.style.backgroundColor = 'red';
}
// mark it not ready after 2 seconds
item.ready = false;
}, 2000);
if (items.length) {
setTimeout(loop, 3000);
}
square.addEventListener('click', function() {
// pseudo code:
// if I click this square in the next 2 seconds
// background color change to the green,
// if I don't click,
// or click after 2 seconds color change to red
// if clicked on when ready, store the state
if (item.ready) {
item.clicked = true;
square.style.backgroundColor = 'green';
}
});
}, 3000);
});
<button id="btn">button</button>
<div>
<button id="1">1</button>
<button id="2">2</button>
<button id="3">3</button>
<button id="4">4</button>
<button id="5">5</button>
<button id="6">6</button>
<button id="7">7</button>
<button id="8">8</button>
<button id="9">9</button>
<button id="10">10</button>
</div>
Well it's not easy (if not impossible) getting this value inside the setTumeout function. The best approach would be to use javascript Date object with the .now() method. Here's how your code might look like
let btn = document.getElementById('btn');
let lower = 1,
upper = 10,
uniqueN = [];
while (uniqueN.length < upper) {
let random = Math.floor(Math.random() * upper + lower);
if (uniqueN.indexOf(random) == -1) {
uniqueN.push(random);
}
}
btn.addEventListener('click', function() {
// -------------time at the begining of the timeout----------
const start = Date.now();
setTimeout(function loop() {
let square = document.getElementById(uniqueN.shift());
square.style.backgroundColor = 'lightblue';
if (uniqueN.length) {
setTimeout(loop, 3000);
}
square.addEventListener('click', function() {
//------------time elasped since the begining of timeout---------
const elapsed = Date.now() - start;
if (elapsed <= 2000) {
// background color change to the green,
} else {
// or click after 2 seconds color change to red
}
});
}, 3000);
});

I am not able to clear my interval set with onmousedown with onmouseup

I am currently trying to make my webpage more userfriendly for mobile and tabs, and I'm having this issue:
I want a button to increase a textbox value while the button is being pressed (onmousedown). So I created my button like this:
<span
class="glyphicon glyphicon-resize-full textIconBoxControll"
aria-hidden="true"
onmousedown="inter=setInterval(increaseFont, 300);"
onmouseup="clearInterval(inter);"
onmouseout="clearInterval(inter);">
</span>
Now, when I press the button, it starts calling the increaseFont function, but it doesn't stop when I release the button or move the mouse out of the span. If I type this into my browser console (inter="setInter.." and clearInterval(inter);) it works as intended. I fear this has something to do with what scope "inter" belongs to when using the html events, but I cannot seem to find a solution to this. I've tried creating a global variable named inter in the top of my JS (doesn't work).
Here's an example using onmousedown and onmouseup (you might want to use ontouchstart/ontouchend):
<button type='button' id='bigger'>Bigger</button>
<button type='button' id='smaller'>Smaller</button>
<br/>
<input type='text' id='num' value='5'/>
window.onload = function ol(){
var bigger = document.getElementById('bigger'),
smaller = document.getElementById('smaller'),
num = document.getElementById('num'),
max_num = 16.0,
min_num = 5.0,
speed = 30,
step = .1,
itv;
bigger.onmousedown = go_bigger;
bigger.onmouseup = reset;
smaller.onmousedown = go_smaller;
smaller.onmouseup = reset;
function reset() {
clearInterval(itv);
}
function go_bigger(){
reset();
itv = setInterval(function o(){
var val = parseFloat(num.value, 10);
if (val >= max_num) {
reset();
return;
}
val = Math.round((val + step) * 100) / 100;
num.value = val;
num.style.fontSize = val + 'px';
}, speed);
}
function go_smaller(){
reset();
itv = setInterval(function o(){
var val = parseFloat(num.value, 10);
if (val <= min_num) {
reset();
return;
}
val = Math.round((val - step) * 100) / 100;
num.value = val;
num.style.fontSize = val + 'px';
}, speed);
}
};
http://jsfiddle.net/vcbhpzds/

Categories

Resources