JavaScript cancel function - javascript

I have some code where I have a timer. Every 3 seconds the background changes colors, and when you hover the stop button, the color changer pauses, I have an onclick event that i am using in junction with the mouseout event but the mouseout event cancels out my onclick event. What can I do so that the onclic event works still after I move the mouse from the stop button?
Code: jsfiddle
<script>
var colors = new Array();
colors[0] = "green";
colors[1] = "blue";
colors[2] = "gray";
var i = 0;
var timer;
function changeOfPlans() {
timer = setInterval("colorChange()", 3000);
}
function colorChange() {
document.getElementById("one").style.backgroundColor = colors[i];
document.getElementById("two").style.backgroundColor = colors[i];
i++;
if (i == 3 || i > 3) {
//start over by setting i to 0
i = 0;
}
}
function stop() {
clearTimeout(timer);
}​
</script>

You need to update the on click action so that it sets a variable. Then have the mouse out first check whether that variable is set before restarting the color changing. Demo.
I modified your JavaScript like so:
var stopped = false;
function changeOfPlans() {
if (!stopped) {
timer = setInterval("colorChange()",3000);
}
}
function fullstop() {
stopped = true;
stop();
}
Then I updated your onclick to call fullstop() instead of just stop(). Since I left the other stop() function the same, the hover-to-stop-move-away-to-restart functionality still works as you had it originally. All of the other JavaScript remains the same.
<button type="button" onmouseover="stop()" onmouseout="changeOfPlans()" onclick="fullstop()">Stop</button>
There are other ways of doing this -- enhzflep suggests a good one in the comments -- but this is the simplest.

You are using setInterval, so to cancel you need clearInterval not clearTimeout.
Also don't run it again on mouseout i guess:
onmouseout="changeOfPlans()"

Related

JavaScript: How prevent dblclick (Double Click) to also fire a single click event

I want avoid that double click also fire a single click event.
A simple solution i found is to delay the click with a timer and destroy the timer if a double click is fired.
var pendingClick;
function myclick(){
clearTimeout(pendingClick);
pendingClick = setTimeout(function(){
console.log('click');
}, 500);
}
function mydblclick(){
clearTimeout(pendingClick);
console.log('double click');
}
<div onclick="myclick()" ondblclick="mydblclick()">Double Click Me!</div>
But this solution is based on timing, if the double click is too slow (>500ms) it also fire a single click.
There is a stable solution for handle both click and double click?
Double-clicking in itself is "based on timing", even in the standard implementation of dblclick / ondblclick. There will always be the issue of a single-click being fired if the double-click is "too slow". What is "too slow"? 300ms? 500ms? 1000ms? Your double-clicks may be only 50ms apart, while my mom's double-clicks are 1-2 seconds apart...
You can get the event and cancel it with the addEventListener like this:
document.addEventListener('dblclick', (event) => { 
event.preventDefault();  
event.stopPropagation(); 
}, true); // With this true, you are cancelling the dblclick event
let pendingClick;
function myclick(){
clearTimeout(pendingClick);
pendingClick = setTimeout(function (){
console.log('click');
}, 500);
}
function mydblclick(){
clearTimeout(pendingClick);
console.log('double click');
}
<div onclick="myclick()" ondblclick="mydblclick()">Double Click Me!</div>
Only work with the 'onclick' function to check if it was one or two clicks and use a variable to count the number of clicks in a given time interval.
Example:
var pendingClick;
var clicked = 0;
var time_dbclick = 500 // 500ms
function myclick(){
clicked++;
if(clicked >= 2){
mydblclick()
clearTimeout(pendingClick)
clicked = 0;
return;
}
clearTimeout(pendingClick)
pendingClick = setTimeout(() => {
console.log('One click!')
clicked = 0;
}, time_dbclick);
}
function mydblclick(){
console.log('double click');
}
<div onclick="myclick()">Double Click Me!</div>
Custom Events instead of inline event handlers
If one prefers to use .addEventListener and .removeEventListener instead of HTML inline-eventhandlers, I would suggest another approach based on Custom Events. That means one would not make use of the standard implementation of "click" and "dblclick", but create own event handling for both:
let lastLeftClick = document.dispatchEvent(new Event("click"));
let doubleclickLength = 300;
function leftClickHandler (e) {
if (e.button != 0) return; // only left clicks shall be handled;
let delaySinceLastClick = e.timeStamp - lastLeftClick.timeStamp;
let eIsDoubleClick = delaySinceLastClick < doubleclickLength;
if (eIsDoubleClick) {
let doubleclickEvt = new CustomEvent("doubleclick", e);
lastLeftClick = lastLeftClick = doubleclickEvt;
document.dispatchEvent(doubleclickEvt);
} else {
let singleClickEvt = new CustomEvent("singleclick", e);
lastLeftClick = singleClickEvt;
document.dispatchEvent(lastLeftClick);
}
}
// adding above click event implementation:
document.addEventListener("click", leftClickHandler);
using the new custom events:
document.addEventListener("singleclick", e=>console.log("single click"));
document.addEventListener("doubleclick", e=>console.log("double click"));

