twobin / react-lazyload

Lazy load your component, image or anything matters the performance.
MIT License
5.85k stars 487 forks source link

Not working if two set of instances exist on the same page, one uses scrollContainer and one doesn't #281

Closed iNishant closed 11 months ago

iNishant commented 4 years ago

I have a page which contains two lists of images (images are lazy-loaded). One of the lists is inside an overflow-y div (I set the scrollContainer for this) and one is inside a normal div (no scrollContainer set).

The list inside the overflow-y div works, as I scroll inside the div it loads the images. But the list outside which is inside a normal div, weirdly, listens to the scroll events of the first list's scroll container (not window's).

Version: 2.6.5

ezgif-7-c26ec5430412

xmcp commented 4 years ago

+1 on this.

I believe this part of code causes the issue.

function componentDidMount() {
      // ...
      if (this.props.overflow) {
          // add listener to its parent
      } else if (listeners.length === 0 || needResetFinalLazyLoadHandler) {
          // add listener to window
      }

      listeners.push(this);
      // ...
}

So, this issue can be reproduced when:

When the first component mounts, it attaches scroll event to its parent, and pushes itself into listeners array.

Then, when the second component mounts, both if (this.props.overflow) and else if (listeners.length === 0 || needResetFinalLazyLoadHandler) check will fail, so no listener is attached on window.

ameerthehacker commented 4 years ago

@xmcp can you raise a PR if possible?

alexbidule commented 4 years ago

I've got the same issue here :) Please submit a PR to fix it, thank you

ArisAgeha commented 4 years ago

I've got the same issue here :) Please submit a PR to fix it, thank you

I've studied for whole night and found that this problem seems has been fixed.

add props overflow to your LazyLoad component, likes: <LazyLoad overflow ... /> maybe fix your problem.

see details at docs overflow.

xmcp commented 4 years ago

I put a reproducible demo on CodeSandbox.

You can see that the LazyLoad without overflow prop is broken until you scroll inside the overflowed div (triggering a visibility check).

ArisAgeha commented 4 years ago

I put a reproducible demo on CodeSandbox.

You can see that the LazyLoad without overflow prop is broken until you scroll inside the overflowed div (triggering a visibility check).

my solution is provide scrollContainer and overflow to each scroll instance. However, the scroll container should set overflow and specify height or position. (fortunately, specify height to the scroll contrainer is tolerable.)

see CodeSandBox

github0013 commented 4 years ago

source https://codesandbox.io/s/react-lazyload-modal-1p69u?file=/src/App.tsx view this page with network tab opened to see the actions https://1p69u.csb.app/

Screen_Shot_2020-08-05_at_10_45_00

I am not sure if I found how to avoid this issue, but adding these props seems to make it work.

For regular <Lazyload/>

For the <Lazyload/> inside overflow scrolling element

* if you don't give them height they all will be in the initial viewport, so that they all get loaded without scrolling, so giving height is important.