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>
Related
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.
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>
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.
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>
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);
});