angular-inview icon indicating copy to clipboard operation
angular-inview copied to clipboard

Angular expression is not evaluated for an element when scrolling too fast by dragging the scrollbar

Open vinaynb opened this issue 9 years ago • 8 comments
trafficstars

Firstly this issue occurs when you have a large vertical scrolling area and you need to scroll a few hundred pixels very fast via dragging scroll bar to reproduce this.

I have maybe like 5000px of height to scroll and i have elements at 1500px and 2000px which have in view expressions attached to them. When i scroll too fast from 5000px to 0px at top of page by dragging the scroll bar it skips and fails to fire inview events for elements at 1500 and 2000px. I checked #98 which is similiar but the use case is a bit different. Therein he works on a scrollable container and here in my case i am working on whole

tag.

Any help ?

vinaynb avatar Jun 24 '16 12:06 vinaynb

Update

I did some reading and found that it may be possible that as scroll events are fired too quickly the browser is not able to run all the callbacks coming in at that speed and that maybe the reason they are skipped someway. I am not sure about this. Trying a few things. Will keep this thread updated.

vinaynb avatar Jun 24 '16 12:06 vinaynb

UPDATE

I looked deeper into the source code and found out that its the browser that, when scrolling fast, basically is not firing the onscroll callback that many times when it would if you would scrolling a little slower.

So i guess we can look more into issues with this library once we are sure it receives onscroll events callback form browser (which in this case doesn't happen). I have no idea how to get around this.

I can use debounce and limit scroll events but that does not solve my use case as i have elements at various heights that need repositioning during scroll and right now i do that repositioning in a function that is being called by inview.

vinaynb avatar Jul 07 '16 09:07 vinaynb

@thenikso Any chance you could have a pointer in the right direction to fix this ?

vinaynb avatar Jul 07 '16 09:07 vinaynb

I think one approach would be to interpolate scrolling events between last two known scrolling positions, however, it could be difficult to implement properly.

slavafomin avatar Jul 26 '16 13:07 slavafomin

some kind of delayed check might fix this. The library already have a check for the actual element position here so triggering the check should do. This of course assuming that any scroll event is triggered at all.

Anyone tried this already?

thenikso avatar Aug 17 '16 07:08 thenikso

Well it fires scroll event that is for sure because i put logs in onscroll callback and normally it would fire for 100 times for example so when scrolling fast it would log just 8 or 9 times.

But i am skeptical about that check that the library performs because i am guessing that the check function would indicate if any element is inview or went out of inview. Deciding that former or later from both is possible if onscroll fires frequently and scroll coordinates are available to us. In case when we are scrolling too fast the scroll event fires less frequently and newer coordinates are not available more frequently.

For ex library needs scroll offsets top - 200px and bottom 300px to trigger inview callback for particular element. But when scrolling too fast the offsets we have when onscroll fires is top 100px and bottom 200px. In this case the inview call back won't fire at all.

I suppose you already know this but this was just to mention the stuff i know here if it helps in any way.

vinaynb avatar Aug 17 '16 09:08 vinaynb

@vinaynb it would be nice if you could try this issue in v2, see #107

Also and example so that I could understand/reproduce the problem would be great

thenikso avatar Aug 19 '16 17:08 thenikso

@vinaynb

In IE 11, when we click and drag scrollbar it was not invoking inview. Also If we I try to scroll to last using 'ctrl + end'. This fix solves my issue. Am using Version: 2.2.0 Update 'signalFromEvent' method with below code. It should work. We should set useCapture 'true'

function signalFromEvent (target, event) { return new QuickSignal(function (subscriber) { var handler = function (e) { subscriber(e); }; var el = angular.element(target); el[0].addEventListener(event, handler, true); // el.on(event, handler); subscriber.$dispose = function () { el[0].removeEventListener(event, handler, true); // el.off(event, handler); }; }); }

farshad9037 avatar Sep 21 '17 14:09 farshad9037