Disabling Mouse Wheel for X Milliseconds with javascript? - javascript

I have a Website with RoyalSlider and Mousewheel support. http://www.linus.de/mark/drei.php
Everything works fine, but when i use my macbook (touchpad) the thing is that i fire several mousewheel events at a time when scrolling. so basically i want the script to pause for the time (or a bit less) it takes for one slide to change...
What i would need is a javascript which freezes the mousewheel for x milliseconds each time it's been triggered (after sending 1 or -1 to the slider)...

A Timer with a call back and a flag could work. When you start to scroll you set the flag and not allow the scroll wheel to function, see This Answer on how to disable the scroll wheel. When the timer fires (1 second or so) you reset the flag to let the person scroll again. See This page for how to set up a timer with a call back

I can't give you a full code example since you didn't give any code to us but here's the solution.
When you scroll the mouse, a scroll animation begins. Create a variable somewhere outside the event handler, let's say
var animationInProgress = false;
and set it to true right before the animation begining. Then, this RoyalSlider plugin must have some kind of complete handler (I bet it has - it's paid though) - a parameter where you can put a function to be called when the animation is over. So, you put there a function similar to that:
function() {
animationInProgress = false;
}
The last thing is to check the value of the animationInProgress variable each time you want to run an animation
if (false === animationInProgress) {
//run the animation
}
I hope you get the idea.

Related

jQuery ScrollTop: Each animation needs to be finished before jumping to the next one

I'm using a live search plugin that uses scrollTop to scroll to found text on the page.
The code use keyboard arrow keys up and down to choose between results, the only problem is that due to the animation time of the scrollTop, the last action result won't be achieved before the result from the previous actions haven't been achieved after the animation time that is specified in the code.
What it means is that if I press down key too many times in a row, let's say 10 times, after the last item have been found on page, even if I immediately press the up key, I'll have to wait until the last 10 events have been executed, then it will execute the last event that uses the up key.
$('html,body').animate({scrollTop: mark.offset().top-100}, 100);
Working Fiddle
Is there anyway to cancel the previous event and jump to the next one if the key is pressed at the same time the animation is happening?
Ok I see the lag now, you will need to create a queue with jQuery first then clear it when the search changes direction with:
$(element).clearQueue();
I couldn't recreate the laggy effect you described. But there is a function in jquery animate you can use to achieve this.
$(element).stop()
I updated your jsFiddle to stop the previous animation before starting a new one, here.
Also you can read more about .stop() here.

Are there any javascript/jQuery events that are like an "onmousestop" or any events equivalent to "onmousewheel" for an optical mouse and/or touchpad?

I am trying to create a Javascript-based inactivity timeout for my site. The function which controls inactivity is very simple; a form value recording the "initial time" is reset concomitantly with any event (the assumption being any event should be indicative of activity):
function ResetTimeout() {
document.forms.TimeoutForm.initialtime.value = (new Date().getTime()) / 1000;
}//This function is called on each event, such as an onclick
In a separate function, when new Date().getTime() (that is, the time at this moment) - document.forms.TimeoutForm.initialtime.value (in milliseconds) > 720000 (12 min), a hidden logout form is submitted. Right now, I am binding these events to the <body> as follows:
<body onclick="ResetTimeout()" onkeydown="ResetTimeout()" onscroll="ResetTimeout()">
This works for almost all cases, since each page on my site requires a vertical scrollbar to see the bottom of the page. Any mouse or touchpad press is also captured, anywhere on screen. However, two valid outliers would be for (a) the user that never scrolls down, and never clicks the mouse/touchpad nor presses any keys but is still somehow engaged on the site and (b) the user that is (unlikely but possible) moving the mouse left/right but never scrolling, clicking, nor pressing any keys. Both of these users would technically be active on the site but would be considered inactive by my code.
I tried accounting for these users by binding the onmouseover or onmousemove events to the <body>, but these events are continuously triggered even if you do not move the cursor at all. I found HTML5's onmousewheel, but this does not work for an optical mouse nor touchpad (function never fires so event is never recorded even as you move the cursor all over the screen).
Is there an event in jQuery or Javascript that is recorded only whenever a user MOVES the mouse anywhere on the screen (and does not remain motionless)? That is, an event which fires only when xcoord2 - xcoord1 (or same for ycoord) does not equal zero over some time interval? My gut feeling is this may be complex and may require the code to record x or y coordinates at different time intervals and then compare. Alternatively, is there any event that would be something like onmousestop (a cursor-in-motion stops moving)? I read about "onwheel" (click here) but I need something for all browsers. Any suggestions? Thanks
The mousemove event is not triggered unless the mouse actually moves
The mousemove event is fired when a pointing device (usually a mouse) is moved while over an element
so simply
var timer;
$(document).on('mousemove', function() {
clearTimeout(timer);
timer = setTimeout(function() {
logout();
}, 720000);
});
FIDDLE

Sencha Touch button click slower than list item click?

I am in the process of profiling Sencha Touch applications and came across the fact that a click of a button triggers action faster as opposed to a click of a list item from Ext.List for the same action. My timeline profiling data indicates that the action is performed on Timer Fired condition for list item. This timer's timeout is 300ms. Now, for buttons there's no timer, so the action is performed as soon as there's touch end (and other Sencha processing common to all clicks).
In my case, the action is a simple transition to another view without any animation.
Following are the screenshot of my timeline data running application on an iPhone 4.
Transition by button click/tap:
Transition by list item click/tap:
I tried to dig into the source code, but could not understand why this is actually happening. My hypothesis is that list waits for that 300ms to see if it was actually a tap action or a scroll action. But is this true? If not, can anyone point me towards the right direction to verify if this hypothesis is true or not?
Any help would be highly appreciated!
I think is because of the pressedDelay config, which for Ext.Button default is 0 and for Ext.DataView is 100 ms.
Aditionally, the button fires directly the handler function. And the dataView executes store.getAt(index) to find the record object and pass it to the itemTap callback what adds some ms.
Got it!
This 300ms wasn't because of the scroll event, rather it was to recognize if its a single or a double tap event. If you look at DoubleTap recognizer source code, it has a maxDuration of 300 ms in the config object. This is used to set the time out for firing singleclick event.
onEnd function:
else {
this.singleTapTimer = setTimeout(function() {
me.fireSingleTap(e, touch);
}, maxDuration);
}
And on every touchStart event, this timeout is cleared.
onTouchStart: function(e) {
if (this.callParent(arguments) === false) {
return false;
}
this.startTime = e.time;
clearTimeout(this.singleTapTimer);
},
To note, this is a private class, so we cannot rely on it. But if anyone wants to decrease the duration between a tap event and firing off its logic, reduce this time. I have noticed that setting it to 150ms will make list item click much much faster, but at the same time, it also opens up the room for ghost click in other screens, since the events are queued up.
You can disable or edit recognizers configuration in Ext.application: http://www.sencha.com/forum/showthread.php?205692-Reduce-delay-of-itemsingletap-on-xtype-list

DOM element visiility and requestAnimationFrame

I was reading an article on HTML5Rocks that gave an example about scrolling through a webpage and checking an array of DOM elements offsetTop's to see if they should be visible.
The article says the best practice way of doing this would be to update a variable with the windows current offset top every time a scroll event is fired. When the first scroll event is fired, it triggers the requestAnimationFrame process of checking offsetTop's of the DOM elements. This decouples the visibility logic from the scroll event.
While I understand the benefit of certainly decoupling these two processes (since the scroll event could be called hundreds of times a second), I can't see the benefit of running the visibility logic every 16ms after the first scroll event, regardless of whether the user has continued to move or not..
Can someone please explain what part of the process I'm missing here?
I think it's well explained in the article.
What else can we do? Well for one thing we are constantly running
requestAnimationFrame and that’s not necessary if we haven’t just
scrolled since nothing will have changed. To fix that we have the
onScroll initiate the requestAnimationFrame
Now whenever we scroll we will try and call requestAnimationFrame, but
if one is already requested we don’t initiate another. This is an
important optimization, since the browser will stack all the repeated
rAF requests and we would be back to a situation with more calls to
update than we need.
Thanks to this setup we no longer need to call requestAnimationFrame
at the top of update because we know it will only be requested when
one or more scroll events has taken place. We also no longer need the
kick off call at the bottom, either, so let’s update accordingly:
var latestKnownScrollY = 0,
ticking = false;
function onScroll() {
latestKnownScrollY = window.scrollY;
if (!ticking) {
requestAnimationFrame(update);
}
ticking = true;
}
function update() {
ticking = false; // reset the tick so we can capture the next onScroll
var currentScrollY = latestKnownScrollY;
// Do visibilty logic and animation here
}
So, "regardless of whether the user has continued to move or not" is not really true. update is only called during (or a littlebit after) the scroll, and at a browser-choosen frame rate instead of a rate of hundreds of events per seconds.

How do I detect whether scroll events are fired *only once* like on touch devices?

iOS devices (and likely Android ones) have a different scrolling behavior: The scroll event is only fired once after the entire scroll is done.
How do I detect whether the browser behaves this way?
I could use window.Touch or Modernizr.touch but they don't tell me anything about the scroll behavior, it would be like asking if someone is French to understand whether they like croissants, right? :)
I think you're right about the detection because there will be some devices that will support both touch and mouse behaviors (like Windows 8 tablets), some will only support touch (phones) and some will only support mouse (desktops). Because of that, I don't think you can conclusively say that a device only has one behavior as some could have both.
Assuming that what you're really trying to do is to figure out whether you should respond immediately to every scroll event or whether you should use a short delay to see where the scroll destination ends up, then you could code a hybrid effect that could work well in either case.
var lastScroll = new Date();
var scrollTimer;
window.onscroll = function(e) {
function doScroll(e) {
// your scroll logic here
}
// clear any pending timer
if (scrollTimer) {
clearTimeout(scrollTimer);
scrollTimer = null;
}
var now = new Date();
// see if we are getting repeated scroll events
if (now - lastScroll < 500){
scrollTimer = setTimeout(function() {
scrollTimer = null;
doScroll(e);
}, 1000);
} else {
// last scroll event was awhile ago, so process the first one we get
doScroll(e);
}
lastScroll = now;
};
doScroll() would be your scroll processing logic.
This gets you a hybrid approach. It always fires on the first scroll event that arrives when there hasn't recently been a scroll event. If there are a series of scroll events, then it fires on the first one and then waits until they stop for a second.
There are two numbers that you may want to tweak. The first determines how close scroll events must be to consider them rapid fire from the same user action (current set to 500ms). The second determines how long you wait until you process the current scroll position and assume that the user stopped moving the scrollbar (currently set to 1s).

Categories