Problem/Motivation
I've observed an interesting combination of issues when placing multiple views on a single page and enabling the infinite scroll with the autoload for all of them. This setup makes sense if we put the views in separate toggleable containers (eg. tabs, accordions, etc).
1. display:none
Since most of the togglable elements will be implemented with the property "display" set to "none" (display: none) when in collapsed/hidden state, the first issue will manifest when a view loads in one of the hidden containers. In this case, the vertical offset of the pager [ $pager.offset().top
] will hold the value of 0 (zero), and the condition within the isLoadNeeded function will be evaluated as true. This means it will keep on loading the next page in the view until it reaches the end. Basically, we will see a throbber appearing multiple times as soon as our page loads. Once it stops, we can toggle our container (tab) so it displays the view, and we will see all the whole result set loaded. (It may be similar to the issue described here -
https://www.drupal.org/project/views_infinite_scroll/issues/3207098
🐛
Immediate loading of more results without user scrolling (patch included)
Postponed: needs info
)
2. Only the first view can be autoloaded
After resolving the first issue, I encountered another one. With multiple views being on the same page, the first interaction with one of the views (loading the next result set), will remove the event binding [ $window.off(scrollEvent);
] for all of the views. The assumption is that the js behavior will run post-AJAX response, and we will re-bind the event handler again to the view. And this logic works fine with a single view, but not multiple - running the once() with the new context will associate the event handler only with a single pager, not all of them. Therefore the other view(s) will no longer be bound to the scrollEvent, hence making them unresponsible.
Steps to reproduce
1. Place multiple views (with infinite scroll & autoload enabled) on a single page inside togglable containers, such as UI Tabs (
https://www.drupal.org/project/jquery_ui_tabs →
). However, any container with the display property set to "none" will do.
2. When the page loads, the autoloader will start making AJAX calls to pull the next set of results into the view until it reaches the end of the result set.
3. If updating the test function
var isLoadNeeded = function () {
return window.innerHeight + window.pageYOffset > $pager.offset().top - scrollThreshold;
};
to
var isLoadNeeded = function () {
if ($pager.offset().top) {
return window.innerHeight + window.pageYOffset > $pager.offset().top - scrollThreshold;
}
else {
return false;
}
};
solvers our first issue, the second one can be replicated by toggling to different tabs/containers and scrolling down to trigger the autoload.
4. You will notice that only the first (any) view that starts autoloading will continue to do so. The rest will become unresponsive.
Proposed resolution
1. Adjust the condition for checking isLoadNeeded to make sure that the vertical offset for the pager is not zero
https://git.drupalcode.org/project/views_infinite_scroll/-/blob/2.0.x/js...
2. Keep track of the number of active views and re-bind the scrollEvent outside of the once() callback chain. I will provide my solution as a forked branch.
Similar Issues
Based on my search of the issue queue, I found similar issues, which may or may not be resolved by the proposed solution:
https://www.drupal.org/project/views_infinite_scroll/issues/3207098
🐛
Immediate loading of more results without user scrolling (patch included)
Postponed: needs info
https://www.drupal.org/project/views_infinite_scroll/issues/2877652
🐛
infinite scroll does not work for multiple views on a single page
Needs work