How can I know how long a user has been holding the mouse button down (anywhere on a webpage)? I want to execute a function when the user held the mouse button for at least 2-3 seconds (preferably cancelling the mouse down in the process). Is this possible?
Here you go:
$(window).mousedown(function(e) {
clearTimeout(this.downTimer);
this.downTimer = setTimeout(function() {
// do your thing
}, 2000);
}).mouseup(function(e) {
clearTimeout(this.downTimer);
});
Live demo: http://jsfiddle.net/simevidas/Pe9sq/2/
Off hand I would experiment with $("body").mousedown(function(){}) using jQuery and $("body").mouseup(function(){}). I guess you can start a timer which will call function in 2 to 3 seconds. If the mouseup event occurs, then you can cancel the timer. You could probably test it with a simple script but you might have to look at cases where the click might have occurred because a link or button was clicked on the page. But as a starting point I would experiment with the $("body").mousedown and $("body").mouseup. If I have chance I'll see if I can send a code sample.
Try this:
function WhateverYoudLikeToExecWithinNext3Seconds(){
// Code goes here.
}
element.addEventListener('mousedown', function(){
setTimeout(function(){WhateverIdLikeToExecWithin3Seconds();}, 3000);
}, false);
Check out this one.
http://jsfiddle.net/b1Lzo60n/
Mousedown starts a timer that checks if mouse is still down after 1 second.
<button id="button">Press me</button>
<div id="log"></div>
Code:
var mousedown = false;
var mousedown_timer = '';
$('#button').mousedown(function(e) {
mousedown = true;
$('#log').text('mousedown...');
mousedown_timer = setTimeout(function() {
if(mousedown) {
$('#log').text('1 second');
}
}, 1000);
}).mouseup(function(e) {
mousedown = false;
clearTimeout(mousedown_timer);
$('#log').text('aborted');
});
Related
On the page there is a link with id get-more-posts, by clicking on which articles are loaded. Initially, it is outside the screen. The task is to scroll the screen to this link by clicking on it. The code below does what you need. But the event is called many times. Only need one click when I get to this element scrolling.
p.s. sorry for my bad english
$(window).on("scroll", function() {
if((($(window).scrollTop()+$(window).height())+250)>=$(document).height()){
$('#get-more-posts').click();
}
});
Try use removeEventListener or use variable with flag, just event scroll detached more at once
You can set up throttling by checking if you are already running the callback. One way is with a setTimeout function, like below:
var throttled = null;
$(window).on("scroll", function() {
if(!throttled){
throttled = setTimeout(function(){
if((($(window).scrollTop()+$(window).height())+250)>=$(document).height()){
$('#get-more-posts').click();
throttled = null;
}
}.bind(window), 50);
}
}.bind(window));
Here's an ES6 version that might resolve the scoping issues I mentioned:
let throttled = null;
$(window).on("scroll", () => {
if(!throttled){
throttled = setTimeout(() => {
if((($(window).scrollTop()+$(window).height())+250)>=$(document).height()){
$('#get-more-posts').click();
throttled = null;
}
}, 50);
}
});
The last argument of setTimeout is the delay before running. I chose 50 arbitrarily but you can experiment to see what works best.
I don't know how true it is, but it works. After the event (click), delete the element id, and then add it again, so the click is performed once. Scroll the page to the desired item, click again, delete the id and add it again. It works. Can someone come in handy.
window.addEventListener('scroll', throttle(callback, 50));
function throttle(fn, wait) {
var time = Date.now();
return function() {
if ((time + wait - Date.now()) < 0) {
fn();
time = Date.now();
}
}
}
function callback() {
var target = document.getElementById('get-more-posts');
if((($(window).scrollTop()+$(window).height())+650)>=$(document).height()){
$('#get-more-posts').click();
$("#get-more-posts").removeAttr("id");
//$(".get-more-posts").attr("id='get-more-posts'");
};
}
window.removeEventListener('scroll', throttle(callback, 50));
I have already tried a lot, but did not come to an optimal solution. I have an image (html) and would like that if you press/click the image 5 seconds long, that he opens a link.
So far I have this code:
if (...) { window.location.href = 'http://www.google.com'; }
http://jsfiddle.net/xBz5k/
All the other answers open the link 5 seconds after a simple click. This one opens the link if the click lasted 5 seconds:
// the gif
var imgAnimation = '/images/animation.gif';
// the original image
var imgInitial = '/images/still.jpg';
// preload the gif
(new Image()).src = imgAnimation;
var imageMouseDown;
// mouse button gets pressed
$('#image').mousedown(function() {
$(this).prop('src', imgAnimation);
// start the timeout
imageMouseDown = setTimeout(function() {
window.location.href = 'http://www.google.com';
}, 5000);
});
// when the mouse button gets released
$('#image').mouseup(function() {
// the timeout isn't fired yet -> clear it
if (imageMouseDown) {
// set the old image again
$(this).prop('src', imgStill);
clearTimeout(imageMouseDown);
}
});
Here's a demo including the changing image: http://jsfiddle.net/7Qugn/
Use setTimeout in click event handler.
setTimeout should do the trick
Using jQuery:
$('#linkImg').click(function(){
setTimeout(function(){
window.location.href="http://google.com";
},5000);
});
Since this is a javascript answer, you could do:
document.getElementById('random-image').addEventListener('click', function() {
setTimeout(function(){
window.location.href = 'http://www.google.com';
}, 1000);
}, false);
I've created a JSFiddle for you (CLICK HERE), to illustrate the behavior.
This is the solution if you want to click and hold the image
var timeout = 0;
$('img').mousedown(function() {
timeout = setTimeout(myFunction, 5000);
}).bind('mouseup mouseleave', function() {
clearTimeout(timeout);
});
function myFunction() {
window.location.href="http://google.com";
}
I need a function that executes a function while a button is pressed and stops executing when the button is let go
$('#button').--while being held down--(function() {
//execute continuously
});
I believe something like this would work:
var timeout, clicker = $('#clicker');
clicker.mousedown(function(){
timeout = setInterval(function(){
// Do something continuously
}, 500);
return false;
});
$(document).mouseup(function(){
clearInterval(timeout);
return false;
});
See this demo: http://jsfiddle.net/8FmRd/
A small modification to the original answer:
$('#Clicker').mousedown(function () {
//do something here
timeout = setInterval(function () {
//do same thing here again
}, 500);
return false;
});
$('#Clicker').mouseup(function () {
clearInterval(timeout);
return false;
});
$('#Clicker').mouseout(function () {
clearInterval(timeout);
return false;
});
With the mouseout event on the Clicker it stops when you move your mouse out of the click area.
The reason why I suggest to do the same thing twice is to get a smoother effect. If you don't do it once before the timeout is set it will be a delay of, in this case, 500ms before something happens.
Here's a pure JavaScript implementation of the supplied solutions which has extended support for touch screens. You supply the id, action to perform (function(){}) and the interval (ms) to repeat the action. Note that this implementation will also execute the action immediately, rather than waiting for the interval to lapse.
// Configures an element to execute a function periodically whilst it holds the user's attention via a mouse press and hold.
function assertPeriodicPress(id, action, interval) {
// Listen for the MouseDown event.
document.getElementById(id).addEventListener('mousedown', function(ev) { action(); timeout = setInterval(action, interval); return false; }, false);
// Listen for mouse up events.
document.getElementById(id).addEventListener('mouseup', function(ev) { clearInterval(timeout); return false; }, false);
// Listen out for touch end events.
document.getElementById(id).addEventListener('touchend', function(ev) { clearInterval(timeout); return false; }, false);
}
$.fn.click2=function(cb,interval){
var timeout;
if(!interval) interval=100;
$(this).mousedown(function () {
var target=this;
timeout = setInterval(function(){
cb.apply(target);
}, interval);
return false;
}).mouseup(function () {
clearInterval(timeout);
return false;
}).mouseout(function () {
clearInterval(timeout);
return false;
});
}
I have an element on my page that I need to attach onclick and ondblclick event handlers to. When a single click happens, it should do something different than a double-click. When I first started trying to make this work, my head started spinning. Obviously, onclick will always fire when you double-click. So I tried using a timeout-based structure like this...
window.onload = function() {
var timer;
var el = document.getElementById('testButton');
el.onclick = function() {
timer = setTimeout(function() { alert('Single'); }, 150);
}
el.ondblclick = function() {
clearTimeout(timer);
alert('Double');
}
}
But I got inconsistent results (using IE8). It would work properly alot of times, but sometimes I would get the "Single" alert two times.
Has anybody done this before? Is there a more effective way?
Like Matt, I had a much better experience when I increased the timeout value slightly. Also, to mitigate the problem of single click firing twice (which I was unable to reproduce with the higher timer anyway), I added a line to the single click handler:
el.onclick = function() {
if (timer) clearTimeout(timer);
timer = setTimeout(function() { alert('Single'); }, 250);
}
This way, if click is already set to fire, it will clear itself to avoid duplicate 'Single' alerts.
If you're getting 2 alerts, it would seem your threshold for detecing a double click is too small. Try increasing 150 to 300ms.
Also - I'm not sure that you are guaranteed the order in which click and dblclick are fired. So, when your dblclick gets fired, it clears out the first click event, but if it fires before the second 'click' event, this second event will still fire on its own, and you'll end up with both a double click event firing and a single click event firing.
I see two possible solutions to this potential problem:
1) Set another timeout for actually firing the double-click event. Mark in your code that the double click event is about to fire. Then, when the 2nd 'single click' event fires, it can check on this state, and say "oops, dbl click pending, so I'll do nothing"
2) The second option is to swap your target functions out based on click events. It might look something like this:
window.onload = function() {
var timer;
var el = document.getElementById('testButton');
var firing = false;
var singleClick = function(){
alert('Single');
};
var doubleClick = function(){
alert('Double');
};
var firingFunc = singleClick;
el.onclick = function() {
// Detect the 2nd single click event, so we can stop it
if(firing)
return;
firing = true;
timer = setTimeout(function() {
firingFunc();
// Always revert back to singleClick firing function
firingFunc = singleClick;
firing = false;
}, 150);
}
el.ondblclick = function() {
firingFunc = doubleClick;
// Now, when the original timeout of your single click finishes,
// firingFunc will be pointing to your doubleClick handler
}
}
Basically what is happening here is you let the original timeout you set continue. It will always call firingFunc(); The only thing that changes is what firingFunc() is actually pointing to. Once the double click is detected, it sets it to doubleClick. And then we always revert back to singleClick once the timeout expires.
We also have a "firing" variable in there so we know to intercept the 2nd single click event.
Another alternative is to ignore dblclick events entirely, and just detect it with the single clicks and the timer:
window.onload = function() {
var timer;
var el = document.getElementById('testButton');
var firing = false;
var singleClick = function(){
alert('Single');
};
var doubleClick = function(){
alert('Double');
};
var firingFunc = singleClick;
el.onclick = function() {
// Detect the 2nd single click event, so we can set it to doubleClick
if(firing){
firingFunc = doubleClick;
return;
}
firing = true;
timer = setTimeout(function() {
firingFunc();
// Always revert back to singleClick firing function
firingFunc = singleClick;
firing = false;
}, 150);
}
}
This is untested :)
Simple:
obj.onclick=function(e){
if(obj.timerID){
clearTimeout(obj.timerID);
obj.timerID=null;
console.log("double")
}
else{
obj.timerID=setTimeout(function(){
obj.timerID=null;
console.log("single")
},250)}
}//onclick
Small fix
if(typeof dbtimer != "undefined"){
dbclearTimeout(timer);
timer = undefined;
//double click
}else{
dbtimer = setTimeout(function() {
dbtimer = undefined;
//single click
}, 250);
}
, cellclick :
function(){
setTimeout(function(){
if (this.dblclickchk) return;
setTimeout(function(){
click event......
},100);
},500);
}
, celldblclick :
function(){
setTimeout(function(){
this.dblclickchk = true;
setTimeout(function(){
dblclick event.....
},100);
setTimeout(function(){
this.dblclickchk = false;
},3000);
},1);
}
I found by accident that this works (it's a case with Bing Maps):
pushpin.clickTimer = -1;
Microsoft.Maps.Events.addHandler(pushpin, 'click', (pushpin) {
return function () {
if (pushpin.clickTimer == -1) {
pushpin.clickTimer = setTimeout((function (pushpin) {
return function () {
alert('Single Clic!');
pushpin.clickTimer = -1;
// single click handle code here
}
}(pushpin)), 300);
}
}
}(pushpin)));
Microsoft.Maps.Events.addHandler(pushpin, 'dblclick', (function (pushpin) {
return function () {
alert('Double Click!');
clearTimeout(pushpin.clickTimer);
pushpin.clickTimer = -1;
// double click handle here
}
}(pushpin)));
It looks like the click event masks the dblclick event, and this usage is clearing it when we add a timeout. So, hopefully, this will work also with non Bing Maps cases, after a slight adaptation, but I didn't try it.
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;
}
};