twobin / react-lazyload

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

Load not work when parent element has display: none; #307

Open guilouro opened 4 years ago

guilouro commented 4 years ago

When I have a <LazyLoad> inside an element with display: none and I change this display to block, the content not load. This content only will load after a scroll interaction.

The code is like that:

export default function App() {
  const [tab, setTab] = useState(1);

  return (
    <div className="App">
      <ul className="tabs">
        <li>
          <button onClick={() => setTab(1)}>tab 1</button>
        </li>
        <li>
          <button onClick={() => setTab(2)}>tab 2</button>
        </li>
      </ul>

      <div className="content">
        <div style={{ display: tab === 1 ? "block" : "none" }}>
          <p>Content of tab 1</p>
          <LazyLoad>
            <img src="https://via.placeholder.com/150?text=Content 1" alt="1" />
          </LazyLoad>
        </div>
        <div style={{ display: tab === 2 ? "block" : "none" }}>
          <p>Content of tab 2</p>
          <LazyLoad>
            <img src="https://via.placeholder.com/150?text=Content 1" alt="2" />
          </LazyLoad>
        </div>
      </div>
    </div>
  );
}

The problem is that:

Screen Recording 2020-06-12 at 07 07 PM

And the complete code is here:

https://codesandbox.io/s/determined-hoover-z6cff?file=/src/App.js:104-960

geraldstrobl commented 4 years ago

@guilouro Did you found a solution? I'm facing the same problem.

Nantris commented 4 years ago

@guilouro Your example would be much clearer if not for a typo where both examples are called Content 1.

display: none means the element won't be rendered to the DOM at all, so making this work would be quite difficult. I can't get this library to work consistently with simpler use cases.

I'd advise either planning to submit a PR to make this work, or abandoning display: none in conjunction with this library for now.

guilouro commented 4 years ago

@guilouro Did you found a solution? I'm facing the same problem.

@geraldstrobl I created my own implementation using IntersectionObserver. But before it, I needed to change the location of the <LazyLoad />.

<LazyLoad>
  <div className="content">
    <div style={{ display: tab === 1 ? "block" : "none" }}>
      <p>Content of tab 1</p>
      <img src="https://via.placeholder.com/150?text=Content 1" alt="1" />
    </div>
    <div style={{ display: tab === 2 ? "block" : "none" }}>
      <p>Content of tab 2</p>
      <img src="https://via.placeholder.com/150?text=Content 2" alt="2" />
    </div>
  </div>
</LazyLoad>
guilouro commented 4 years ago

@guilouro Your example would be much clearer if not for a typo where both examples are called Content 1.

display: none means the element won't be rendered to the DOM at all, so making this work would be quite difficult. I can't get this library to work consistently with simpler use cases.

I'd advise either planning to submit a PR to make this work, or abandoning display: none in conjunction with this library for now.

Yeah sorry!! My typo may have generated some confusion. But the problem could be understood I think.

About a PR, at the moment I found another solution out of this lib for my case, but I guess important to maintain this issue opened until a real solution about display: none in conjunction with this library

berk9595 commented 3 years ago

Hi, is it fixed ?