stutrek / scrollmonitor

A simple and fast API to monitor elements as you scroll
MIT License
3.3k stars 243 forks source link

Wrong position calculation after content insertion #86

Closed nomve closed 5 years ago

nomve commented 5 years ago

Hi,

thanks for the nice lib!

I have an issue to report: when the scrollmonitor gets initialised after there was some content inserted (e.g. advertisement) on the page, the position calculation could be off. I did some checking and it happens here https://github.com/stutrek/scrollMonitor/blob/695e786c6c3678b29b432d93be75335e23307775/src/watcher.js#L128

this.container.viewportTop does not match the actual scroll position because it's set initially and updated on e.g. scroll https://github.com/stutrek/scrollMonitor/blob/695e786c6c3678b29b432d93be75335e23307775/src/container.js#L125 . In our case it happens that the content gets inserted on the page, but this value does not update before scrollmonitor.create(). Replacing this.container.viewportTop with e.g. window.pageYOffset in that calculation removes the issue.

we have a workaround where we do some basic checks if the user stopped scrolling and only init after that, but maybe it can be fixed in the library itself.

nomve commented 5 years ago

so if anybody needs this, the best workaround I have is

scrollmonitor.viewportTop = window.pageYOffset; // pageYOffset works in all browsers we support, check yours
scrollmonitor.create(...);
sem4phor commented 5 years ago

There is a method documented for recalculating the boundaries manually: elementWatcher.recalculateLocation

justinmetros commented 5 years ago

Ran into similar issue using scrollMonitor on content rendered by VueJs. Similarly, was using getBoundingClientRect().top along with el.offsetHeight.

@nomve 's solution did the job.

For whatever reason, the recalculateLocations() and update() methods didn't work on my content unless it was in a setTimeout. 🤷‍♂️

stutrek commented 5 years ago

@sem4phor's solution is the intended way.