I'm trying to create a scrolling button that reacts differently to a quick click event than it does to a prolonged MouseDown (click and hold). The quick click event will scroll a specific number of pixels while click and hold will slowly scroll the pane until mouse up where it will stop.
This is what I have currently:
var mdown;
$('.next').bind('mousedown', function(event) {
mdown = event.timeStamp;
moving = setInterval(function(){
$('#main').scrollLeft($('#main').scrollLeft() + 5);
}, 1);
});
$('.next').bind('mouseup', function(event) {
clearInterval(moving);
if ((event.timeStamp - mdown) < 100)
$('#main').animate({ scrollLeft : '+=800'}, 500);
});
Is there another way of doing this without comparing event timestamps? Is a click event treated any differently than mousedown/mouseup? Thanks!
Check this plugin(It defines an event to handle long clicks):
https://github.com/pisi/Longclick
Related
I have a carousel and I need to make him work as Instagram carousel does.
On click change slide, but on mousedown just stop animation. My JQuery :
$(".fancy-carousel").on('mousedown',function (e) {
...stop animation
});
$(".fancy-carousel").on('mouseup',function (e) {
..continue animation
});
$(".fancy-carousel").on('click',function (e) {
..change slide
});
But i don´t know how can i let script know about difference between "click" and "mousedown". When i click on element and hold for a time, it stop animation but after "mouseup" it trigger "click" event too. Is there any way how to split this events? Or should i do it with some calculating of mouse hold time?
A “click” is just a full cycle of a “mousedown” and a “mouseup”. You can’t have one without the other.
For your code to know the difference, you’ll need a variable that tracks your intentions.
Create a variable to track your intention - default it to “click”.
var intention = "click";
In your mousedown function, pause the animation and start a timer. We will use this timer to detect how long the mouse is down for (I.e, if it’s for over a second, it’s not a click and you just want to trigger mouseup)
var detectIntention = setTimeout(function(){
intention = "mouseup";
})
In your mouse up function, cancel this timeout. If mouse up is called after just a few MS, then you want to do a click.
clearTimeout(detectIntention);
if (intention === "mouseup") {
// do mouseup stuff
}
// reset intention
intention = click;
Check in your click function that you wanted to do a click;
if (intention === "click") {
// do click stuff
}
I'm trying to detect "wheel" events on a web page to intercept these and implement a page-by-page scroll instead.
This works fine with a mouse - using the wheel seems to trigger a single "wheel" event, which I'm able to intercept.
I have an issue with mousepad however, which seems to fire multiple successive "wheel" events. I have tried throttling my custom scroll function using underscoreJS and disabling trailing end, but somehow the subsequent events are still fired..
wheelHandlerThrottled: _.throttle(function(e, pageNum) {
// My scrolling code
}, 500, {leading: true, trailing: false})
When on page 1 and scrolling down with mousepad, I'll get the following behavior:
Scroll to page 2
500 ms pause
Scroll to page 3
500 ms pause
Scroll to page 4
Logging events in the console shows me that 3 "wheel" events are fired and processed.. so it's like my throttling is not working, but instead a pause is inserted between every event.
Throttle seems to just pile on the scroll events.
I would do it with something like this jsfiddle
Essentialy a event listener for mousewheel and when its triggered there is a timeout for x miliseconds until it can be triggered again.
let canScroll = true;
let marginTop = 10;
const element = $('#custom');
window.addEventListener('mousewheel', (event) => {
if (canScroll) {
if (event.deltaY > 0) {
marginTop += 10;
} else {
marginTop -= 10;
}
element.css('margin-top', marginTop + 'px');
canScroll = false;
setTimeout(() => {
canScroll = true;
}, 1000);
}
});
I don't know whether it is only Chrome problem (can't check now), however let's try the following piece of code, where we bind two events to some element:
$("div").on({
mousemove: function(e) {
console.log("move");
},
click: function(e) {
console.log("click");
}
});
If we try to click the element, we'll find that for some reason mousemove event fires immediately after click, so in console we have:
>> ...
>> click
>> move
DEMO: http://jsfiddle.net/gKqVt/
Note, that mousedown and mouseup events work by the same scenario.
I saw many questions on SO about the same problem, but none (in my search) gave the straightforward idea what to do in order to fire the click event only.
Mousemove appears to be binded to every mouse action there is in Chrome, so store the mouse position every time the mouse "moves" and check it against the previous mouse position to validate that it has indeed "moved"..
var currentPos=[];
$("div").on({
mousemove: function(e) {
if (e.pageX!==currentPos[0] && e.pageY !==currentPos[1]){
currentPos=[e.pageX,e.pageY];
this.innerHTML = "Event: " + e.type;
console.log("move");
}
},
click: function(e) {
this.innerHTML = "Event: " + e.type;
console.log("click");
}
});
Demo | Source
This appears to be a bug in Chrome that was first reported back in November, and remains open.
Chromium Issue 161464
If you are targeting Chrome specifically then it may be worth comparing the event timestamps to get around it (using some minimum delta time as #ExplosionPills suggested. But if you're looking for general behavior it seems that you're better off treating them as separate events, because in every browser but chrome (and maybe Safari? the bug is labeled as webkit-core) they will in fact be separate events.
This behavior is odd, and it doesn't seem to occur universally (happens in Chrome/IE for me, but not FFX). I think you haven't gotten a straight answer because there isn't one really.
It's possible that the mouse is moved very slightly by the click action, but that's probably not it. Could just be a browser quirk. These don't even seem to be the same event since stopImmediatePropagation in click doesn't stop mousemove from firing. If you focus the element and hit a keyboard button, it will actually trigger click and only click.
Since this is so quirky, it seems like the only way to deal with it is times. As much of a kludge as this is, I do notice that click happens one millisecond before mousemove, so you could get close by comparing the click timestamp + 2 (or 10):
mousemove: function(e) {
if ($(this).data('lastClick') + 10 < e.timeStamp) {
http://jsfiddle.net/gKqVt/3/
This is very specific, though. You should consider not having behavior that occurs immediately on mousemove since it's so frequent.
Why don't just check that did the mouse really move or not like below:
function onMouseDown (e) {
mouseDown = { x: e.clientX, y: e.clientY };
console.log("click");
}
function onMouseMove (e) {
//To check that did mouse really move or not
if ( e.clientX !== mouseDown.x || e.clientY !== mouseDown.y) {
console.log("move");
}
}
FIDDLE DEMO
(I think it's will still correct in all browsers)
var a,b,c,d;
$(".prd img").on({
mousedown: function(e){
a= e.clientX, b= e.clientY;
},
mouseup: function(e){
c= e.clientX, d= e.clientY;
if(a==c&&b==d){
console.log('clicked');
}
}
});
Try this. This one work correct.
I noticed this behavior when I needed to differenciate between mousedown and mouseup without dragging between the two and mousedown and mouseup with dragging between them, the solution that I used is as follows:
var div = $('#clickablediv');
var mouseDown = false;
var isDragging = 0;
div.mousedown(function () {
isDragging = false;
mouseDown = true;
}).mousemove(function () {
if (mouseDown) isDragging++;
}).mouseup(function () {
mouseDown = false;
var wasDragging = isDragging;
isDragging = 0;
if (!wasDragging || wasDragging<=1) {
console.log('there was no dragging');
}
});
when I tried it, I noticed that periodacaly a simple click makes "isDragging" equal to 3 but not very frequently
I added the following to my mouseMove(event) function:
function mouseMove(event)
{
if ((event.movementX == 0) && (event.movementY == 0)) return;
Not clear why it triggers when there is no movement, but this worked for me. Had the issue in Chrome 102.0.5005.61 at least. It did not happen a few years ago.
I have set event listener onmouseUp.
I want to make difference between onmouseUp in short time (just click) and onmouseUp after holding lets say more than one second OR onmouseDown with mouseMove together.
Reason:
I'm listening button number 2 (which == 2), and i want to have function onclick to center something and zoom something with holding button2 and moving mouse up/down. But not to do it both in one time.
Is it possible in JS or jQuery with any integrated method?
Get NOW on Mouse Down
Get NOW on Mouse Up
var start = 0;
$('#button').mousedown(function () {
start = $.now();
});
$('#button').mouseup(function () {
end = $.now();
$('#output').html(end - start);
if (end - start > 1000) {
alert('you just held the mouse for 1 second');
}
});
DEMO
You can measure the time that was spent for the action before mouse is up:
E.g.:
$(<your_element>).on(<your_event_type>, function(e) {
start = new Date().getTime();
});
Then do a similar thing for the other event type and calculate a stop value.
Compute the difference stop - start and make a decision.
This will also cover the case when the mouse is moved while the click is pressed ( because it is bigger than a specified threshold ). But if you want to check that mouse was moved, you can use its coordinates (e.pageX and e.pageY).
I would like to display a helpful DIV that basically shows the user how to accomplish something on a particular page, but only if the user has been idle for a period of time, say, 30seconds.
What I mean by "Idle" is:
Not clicking any links
Not right clicking anywhere
Exceptions:
I would like to exclude the following conditions from the Is User Idle rule:
User has scrolled up or down/left or right
User has pressed mouse button on an empty area on the site/ or on an element which has no source/link for example, an image with no hyperlink.
and, Pressing keyboard buttons
Can this be done? Or can we only detect when a particullar event occurs?
Any thoughts/suggestions/resources will be greatly appreciated.
Thank you
fairly basic...
var trigger = 30000
$.(function(){
setInterval('displayInf()',trigger );
$('body').bind('click dblclick keypress mousemove scroll', function(){
clearDisplayInf();
});
});
function displayInf()
{
$('body').append('<div>Your notification div</div>');
}
function clearDisplayInf()
{
trigger = clearInterval(trigger);
trigger = setInterval('displayInf()', 30000 );
}
that should do the trick - you could add some script to make the div removable and start the timer again once its removed but that just polishing up really..
Event in DOM would bubble from leaf to root, thus add a event listener on document would make sense.
But since we are possibiliy stop bubbling for click event in certain element, register click event on document may not work perfectly, in that case, register mousedown and mouseup event would help:
var timer; // create a timer at first
// restart timer on click
function startIdle() {
timer = setTimeout(function() { /* show div */ }, time);
}
if (document.addEventListener) {
document.addEventListener('mouseup', startIdle, false);
}
else {
document.attachEvent('onmouseup', startIdle);
}
// start the first timer
startIdle();