Using masonry with imagesloaded - javascript

I'm a js newbie and hope this questions doesn't seem too stupid.
I'm using masonry for my site - works fine.
I wanted to let my boxes appear just when masonry finished loading. Searching in the internet I found several posts recommending to use imagesloaded Plugin to solve this issue. It just doesn't change anything. That means: my layout and content boxes keep being messed up until masonry finished loading, just then the boxes suddenly jump to their right positions.
My code:
$(document).ready(function() {
var $container = $('#post-area');
$container.imagesLoaded( function() {
$container.masonry({
itemSelector : '.box',
columnwidth: 300,
gutter: 20,
isFitWidth: true,
isAnimated: !Modernizr.csstransitions
});
});
});
I'm also getting this firebug-error:
TypeError: EventEmitter is not a constructor
ImagesLoaded.prototype = new EventEmitter();
I'm loading the imagesloaded js like this at the end of my website (I couldn't find any information if imagesloaded is already included in masonry or not, some wrote that it's not included anymore - confusing):
<script src="http://www.domainname.com/js/imagesloaded.js"></script>
I would be really happy if someone could help me. And tell me if imagesloaded is even the right plugin to solve this issue!

imagesLoaded is not included in Masonry, so you should use separate plugin. I would recommend to use compiled .min version.
Regarding your problem with stacked images: the problem is not in imagesLoaded neither Masonry.
In your code imagesLoaded is waiting until all images loaded and then fires masonry. Having all images loaded, Masonry plugin can properly define their sizes and put on grid. Before that, browser loads images as usually and display 'em according to defined CSS, that's why they're messed up.
One of the possible solution is to hide elements by default and then fadein while imagesLoaded confirm, that images loaded:
$(document).ready(function() {
var $boxes = $('.box');
$boxes.hide();
var $container = $('#post-area');
$container.imagesLoaded( function() {
$boxes.fadeIn();
$container.masonry({
itemSelector : '.box',
columnwidth: 300,
gutter: 20,
isFitWidth: true,
isAnimated: !Modernizr.csstransitions
});
});
});

Another solution is to initialize Masonry inside $(window).load() instead of $(document).ready(). This will trigger Masonry after all the media on the page has loaded – images, fonts, external scripts and stylesheets, etc.
$(window).load(function(){
$('#container').masonry({
// options...
});
});

Install
npm install masonry-layout --save
npm install imagesloaded --save
Then vanilla js options would be
'use strict'
const Masonry = require('masonry-layout')
const imgloaded = require('imagesloaded')
const elem = document.querySelector('.grid')
var imgLoad = imgloaded( elem )
function onAlways() {
const msnry = new Masonry( elem, {
// options
columnWidth: '.grid-sizer',
// do not use .grid-sizer in layout
itemSelector: '.grid-item',
percentPosition: true,
gutter: 10
})
// console.log('all images are loaded')
}
if (elem) {
// bind with .on()
imgLoad.on( 'always', onAlways )
// unbind with .off()
// imgLoad.off( 'always', onAlways )
}
Then check the console for all images are loaded.

Related

Masonry- divs overlapping with imagesLoaded plugin

I have the Masonry plugin and the Images Loaded plugin and it seems imagesloaded isn't working. When I refresh the page the divs overlap. Only after resizing the browser window does the overlapping corrects itself. Sometimes upon refreshing it seems it does work... it's pretty random. I'm a newbie with jQuery and javascript.
I hosted the single html page here so you can see what I'm talking about: masonry test
Here's how I'm initializing, but you can see the full code if you look at the source code for the link above because the problem might be elsewhere.
$(document).ready(function() {
// Initialize Masonry
$('#content').masonry({
columnWidth: 320,
itemSelector: '.item',
isFitWidth: true,
isAnimated: true,
}).imagesLoaded(function() {
$(this).masonry('reload');
});
});
The problem is that imagesLoaded() is being called before the masonry plugin finishes initializing. If you look in the browser console on your test page, you will see an error to that affect.
Take a look at the example on the developer's site for how to use imagesLoaded together with masonry. Instead of chaining the functions, you should wait until the images have loaded to initialize masonry.
$('#content').imagesLoaded(function() {
$('#content').masonry({
columnWidth: 320,
itemSelector: '.item',
isFitWidth: true,
isAnimated: true,
});
});
You might be able to do it how you originally attempted (ie. chaining the methods), but you cannot use $(this) in your imagesLoaded function. This function is a callback, so it is not being executed synchronously. If you change your function to
$('#content').masonry('reload');
it might work they way you wanted, but I haven't tested this.

Masonry plugin returning error when used with Infinite Scroll in tumblr

