Skip to content

Items stack on top of each other on the initial load until I resize #50

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
motdde opened this issue Mar 25, 2021 · 4 comments
Open

Items stack on top of each other on the initial load until I resize #50

motdde opened this issue Mar 25, 2021 · 4 comments
Labels
bug Something isn't working question Further information is requested

Comments

@motdde
Copy link

motdde commented Mar 25, 2021

Items stack on top of each other on the initial load until I resize

Screenshot 2021-03-25 at 12 01 53

@e-oj
Copy link
Owner

e-oj commented Jan 11, 2022

You need to set place the image in a div whose height is equal to the height of the image. That way, the grid item will always be the correct height even if the image loads slowly.

@e-oj e-oj added the question Further information is requested label Jan 11, 2022
@guillermohs9
Copy link

Sorry for necrobumping, I'm using the library for a dynamic number of images, but I'm facing the same issue as OP, even after setting the height of the div the same as the image it contains.

<div id="container-imagenes">
    {% for i in inmueble.imagenes_inmueble %}
        <div style="height:{{ i.thumb_height() }}px;">
            <a href="{{ url_for('static', filename='uploads/' + i.filename) }}"><img src="{{ url_for('static', filename='uploads/' + i.thumbnail) }}"></a>
        </div>
    {% endfor %}
</div>

thumb_height() is a method that returns the image height in px from the backend

I'm initializing the grid like this:

let magicGrid = new MagicGrid({
    container: "#container-imagenes", // Required. Can be a class, id, or an HTMLElement.
    items: {{ inmueble.imagenes_inmueble | length }},
    animate: true // Optional.
});
    
magicGrid.listen();

but images appear stacked until I resize the window and the grid starts working. Am I missing something?
Thx

@e-oj
Copy link
Owner

e-oj commented Jun 7, 2024

This needs more investigation

@e-oj e-oj added the bug Something isn't working label Jun 7, 2024
@dmos62
Copy link

dmos62 commented Jan 9, 2025

I ran into this and simply worked around it by having a debouncing listener that calls magicGrid.positionItems() when an image is loaded (img.addEventListener('load', () => debouncedCallback(img))). In my case, I was only experiencing the layout breaking (stacking) when the loading of images was very slow (large files, low bandwidth). Might be useful to someone. Below is the relevant excerpt from a template; excuse the roughness.

│      function debounce(func, delay) {                                                                                                │
│        let timeout;                                                                                                                  │
│        return function (...args) {                                                                                                   │
│          clearTimeout(timeout);                                                                                                      │
│          timeout = setTimeout(() => func.apply(this, args), delay);                                                                  │
│        };                                                                                                                            │
│      }                                                                                                                               │
│                                                                                                                                      │
│      function listenForChildImageLoads(parentElement, callback, debounceDelay = 300) {                                               │
│        const debouncedCallback = debounce(callback, debounceDelay);                                                                  │
│        const images = parentElement.querySelectorAll('img');                                                                         │
│                                                                                                                                      │
│        images.forEach((img) => {                                                                                                     │
│          // Check if the image is already loaded                                                                                     │
│          if (img.complete) {                                                                                                         │
│            debouncedCallback(img);                                                                                                   │
│          } else {                                                                                                                    │
│            img.addEventListener('load', () => debouncedCallback(img));                                                               │
│          }                                                                                                                           │
│        });                                                                                                                           │
│      }                                                                                                                               │
│                                                                                                                                      │
│      let itemCount = {{ pages | length }};                                                                                           │
│      <!-- // https://github.com/e-oj/Magic-Grid -->                                                                                  │
│      let magicGrid = new MagicGrid({                                                                                                 │
│        container: "#wall", // Required. Can be a class, id, or an HTMLElement.                                                       │
│        static: false, // Required for static content.                                                                                │
│        items: itemCount, // Required for dynamic content. Initial number of items in the container.                                  │
│        animate: true, // Optional.                                                                                                   │
│        gutter: {{ magicgrid_gutter }}, // Optional. Space between items. Default: 25(px).                                            │
│        // maxColumns: 5, // Optional. Maximum number of columns. Default: Infinite.                                                  │
│        // useMin: true, // Optional. Prioritize shorter columns when positioning items? Default: false.                              │
│        // useTransform: true, // Optional. Position items using CSS transform? Default: True.                                        │
│        // center: true, //Optional. Center the grid items? Default: true.·                                                           │
│      });                                                                                                                             │
│                                                                                                                                      │
│      magicGrid.listen();                                                                                                             │
│                                                                                                                                      │
│      const parent = document.getElementById("wall");                                                                                 │
│                                                                                                                                      │
│      // Necessary, because slow image loading otherwise breaks the grid                                                              │
│      listenForChildImageLoads(                                                                                                       │
│        parent,                                                                                                                       │
│        (img) => {                                                                                                                    │
│          // console.log('Debounced image load:', img.src);                                                                           │
│          magicGrid.positionItems();                                                                                                  │
│        }                                                                                                                             │
│      );

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants