jquery masonry breaks(stacks images) in chrome/safari but only on first load
Asked Answered
L

12

14

It seems that when I try to load the page, all the images are stacked on top of one another. But if you were to click a link which takes you to the same page (like the home link) then masonry kicks in. So I think masonry is loading too early, like before jquery readies the page or something.

Here my jquery call:

$(document).ready(function(){
    $('#image_roll_container').masonry({
        itemSelector: '.box'
    });

....

Here's the page in question:

http://ratattoos.com/

it works just fine in firefox and IE8.

Laborsaving answered 19/9, 2011 at 20:6 Comment(1)
Please add a screenshot -- your link is broken.Demerit
L
11

looks like I needed a plugin called imagesLoaded in order for the Monsry script to work properly with the likes of chrome and safari

Laborsaving answered 1/10, 2011 at 16:37 Comment(2)
How to use it? or initialize it with Masonry ?Providential
$('#masonry').imagesLoaded( function() { // images have loaded and you can init masonry });Cinerarium
H
20

I've managed to fix this problem with the following tweak:

<script type="text/javascript">
    $(document).ready(function(){
        $('img').load(function(){
            $(".content_photo").masonry();
        });
        $(".content_photo").masonry();
    });
</script>
Hydroplane answered 10/2, 2012 at 21:34 Comment(0)
L
11

looks like I needed a plugin called imagesLoaded in order for the Monsry script to work properly with the likes of chrome and safari

Laborsaving answered 1/10, 2011 at 16:37 Comment(2)
How to use it? or initialize it with Masonry ?Providential
$('#masonry').imagesLoaded( function() { // images have loaded and you can init masonry });Cinerarium
P
8

Tried everything suggested in this thread, nothing worked, then found this:

$(window).load(function(){   $('#content').masonry(); });

Works fine now, found it here: https://github.com/desandro/masonry/issues/35

Original post author: https://github.com/desandro

Phlebitis answered 22/4, 2013 at 19:50 Comment(0)
D
5

You are correct about the imagesLoaded. It was working fine in Firefox but stacking in Chrome/Safari.

Here is the link https://masonry.desandro.com/layout.html#imagesloaded

Code:

var $container = $('#container');

$container.imagesLoaded( function(){
  $container.masonry({
    itemSelector : '.box'
  });
});
Discontinuation answered 26/3, 2012 at 14:7 Comment(0)
M
1

I recently came across this issue. To fix it, I utilized the img width and height attributes. The issue resolved itself.

Margiemargin answered 4/10, 2012 at 19:33 Comment(0)
S
0

Another way, if you know the image heights, is to assign them in the CSS before you load Masonry, then the layout is faster than waiting for the images. This method works if, for example, all your images are the same size. Then your site will still load quickly on slow connections, like mobile.

I posted a bit of script for alternative method here:
http://instancia.net/loading-jquery-masonry-on-mobile/

If you use this script, edit the numbers to match yours.

Squeeze answered 26/1, 2013 at 20:4 Comment(0)
M
0

On Firefox and on my iPad 2 masonry was working fine but in chrome and safari on OS X the elements were overlapping/stacking on page load and until a window resize even happen. After digging in the code of jquery.masonry.js I found that I can trigger a resize() right after creating the masonry so that all elements rearrange properly. Now everything is working fine.

jQuery(document).ready(function(){
var $container = $('#container');
$container.imagesLoaded(function(){
    $container.masonry({
    itemsSelector: '.thumbnail',
    isFitWidth: true
    }).resize();
}); 
})

all of the other solutions: (window).load, setting width & height in CSS and on img attributes, etc, just didn't work for me.

Manrope answered 24/3, 2013 at 23:4 Comment(0)
R
0

It needs heights in these browsers to display correctly like Jennifer said. I use php's getimagesize() function to get the height and width of the images. Works perfectly now.

Rheology answered 22/10, 2013 at 2:29 Comment(0)
T
0
<script>
        var container = document.querySelector('#masonry');
        var msnry = new Masonry( container, {
            itemSelector: '.item',
            "columnWidth": 200,
        });
        $('.item img').load(function(){
                var msnry = new Masonry( container, {
                itemSelector: '.item',
                "columnWidth": 200,
            });
        })
</script>
Trow answered 13/11, 2013 at 8:41 Comment(1)
Please only use the english language.Lamellate
F
0

if use $('img').load(function() F5(refesh) => error

New Methods:

$(window).on('load resize', function() {
  if ($('.masonry-wrap').length) {
    $('.masonry-wrap')
    .css('max-width', $(window).width());
  }
});
$(window).on('load', function() {
  if ($('.masonry-wrap').length) {
    setTimeout(function() {
      $('.masonry').masonry({
        columnWidth: 0,
        itemSelector: '.grid-item'
      });
    }, 1);
  }
});
<div class="masonry-wrap">
  <div class="masonry">
    <div class="grid-item">...</div>
    <div class="grid-item">...</div>
    ....
  </div>
</div>
Feinstein answered 31/1, 2015 at 19:27 Comment(0)
P
0

The "load" event will trigger for every image in the DOM, this is overkill. You need to update the layout of the masonry when the last image in the DOM loads. Here is the code:

$(document).ready(function(){
    // init the masonry on document ready event;
    // at this point the images are not loaded so the layout will break UNLESS you set up the correct values for the "width" and "height" attributes of the img tags
    $('.content_photo').masonry();

    // to make sure the layout will not break apart we update the masonry layout just after the last image from the DOM was loaded
    var total_images = $('img').length;
    var counter = 1;
    $('img').load(function() {
        if(counter == total_images) {
            alert('the last image in the DOM was loaded. now we can update the masonry layout');
            $('.content_photo').masonry('layout');
        }
        counter++;
    });
});
Peculiar answered 7/4, 2016 at 11:13 Comment(0)
M
0

I had the reverse problem as described: first load worked fine in Mac OS X Safari, but changing the grid with all new items caused them all to stack in the top left corner. Further, waiting for ready event and setting CSS height & width on our elements didn't fix it.

On our site, we have categories of data that display in the masonry grid, and only one category shows at a time. A user could switch the category at any time and trigger an AJAX request to load in the new data. In latest Safari (9.1, 10) and browsers like Chrome, we could simply do this when changing the category to swap in all new elements:

    // domData is HTML string from the server
    // IMJS is our global variable that we use for globals and lookups
    $("#divTemplateCategoryName").after(domData); // insert new HTML
    var elementsToAdd = $(".grid-item-template-info"); //select the elements
    IMJS.MasonryGrid.masonry('addItems', elementsToAdd); // tell masonry to add them
    IMJS.MasonryGrid.masonry('layout'); // tell masonry to layout again

However, in some versions of Safari that wouldn't work, and we had to do this instead:

    // domData is HTML string from the server
    // IMJS is our global variable that we use for globals and lookups
    IMJS.MasonryGrid.masonry('destroy'); // destroy the grid
    $("#divTemplateCategoryName").after(domData); // insert new HTML
    InitMasonry(); // re-do our entire masonry init

Because I don't have the time to track down every browser version that might be affected by this bug, I switched to the latter method for all browsers.

Magnesia answered 22/8, 2016 at 17:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.