I know alot has been written about this, but I feel I am close to solving the issue.
I am trying to use a theme which has masonry installed, but now the client is asking for infinite scroll and this is causing me issues.
Initially I was seeing errors in the console for both the masonry and infinite scroll plugins, now at least I am only seeing a masonry error. And it does look as though the infinite scroll function is calling subsequent pages of posts, it's just that Masonry is struggling to append them to the page in the right layout.
I think it is something to do with my callback function, but worried I may also need to call an imagesLoaded function (this plugin is also called via the theme).
I have a copy of the current theme here: http://kod-temp.tumblr.com/
The inline script looks like this:
var $wall = $('#posts');
$(window).load(function () {
// Grid
$wall.masonry({
columnWidth: 84,
itemSelector: '.post:visible'
});
// infinite scroll
$('#posts').infinitescroll({
navSelector : ".pagination", // selector for the paged navigation (it will be hidden)
nextSelector : ".pagination a:first", // selector for the NEXT link (to page 2)
itemSelector : "#posts .post" // selector for all items you'll retrieve
},
// trigger Masonry as a callback
function( newElements ) {
var $newElems = $( newElements );
$wall.masonry( 'appended', $newElems );
}
);
The markup follows a simple block like this:
<div id="posts">
<article class="post"></div>
</div>
The error is:
Uncaught TypeError: undefined is not a function
masonry.js:10
(http://static.tumblr.com/qlf79cn/tGeleg9g0/masonry.js)
Well I finally have some working code on this. The js now looks like this:
(function () {
var $tumblelog = $('#posts');
$tumblelog.infinitescroll({
navSelector: ".pagination",
nextSelector: ".pagination a:last-child",
itemSelector: "article",
}, function (newElements) {
var $newElems = $(newElements).css({
opacity: 0
});
$newElems.imagesLoaded(function(){
$newElems.animate({
opacity: 1
});
$tumblelog.masonry('appended', $newElems);
});
});
$tumblelog.imagesLoaded(function(){
$tumblelog.masonry({
columnWidth: 84
});
});
})();
The imagesLoaded script was required (as this question has also been raised by me here).

no such method 'reload' for masonry instance

Good staff is as follows, when the page finishes loading, masonry failure and I do not know why, but I found a method that is masonry.reload.
This method works sometimes, I wonder why.
var $container = $('.container');
$container.masonry({
itemSelector: '.item',
columnWidth: 25
}).imagesLoaded(function(){
$container.masonry('reload');
});
In the newer versions of masonry you use "reloadItems" instead of "reload". I ran across a tip on this thread that pointed me in the right direction.
.imagesLoaded(function(){
$container.masonry('reloadItems');
$container.masonry('layout');
});
Try the following:
<script src="https://unpkg.com/imagesloaded#4/imagesloaded.pkgd.min.js"></script>
var $grids = $('.masonrow').masonry({
itemSelector : '.masonryme'
});
$("#Box").append(e).imagesLoaded(function() {
$grids.masonry('reloadItems');
$grids.masonry('layout');
});
i have same problem with you
yesterday i downloaded masonry from it's github repository, and masonry('reload') methods works, but now i change script source to cdn and it's not working anymore, maybe because different versions, after some googling, i got this http://masonry.desandro.com/methods.html#reloaditems, .masonry('reloadItems') to recollect all items element

JQuery Masonry: Images stacking until page resize

This is most likely a duplicate, but I do not know JQuery and have just been copying/pasting code to get to this point. I do not understand why my images are stacked until I do a page resize. Here is my code:
$ ->
$('things').imagesLoaded ->
$('#things').masonry
itemSelector: '.box'
isFitWidth: true
This is not only jQuery but jQuery + coffeescript.
Here a "translation" of your code in javascript (with jQuery framework) :
$(function() {
$('things').imagesLoaded(function() {
$('#things').masonry({
itemSelector: '.box',
isFitWidth: true
});
});
});
In coffeescript -> mean function (for anonymous function).

Masonry - How to shuffle items

I'm using the masonry script for one of my webpages.
This is the JS (using jQuery, Typescript and the ImagesLoaded Plugin):
$(function(){
// or with jQuery
var $container;
function triggerMasonry() {
// don't proceed if $container has not been selected
if ( !$container ) {
return;
}
// init Masonry
$container.imagesLoaded( function() {
$container.masonry({
itemSelector : '.item',
stamp: '.stamp',
gutter:20
});
});
}
// trigger masonry on document ready
$(function(){
$container = $('#container');
triggerMasonry();
});
// trigger masonry when fonts have loaded
Typekit.load({
active: triggerMasonry,
inactive: triggerMasonry
});
});
This is working very good.
But now I need to shuffle the items before they are rendered and displayed my masonry. Is this somehow possible?
I tried to use Isotope and looked at packery but both doesn't worked out at my website.
Thank you for every help!
shuffle the items before they are rendered and displayed
Do the items have any JavaScript event listeners assigned to them.
If not (meaning if the 'container' only contains markup and no script dependency) then I would suggest:
creating an array that stores the markup of each individual masonry-item as HTML string.
Shuffle the array and
dump the array contents into the 'container'
A crude solution for sure. But, hope this gets the job done.

Categories