Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I need to customize single click event to double click. And it have to work if second click is clicked in 300 ms.
Something like this should work. Basically you can save the first click, and set a timer to reset that click if no other click is there.
I'm sure there are plenty of better ways to do this, but this works:
let clicked = false;
const timeout = 300;
let timer;
function onClickHandler(e) {
console.log('click');
document.querySelector('#result').innerText = '';
if (timer) window.clearTimeout(timer);
if (!clicked) {
console.log('first time');
clicked = true;
timer = window.setTimeout(() => clicked = false, timeout);
} else {
console.log('double click');
clicked = false;
document.querySelector('#result').innerText = 'Double click!';
}
}
#result{background:red;}
<div onclick="onClickHandler(event)">Click me twice</div>
<div id="result"></div>
Description
Here is an example using the Timeout built into JavaScript
Example:
// the double click time amount
const doubleClickTimeout = 300
// timer variable used to store our timeout pointer
let timer = undefined
// clear function that kills the timeout/timer and variable
let clear = () => {
if (timer) clearTimeout(timer)
timer = undefined
}
// starts the timeout/timer
let clickStart = () => {
timer = setTimeout(clear, doubleClickTimeout)
}
// gets the area you want to monitor
const doubleClick = document.getElementById("doubleClick")
// set up a onclick event on the doubleClick variable that points to the doubleClick div
doubleClick.onclick = () => {
// if timer isn't undefined then we have a double click
if (timer) {
console.log("double click detected")
// call the clear function: clear the timer
clear()
} else {
// call the clickStart function: start a timer
clickStart()
}
}
<div id="doubleClick">this is a clickable area with custom double clicking</div>
Related
I can't for the life of my figure out how to get this to work bug free.
The button in the code below needs to do three things.
Start a countdown when clicked (works)
End the countdown automatically, and reset itself when it reaches 0(works)
Reset itself prematurely if its clicked in the middle of a countdown(works, sort of)
Bug: when clicked repeatedly it starts multiple countdowns, and more or less breaks. It needs to either reset itself or start a countdown if clicked repeatedly. There should never be more than one countdown.
It works fines as long as people press the button, wait a second, and then press it again to stop it.
The bug I'm running into is if someone spam clicks it, it starts multiple countdowns and generally just breaks the button. I've tried a lot of different methods to fix it, and this is the closest I've gotten.
var i = 29;
let running=false;
$("#startButton").click(function () {
if(running==false){
var countdown = setInterval(function () {
$("#startButton").text("Reset Timer");
running=true;
$("#stopWatch").html(i);
i--;
if (i <0)
{
$("#startButton").text("Start Timer");
running=false;
clearInterval(countdown);
i = 29;
$("#stopWatch").html(i);
}
$("#startButton").click(function () {
$("#startButton").text("Start Timer");
running=false;
clearInterval(countdown);
i = 29;
$("#stopWatch").html(i+1);
});
}, 1000);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="stopWatch">30</div>
<button id="startButton">Start Timer</button>
Welcome to Stack Overflow #William!
I'm not sure what this means: Reset itself prematurely if its clicked in the middle of a countdown(works, sort of). But I managed to fix your bug on spamming button click and for item 3, i just do reset the countdown from initial state. See snippets below:
// Get attribute value from div `stopwatch`. This is for resetting from default value.
var initial = $('#stopWatch').attr("value");
// Assigned initial value to var i.
var i = initial;
$("#stopWatch").html(i);
let running = false;
// Created a separate function to call from button click.
function run(timer = true) {
if (timer) {
running = true;
$("#startButton").text("Reset Timer");
$("#stopWatch").html(i);
var countdown = setInterval(function () {
i--;
$("#stopWatch").html(i);
if (i <= 0) {
running = false;
$("#startButton").text("Start Timer");
clearInterval(countdown);
i = initial;
$("#stopWatch").html(i);
}
}, 1000);
} else {
running = false;
clearInterval(countdown);
i = 0;
$("#startButton").text("Start Timer");
}
}
$("#startButton").click(function () {
// Check if its not running and var i is not 0
if(!running && i != 0) {
run();
// Check if its running and var i is not 0 to ensure that if someone spam the button it just reset the countdown.
} else if (running && i != 0) {
// Will return the else{} on function run().
run(false);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="stopWatch" value="30"></div>
<button id="startButton">Start Timer</button>
Added some comments on the snippet. Feel free to ask if you have any questions.
I'm trying to show a label when a user clicks a button. I've tried to use setTimeout to achieve this, but when you click the button multiple times before the timeout ends, this don't work properly.
This is what I got:
const [cameraLabelVisible, setCameraLabelVisible] = useState(false);
let labelTimer;
function labelVisible() {
setCameraLabelVisible(true);
labelTimer = setTimeout(() => {
setCameraLabelVisible(false);
clearTimeout(labelTimer);
}, 1500);
}
};
My question is: Is it posible reset the timer to the initial value (in this case 1500) by clicking the same button before the timer ends?
I want to show the label if the button is clicked multiple times before the time runs out.
You could clear the existing timer first:
const [cameraLabelVisible, setCameraLabelVisible] = useState(false);
let labelTimer;
function labelVisible() {
setCameraLabelVisible(true);
// clear the timer if there's another timer running
if(labelTimer) clearTimeout(labelTimer);
labelTimer = setTimeout(() => {
setCameraLabelVisible(false);
}, 1500);
}
My question is: Is it possible reset the timer to the initial value
(in this case 1500) by clicking the same button before the timer ends?
Yes, this can be achieved by clearing the existing timeout and creating a new timeout. This can be achieved as below:
const [cameraLabelVisible, setCameraLabelVisible] = useState(false);
let labelTimer;
function labelVisible() {
if(labelTimer) {
clearTimeout(labelTimer);
}
setCameraLabelVisible(true);
labelTimer = setTimeout(() => {
setCameraLabelVisible(false);
clearTimeout(labelTimer);
}, 1500);
}
};
I want to show the label if the button is clicked multiple times
before the time runs out.
This sounds like a different issue than what you asked above. If I'm understanding you correctly, the below will allow you to click the button multiple times within 1.5 seconds, and the label appear for only that amount of time before clearing.
const [cameraLabelVisible, setCameraLabelVisible] = useState(false);
let labelTimer = undefined;
function labelVisible() {
setCameraLabelVisible(true);
if(!labelTimer) {
labelTimer = setTimeout(() => {
setCameraLabelVisible(false);
labelTimer = undefined;
}, 1500);
}
};
This question already has answers here:
Incrementing value continuously on mouse hold
(5 answers)
Closed 5 years ago.
I have this script that adds 1 to a value every time I click on a button:
<script>
function incrementValue(id) {
var value = parseInt(document.getElementById(id).innerHTML);
value = value + 1;
document.getElementById(id).innerHTML = value;
}
</script>
<button onclick="incrementValue('skill_1')"> add </button><br>
<span id=skill_1>0</span>
However I want to adjust it so that if I hold down the mouse button, it'll repeat so I don't have to keep pressing it over and over.
Any way to do that using javascript? Or would jquery suit?
To achieve this you need to use the mousedown event to start a timeout (which is the delay before the incremental count starts) and an interval (which does the repeated counting). You'll also need a mouseup and mouseleave handler to remove both of those timers. Try this:
var timeout, interval;
[].forEach.call(document.querySelectorAll('.add'), function(button) {
button.addEventListener('mousedown', function() {
var id = button.dataset.target;
incrementValue(id);
timeout = setTimeout(function() {
interval = setInterval(function() {
incrementValue(id);
}, 50);
}, 300);
});
button.addEventListener('mouseup', clearTimers);
button.addEventListener('mouseleave', clearTimers);
function clearTimers() {
clearTimeout(timeout);
clearInterval(interval);
}
});
function incrementValue(id) {
var el = document.getElementById(id);
var value = parseInt(el.textContent, 10);
document.getElementById(id).textContent = ++value;
}
<button class="add" data-target="skill_1">add</button><br />
<span id="skill_1">0</span>
You'll need 3 event handler:
mousedown that will call a function, that will call itself with a timeout (continuosIncerment) while the mouse button is pressed.
mouseup that will clear the timeout when the button is released.
mouseleave that clears the timeout when the mouse leaves the button area.
const btn = document.querySelector('#btn');
const skill_1 = document.querySelector('#skill_1');
let value = 0;
let timer;
function continuosIncerment() {
skill_1.innerHTML = ++value;
timer = setTimeout(continuosIncerment, 200);
}
function timeoutClear() {
clearTimeout(timer);
}
btn.addEventListener('mousedown', continuosIncerment);
btn.addEventListener('mouseup', timeoutClear);
btn.addEventListener('mouseleave', timeoutClear);
<button id="btn"> add </button><br>
<span id="skill_1">0</span>
Instead of reading the value from the HTML, then writing it back, it's easier to hold the value in a variable, increment it, then write it out.
Did you know you can do this with a simple HTML spinner?
<input type="number" min="0" max="50" step="1">
I'd go with a solution like this: on mouse down event starts a repeating timer that triggers your function and it stops when the mouse up event occurs.
var inter = null;
function setInter(){
inter=setInterval(incrementValue, 500);
}
function unsetInter(){
clearInterval(inter);
}
function incrementValue() {
var value = parseInt(document.getElementById('skill_1').innerHTML);
value = value + 1;
document.getElementById('skill_1').innerHTML = value;
}
<button
onmousedown="setInter()"
onmouseup="unsetInter()"> add </button>
<br>
<span id=skill_1>0</span>
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Why bind won't work after setInterval?
var i = 0;
$('.click').bind('click').click(function(){
var thisclick = $(this);
var move = setInterval(function(){
if(i < 30){
i++;
thisclick.unbind('click');
}
else{
thisclick.bind('click');
clearInterval(move);
}
},3000)
})
As of jQuery 1.7 .on() method is preferred, but the actual issues you have are
you are not providing handler for the second binding ( in case you want to rebind the click with the same handler )
you need to reset/clear the counter, since it's a closure variable it'll always be in 30 once reached.
$('.click').on('click', handler);
var i = 0;
function handler(e) {
e.preventDefault();
var thisclick = $(this);
var move = setInterval(function () {
if (i < 10) {
i++;
thisclick.off('click');
} else {
thisclick.on('click', handler);
i = 0; // reset here
clearInterval(move);
}
}, 1000);
};
DEMO
You have to pass function and time to setInterval. Like following example and you are missing time is your code.
setInterval(function(){alert("Hello")}, 3000);
So Change would be
setInterval(function(){
if(i < 30){
i++;
thisclick.unbind('click');
}
else{
thisclick.bind('click');
clearInterval(move);
}
},3000)//Give your value here
Binding to the click event has nothing to do with the issue.
setInterval() expects two parameters: the function to call when triggered, and the time interval in which to trigger said function (in milliseconds)
For example:
var myInterval = setInterval(myFunction, 200);
This will trigger the "myFunction" method every 200 milliseconds.
I am able to find the cursor position. But I need to find out if the mouse is stable. If the mouse wasn't moved for more than 1 minute, then we have to alert the user.
How its possible, are there any special events for this? (Only for IE in javascript)
Set a timeout when the mouse is moved one minute into the future, and if the mouse is moved, clear the timeout:
var timeout;
document.onmousemove = function(){
clearTimeout(timeout);
timeout = setTimeout(function(){alert("move your mouse");}, 60000);
}
Here's a one-and-done function that can check any element for movement:
function mouse (element, delay, callback) {
// Counter Object
element.ms = {};
// Counter Value
element.ms.x = 0;
// Counter Function
element.ms.y = function () {
// Callback Trigger
if ((++element.ms.x) == delay) element.ms.callback(element, element.ms);
};
// Counter Callback
element.ms.callback = callback;
// Function Toggle
element.ms.toggle = function (state) {
// Stop Loop
if ([0, "off"][state]) clearInterval(element.ms.z);
// Create Loop
if ([1, "on"][state]) element.ms.z = setInterval(element.ms.y, 1);
};
// Function Disable
element.ms.remove = function () {
// Delete Counter Object
element.ms = null; return delete element.ms;
};
// Function Trigger
element.onmousemove = function () {
// Reset Counter Value
element.ms.x = -1;
};
// Return
return element.ms;
};
Usage:
mouse(element, delay, callback)
Examples:
Make a video player hide the mouse after 5 seconds when idle and fullscreen
let x = mouse(video, 5000, function (a) {
if (document.webkitIsFullScreen) video.style.cursor = "none";
});
x.toggle(1); addEventListener("mousemove", function () {
video.style.cursor = "auto";
});
Chat Room AFK (45 Seconds) (assuming you have a chat box and a send message function):
let x = mouse(chatBox, (45e3), function (a) {
chatBox.send({ text: chatBox.username + " is AFK.", italic: true });
});
x.toggle(1); x.addEventListener("mousemove", function () {
chatBox.send({ text: chatBox.username + " is no longer AFK", italic: true });
});
Is there not a way to set a timer to start incrementing after every mouse movement event?
If it gets to a minute then pop up the message box, but every time the mouse moves the timer gets reset.
Use a timer that resets its value on mousemove event.
If timer reaches 1 minute --> Do something.
More info on timer here http://www.w3schools.com/js/js_timing.asp
And more info on catchin mouse events here http://www.quirksmode.org/js/events_mouse.html
Yes, you have a onmousemove event in Javascript, so to achieve what you need you just have to do code something like this:
startTimer();
element.onmousemove = stopTimer(); //this stops and resets the timer
You can use it on the document body tag for instance.
UPDATE: #Marius has achieved a better example than this one.
You can use the onmousemove event. Inside it, clearTimeout(), and setTimeout(your_warning, 1 minute).
You could use this script/snippet to detect the mouse pointer position and "remember" it. Then use a timer "setTimeout(...)" to check the position let's say every second and remember that time.
If more than one minute passed and the position hasn't changed, you could alert the user.