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).
Related
I have some javascript code that is currently called on a div with the id of "lesson." I'd like to call it on a class instead since I have more than one div to call it on. It's for a rails application.
Here's the js:
$(function() {
return $('#lesson').imagesLoaded(function() {
return $('#lesson').masonry({
itemSelector: '.box',
isFitWidth: true
});
});
});
Thanks for any suggestions!
Question
How should I either modify my script to initialize Masonry, or rearrange the order of my scripts.
Background
I have had similar issues on other websites I created, but currently having it on a Tumblr theme I am building at
http://divedemo.tumblr.com/
I was testing the theme. The result of the error is that the images are stacked too closely together. My previous research said that it was due to the boxes not having a set height. But the solutions that I have found so far do not account for responsive websites.
I went into the console to see what was happening
mmasonry.pkgd.js:62 cannot call methods on masonry prior to initialization; attempted to call 'reload'
Error (screenshot)
Javascript
<script src="https://cdnjs.cloudflare.com/ajax/libs/masonry/3.3.2/masonry.pkgd.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.imagesloaded/4.1.0/imagesloaded.pkgd.min.js"></script>
<script>
$(document).ready(function() {
// Initialize Masonry
$('#content').masonry({
columnWidth: 320,
itemSelector: '.item',
isFitWidth: true,
isAnimated: !Modernizr.csstransitions
}).imagesLoaded(function() {
$(this).masonry('reload');
});
});
</script>
Try this,
$(document).ready(function() {
$('#content').imagesLoaded(function() {
$('#content').masonry({
columnWidth: 320,
itemSelector: '.item',
isFitWidth: true
})
});
});
http://masonry.desandro.com/faq.html#error-cannot-call-methods-on-masonry-prior-to-initialization-attempted-to-call-___
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.
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).
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.