Problems with touchpad scrolling JS - javascript

When i scroll on touchpad with two finger on website it triggers scrolling inertially for 1s-1.5s.
So when i console.log('scroll') it , i see 'scroll' 68 times.
And because of that my programm triggers scroll event multiple times after some delay.
For example i scrolled on touchpad, it got event, and after 1.5s it still triggers scroll.
Question is that, how to make scroll event on touchpad not inertiall, or maybe limit scroll count?
document.addEventListener("wheel", this.wheelFilter, {passive: false});
wheelFilter = e => {
this.updateWheelPrevTime();
this.preventParentScroll();
if (
this._wheelTimeDiff > this._REAL_SCROLL_TIME
) {
this.onMouseWheel(e);
} else {
this.updateWheelFireTime();
}
}
Tried to debounce, doesnt work
Tried to unsubscribe event and then suscribe, it gets prev scroll again

Related

How to implement touch event in javascript that can be used as scroll on desktop?

I have animation with ScrollMagic library and I am also using GSAP. This is description of animation on scroll in steps. Every number is one scroll:
Add class overflow-hidden to body, to disable scrolling.
Move credit-cards
Move remove some images
Start doing transform: translate(x,y) rotateZ(zdeg)
Stop scrolling and make image that was translated sticky
So this works good with mouse on mousewheel event. The question is:
What is the best way to implement touch scroll with very same effect when user comes from iOS or Andorid. (When user comes to my website from android, iPhone, iPad etc.)
I know that there is touchmove event.
var image = document.getElementById('image-phone');
if(step == 1){
//do first step
}...
//mousewheel event
window.addEventListener('mousewheel', function (e) {
//this is implemented
});
//touchnmove event
window.addEventListener('touchmove', function (e) {
//should I use this event
});

Distinguish between automatic browser scroll and user scroll

When you scroll to the middle of the page and then refresh it, the browser will automatically scroll to the position you were on. I need to be able to differentiate between this automatic scroll and user scroll and attach different events to them.
I'm currently using
window.addEventListener('scroll', function(e) {});
to listen to the scroll event, but it gets triggered in both user and automatic scrolls.
Is there a way to tell between the two?
PS the suggested answer to similar question only uses mousewheel as an indication of user scroll, but if the user uses mouse to pull the scroll, it will fail
If you have two flags for both events, will that work?
I don't have a mouse to test this in whole unfortunately.
Try this fiddle
window.addEventListener( 'load', function() {
var mousewheel = 0;
var scroll = 0;
window.addEventListener( 'scroll', function(e) {
mousewheel = 0;
scroll = 1;
alert("mousewheel: " + mousewheel + ", scroll: " + scroll);
}, false);
window.addEventListener("mousewheel", function(e) {
mousewheel = 1;
scroll = 0;
alert("mousewheel: " + mousewheel + ", scroll: " + scroll);
}, false);
}, false);
As Manohar previously mentioned, you can use some combination of an onscroll event and an onwheel event. onscroll runs on all scroll events, whenever the content is interacted with. onwheel will run on mouse or trackpad scrolls, but not arrow scrolling. It's also worth mentioning that onwheel is not guaranteed to trigger an onscroll event, depending on the context. There's more detail provided in its documentation.
There's another similar question here with some additional suggestions on redesigning your app, while setting some boolean flags that can help determine who (computer or real user) is initiating the scroll.

detect if a touchstart/touchend has cancelled a scroll (momentum scroll)

i listen for touchstart and touchend events to make my app more responsive for mobile.
the problem is, if you 'flick scroll' (the page is still scrolling even after finger has left screen), and then stop the scroll with a tap - if there is an event on touchend attached to the element you tapped, it will fire.
I need a way to detect if the touchstart or touchend has stopped a scroll, so i can stop any events firing.
I tried setting a variable on scroll (i noticed scroll event on mobile only fires after scroll has finished, i.e page has stopped even on momentum scrolling):
$(window).scroll(function(){
cancelled_scrolling = true;
setTimeout(function(){
cancelled_scrolling = false;
},200);
});
however, when i tap it seems the touchend fires before the .scroll() event, as this doesn't work:
$('body').on('touchend', function(){
if(cancelled_scrolling){
alert('ahahahah');
return false;
}
//code to trigger events depending on event.target after here
});
how can I achieve this?
EDIT:
found an answer to this -
step1 - save the scrollTop on touchend
step2 - on touchstart, check the saved scrollTop against a new scrollTop
if they don't match, the page was scrolled even after the touchend event occurred
On touchStart, keep track of the scrollTop and scrollLeft for each parent node. On touchMove, check if any of these values have changed. If so, cancel the touch. This is slightly better than just checking on touchEnd because maybe they scrolled the page and then unscrolled.
You can also see this logic implemented here: https://github.com/JedWatson/react-tappable/blob/cf755ea0ba4e90dfa6ac970316ff7c35633062bd/src/TappableMixin.js#L120

How to deactivate a hover while scrolling

For performance reasons I want to deactivate a hover effect during scrolling and activate it again on scroll end. I'm using a class to activate and deactivate the hover.
Right now I have this
$(window).scroll(function(){
scrolling = true;
element.removeClass('hover');
setTimeout(function() {
if(!scrolling){
element.addClass('hover');
}
}, 200);
scrolling = false;
});
It applies a timeout of 200ms which checks if any other scroll events fired after this scroll. However, the timeout gets registered for every scroll event and fires multiple times after the scrolling ended.
I'm basically looking for a neat solution for this.

Programmatically halt -webkit-overflow-scrolling

I have a phonegap application that uses iOS native scrolling through -webkit-overflow-scrolling in a div. I want to be able to manually halt an ongoing scroll when the user clicks a button (to scroll back to the top of the page). Is this doable?
This is actually very possible when using fastclick.js. The lib removes the 300ms click delay on mobile devices and enables event capturing during inertia/momentum scrolling.
After including fastclick and attaching it to the body element, my code to stop scrolling and go to the top looks like this:
scrollElement.style.overflow = 'hidden';
scrollElement.scrollTop = 0;
setTimeout(function() {
scrollElement.style.overflow = '';
}, 10);
The trick is to set overflow: hidden, which stops the inertia/momentum scrolling. Please see my fiddle for a full implementation of stop scrolling during inertia/momentum.
Unfortunately this is not possible at the moment. The scroll event is triggered only when the scrolling has come to an end. As long as the momentum keeps moving the content no events are fired at all. You can see this in Figure 6-1 The panning gesture in Apple's "Safari Web Content Guide".
I also created a fiddle to demonstrate this behavior. The scrollTop value is set after iOS is done animating.
You can capture a touch event using 'touchstart' instead of 'click', as the click event sometimes doesn't seem to get fired until the momentum scroll completes. Try this jQuery solution:
$('#yourTrigger').on('touchstart', function () {
var $div = $('.yourScrollableDiv');
if ($div.scrollTop() === 0) {
return false; //if no scroll needed, do nothing.
}
$div.addClass('scrolling'); //apply the overflow:hidden style with a class
$div.animate({
scrollTop: 0
}, 600, function () {
$div.removeClass('scrolling'); //scrolling has finished, remove overflow:hidden
});
}
where the 'scrolling' class simply has the CSS property, overflow:hidden, which as #Patrick-Rudolph said, will halt any momentum scrolling in progress.
.scrolling {
overflow: hidden;
}
Note: It's best to use a callback function to tell when your scroll animation finishes, rather than setting a timer function.

Categories