How to turn on/off a function on a button click?

I have been working in a mini-game-project (Simons game) that many of you may know. Where the computer plays a random sequence of buttons in which players have to follow to go to the next level in the game e.g: [one click first round, two clicks second round..].
I already did all the button effects as well as make the machine plays buttons randomly in a range of ten rounds. So, what I would like to do is use a button to turn on and off the function that makes the computer clicks By Itself using a button.
I already tried using the jQuery function $(startButton).on('click', clickByItself); alone but it did not worked.
$(document).ready(function() {
//four variables representing its button effects
//button blue effect
var blueButtonEffect = code here;
var greenButtonEffect = code here;
var redButtonEffect = code here;
var yellowButtonEffect = code here;
//to be used on the buttonEffects()/clickByItself()
var arr = [blueButtonEffect, redButtonEffect, greenButtonEffect, yellowButtonEffect];
let enabled = true;
let times = 0;
//makes button effects play itself randomly
function clickByItself() {
let random = Math.floor(Math.random() * arr.length);
$(arr[random]).click();
if (++times < 10) {
setTimeout(function() { clickByItself(times); }, 1000);
}
}
clickByItself();
function turnOnTurnOff() {
if (enabled == true) { //TRYING TO TURN ON/OFF THE FUNCTION ON BUTTON CLICK..
$(startButton).on('click', clickByItself);
}else{
$(startButton).on('click', clickByItself);
}
}
Now, I am trying to use a function turnOnTurnOff() to see whether I could do the effect of turning on and off with the click of a the startButton. Thank you.
You can use .off() method of jQuery to remove an event listener as follows.
I added two divs for better demonstration.
One button binds and unbinds (toggles) the click handler of the second button using jQuery's .on() & .off(). When the click handler is bound to the second button, clicking it will update the div with a number. When the click handler is unbounded from the second button, clicking the second button will do nothing. Two lines of interest in the JavaScript code below are decorated with a comment each. The rest is for demonstration.
window.enabled = false;
window.count = 1;
// Initialize the view (for demo)
$(function() {
$('#switchIndicator').html(`<p>${enabled ? 'Switch is ON' : 'Switch is OFF'}</p>`);
$('#btn').html(enabled ? 'You can click me :-)' : 'You CANNOT click me');
});
// Toggle click functionality using jQuery's .on() & .off() methods
function toggle() {
enabled = !enabled;
if (enabled) {
// Line of interest #1: jQuery .on()
$('#btn').on('click', handleClick);
} else {
// Line of interest #2: jQuery .off()
$('#btn').off('click', handleClick);
}
$('#switchIndicator').html(`<p>${enabled ? 'Switch is ON' : 'Switch is OFF'}</p>`);
$('#btn').html(enabled ? 'You can click me :-)' : 'You cannot click me :-((');
$('#btn').removeClass(enabled ? 'disabled' : 'enabled').addClass(enabled ? 'enabled' : 'disabled');
}
function handleClick() {
$('#counter').append(` ${count++}`);
}
/* CSS */
#btn.enabled {
background-color: greenyellow;
}
#btn.disabled {
background-color: lightgray;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="switchIndicator"></div>
<button id="switch" onclick="toggle()">On/OFF Switch</button>
<button id="btn"></button>
<div id="counter"></div>
Give this a try:
function clickByItself() {
if(enabled) {
let random = Math.floor(Math.random() * arr.length);
$(arr[random]).click();
if (++times < 10) {
setTimeout(function() { clickByItself(times); }, 1000);
}
}
}
clickByItself();
function turnOnTurnOff() {
if (enabled) {
enabled = false;
} else {
enabled = true;
clickByItself();
}
}
$(startButton).click(function() {
turnOnTurnOff();
});
You could do it in multiple ways. One is to use setInterval instead of setTimeout and store it inside a variable. When you need to stop it, just call clearInterval.

dblClick and click event in d3.js [duplicate]

I've toggled click event to a node and I want to toggle a dbclick event to it as well. However it only triggers the click event when I dbclick on it.
So How do I set both events at the same time?
You have to do your "own" doubleclick detection
Something like that could work:
var clickedOnce = false;
var timer;
$("#test").bind("click", function(){
if (clickedOnce) {
run_on_double_click();
} else {
timer = setTimeout(function() {
run_on_simple_click(parameter);
}, 150);
clickedOnce = true;
}
});
function run_on_simple_click(parameter) {
alert(parameter);
alert("simpleclick");
clickedOnce = false;
}
function run_on_double_click() {
clickedOnce = false;
clearTimeout(timer);
alert("doubleclick");
}
Here is a working JSFiddle
For more information about what delay you should use for your timer, have a look here : How to use both onclick and ondblclick on an element?
$("#test-id").bind("click dblclick", function(){alert("hello")});
Works for both click and dblclick
EDIT --
I think its not possible. I was trying something like this.
$("#test").bind({
dblclick: function(){alert("Hii")},
mousedown: function(){alert("hello")}
});
But its not possible to reach double click without going through single click. I tried mouse down but it does not give any solution.
I pretty much used the same logic as Jeremy D.
However, in my case, it was more neat to solve this thing with anonymous functions, and a little slower double click timeout:
dblclick_timer = false
.on("click", function(d) {
// if double click timer is active, this click is the double click
if ( dblclick_timer )
{
clearTimeout(dblclick_timer)
dblclick_timer = false
// double click code code comes here
console.log("double click fired")
}
// otherwise, what to do after single click (double click has timed out)
else dblclick_timer = setTimeout( function(){
dblclick_timer = false
// single click code code comes here
console.log("single click fired")
}, 250)
})
you need to track double click and if its not a double click perform click action.
Try this
<p id="demo"></p>
<button id='btn'>Click and DoubleClick</button>
<script>
var doubleclick =false;
var clicktimeoutid = 0;
var dblclicktimeoutid = 0;
var clickcheck = function(e){
if(!clicktimeoutid)
clicktimeoutid = setTimeout(function(){
if(!doubleclick)
performclick(e);
clicktimeoutid =0;
},300);
}
var performclick =function(e){
document.getElementById("demo").innerHTML += 'click';
}
var performdblclick = function(e)
{
doubleclick = true;
document.getElementById("demo").innerHTML += 'dblclick';
dblclicktimeoutid = setTimeout(function(){doubleclick = false},800);
};
document.getElementById("btn").ondblclick = performdblclick;
document.getElementById("btn").onclick=clickcheck;
</script>
a slightly different approach - The actual click comparison happens later in the timeOut function, after a preset interval... till then we simply keep tab on the flags.
& with some simple modifications (click-counter instead of flags) it can also be extended to any number of rapid successive clicks (triple click, et al), limited by practicality.
var clicked = false,
dblClicked = false,
clickTimer;
function onClick(param){
console.log('Node clicked. param - ',param);
};
function onDoubleClick(param){
console.log('Node Double clicked. param - ',param);
};
function clickCheck(param){
if (!clicked){
clicked = true;
clickTimer = setTimeout(function(){
if(dblClicked){
onDoubleClick(param);
}
else if(clicked){
onClick(param);
}
clicked = false;
dblClicked = false;
clearTimeout(clickTimer);
},150);
} else {
dblClicked = true;
}
};

Press and hold button does not fire onClick

I'm having a problem with the button in my HTML5 application.
When I press the button a Video player runs and plays the video that is stored locally. My issue now is that when I hold the button and release it, it doesn't fire the video player. I'm using an onclick event on my button.
I want to achieve that if I press and hold the button and then release it, it fires the same event as the one I use with the onclick.
Use onmouseup event.
var button = //your button
button.onmouseup = function() {
//your logic
}
Actually onmousedown event instead of onClick will do the trick.
Again the same syntax:
Javascript
<button onmousedown ="clickFunction()">Click me!</button>
function clickFunction(){
//code goes here
}
jQuery
function clickFunction(){
$(button).onmousedown(function(){
//code goes here
});
};
you should use a boolean to save the current state.
var mouse_is_down = false;
var current_i = 0; // current_i is used to handle double click (to not act like a hold)
var button = document.querySelector("#myButton");
button.onmousedown = function(){
mouse_is_down = true;
// Do thing here for a mousedown event
setTimeout(
(function(index){
return function(){
if(mouse_is_down && current_i === index){
//do thing when hold
}
};
})(++current_i), 500); // time you want to hold before fire action in milliseconds
};
button.onmouseup = function(){
mouse_is_down = false;
current_i++;
// Do thing here for a mouseup event
};
Fiddle : link

Jquery auto increment css property on mouse button press and hold

Im struggling to create a functionality which keeps on incrementing css property of an element when someone presses and 'holds' a button.
something like this:
var timeoutId = 0;
$('#left').mousedown(function() {
timeoutId = setTimeout(myFunction, 1000);
}).bind('mouseup mouseleave', function() {
clearTimeout(timeoutId);
});
function myFunction() {
var left = parseInt($("#menuElem").css('left')) + 10;
$("#menuElem").animate({
'left' : left + 'px'
});
}
I want that myFunction to be repeated again and again until mouseup or mouseleave event is fired.
cheers
According to this SO question you can't detect the current up or down state of a key, only monitor the respective events.
So you'd need something like this i guess
var mouseIsDown = false;
$('#button').mousedown(function(){
mouseIsDown = true;
incrementValue;
});
$('#button').mouseup(function(){
mouseIsDown = false;
});
Then have that function be all like:
function incrementValue() {
whatever++;
if(mouseIsDown){
setTimeout("incrementValue()", 20);
}
}
On mouse down, the mouseIsDown var gets set to true, and it starts a loop that continues to increment (at whatever interval you set the time parameter to in setTimeout()) until mouseIsDown is false, which happens on mouseup.

Categories