Using masonry with imagesloaded
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
});
});
});
Masonry JS initializing before images are loaded
On your site, I can see that you have tried using the imagesLoaded plugin as follows:
//incorrect selectors
$('#container').imagesLoaded( function() {
$('.grid').masonry({
itemSelector: '.portfolio-item'
});
});
however, you do not have an element on the page with the ID 'container'. '#' is an ID selector. You should add a unique ID to the element containing your images, and update the selector to that. E.g.:
<div class="row pt-5 grid" id="gallery">
Furthermore, you do not have an element on the page with the class 'grid', so you should initialise Masonry on the #gallery too. As follows:
//updated selectors
$('#gallery').imagesLoaded(function() {
$('#gallery').masonry({
itemSelector: '.portfolio-item'
});
});
Finally, you can remove the inline instantiation of Masonry from your HTML, as you are initialising it using jQuery now. This bit:
data-masonry='{"percentPosition": true }' <-- not needed
Masonry Events: Call event after imagesLoaded and layoutComplete
You don't need to use the layoutComplete
event on masonry. As you can just add your animation code under the masonry initialization .
When all images are loaded, the imageLoaded function will execute. You can then create the masonry object and animate right away like so:
var $grid = $('.grid').imagesLoaded( function() {
// init Masonry after all images have loaded
$grid.masonry({
columnWidth: 200,
itemSelector: '.item',
gutter: 10
});
console.log('got here');
$('.grid').animate({'opacity':1});
});
Here is a jsfiddle that demonstrate that
How To Get Masonry and ImagesLoaded To Work With Wordpress
The Answer
The embarrassingly simple answer to my own question was I forgot to include <?php wp_footer(); ?>
in the footer.php file.
The next day however, I discovered that ImagesLoaded wasn't being initiated from the footer as one would expect so this answer has since been re-edited to show how I got ImagesLoaded to work properly.
I should note that Masonry was initiating properly from the html in-page options method but the help files don't show a way to initiate ImagesLoaded with this same in-page method.
Backstory (some info of possible use to others)
The next day, after adding in some test posts with thumbnails to the test blog I found that ImagesLoaded wasn't initializing and all blocks were overlapping each other.
I then discovered that attempting to initialize even Masonry with Javascript from footer.php was not working at all either.
After another hour or two trying to figure out why neither script will initialize from either footer.php or header.php I gave up and went back to this suggestion
..why not just add it to a .js file and enqueue it with a loading
dependency on the masonry script? Then you wouldn't have to add the
jQuery code manually to the header/footer via hooks.
Then I found again this question and answer How can I make masonry and Imagesloaded work correct. (wordpress) with an explanation how to do this.
So with thanks to those two folks I will edit this all over again and show you how I got Wordpress working properly with Masonry and it's now-built-in ImagesLoaded.
One Method On How To Add Masonry To Your Wordpress Theme
Goals
- To have Masonry installed on your wordpress theme to make it behave
like Pinterest. - To have the page centered.
- To prevent the stacking on top of / overlapping of each block element.
Some Stuff To Know
- Current Wordpress versions (3.9? to 4.2.2+) come packaged with Masonry.
- Location - wp-includes/js/masonry.min.js
- This Wordpress version of Masonry includes ImagesLoaded built-in.
- Masonry no longer requires Jquery, though the only way I could find to get it to initialize in Wordpress requires a little bit of it.
Installation and Setup
in functions.php
// to use scripts with wordpress they must first be enqueued
function enqueue_scripts() {
wp_enqueue_script('masonry');
wp_enqueue_script('masonryloader', get_stylesheet_directory_uri() . '/js/TaS-masonryInitializer.js', array( 'masonry', 'jquery' ) );
}
add_action('wp_enqueue_scripts','enqueue_scripts');
notes
- because Wordpress may use other scripts and plugins you install may rely on some others 'enqueueing scripts' is how Wordpress manages them all so as not to conflict with each other. I'd go into more detail but I'm not qualified to do so.
- you may see on some other websites examples that show you have to first register Masonry. This is not so as it is included with Wordpress and so is already registered.
- the two script we are enqueing here are first Masonry and second our little script to get masonry to initialize.
- Jquery is also being uhh, enqueued as a dependency for the little Initializer script to work.
in your themes folder (eg /wp-content/themes/yourThemeName/)
create a folder named 'js'
inside that folder create a file named TaS-masonryInitializer.js
- it should look like this /wp-content/themes/yourThemeName/js/TaS-masonryInitializer.js
copy and paste this Javascript into that file..
(function( $ ) {
"use strict";
$(function() {
// set the container that Masonry will be inside of in a var
// adjust to match your own wrapper/container class/id name
var container = document.querySelector('.masonry-container');
//create empty var msnry
var msnry;
// initialize Masonry after all images have loaded
imagesLoaded( container, function() {
msnry = new Masonry( container, {
// adjust to match your own block wrapper/container class/id name
itemSelector: '.block-wrapper',
// option that allows for your website to center in the page
isFitWidth: true
});
});
});
}(jQuery));
notes
- this step is to initialize both Masonry and ImagesLoaded and to adjust the options for Masonry
- as stated earlier, ImagesLoaded is built into the wordpress version of Masonry so no need to enqueue it separately in functions.php as you would have to do on a straight html site.
- to measure height of each image and it's containing block ImagesLoaded is used to prevent Masonry from loading before these heights are determined. This pause/order allows Masonry to properly calculate the height of each block. This is important if you are using
height: auto;
on your images, as many responsive designs do. - assuming your page width is responsive and set to 100%/not fixed, Masonry needs to determine how wide that 100% actually is in able to center your site on the page. The option
"isFitWidth": true
is how this is done. Read more about that here. - you can assign a column width by letting masonry choose the first block's width and applying it as the column width or you can state explicitly the column width in the options as per this page.
- .masonry-container is the class of the container that wraps around all your blocks that you want to behave as masonry behaves
- it can be an ID as well if, you prefer, #masonry-container
- it can be any name, just be sure to adjust for it in the above function
- the above code is taken from How can I make masonry and Imagesloaded work correct. (wordpress) as well as Masonry's own instructions
in index.php (or other template files depending where on your site you want masonry used)
<div class="masonry-container js-masonry">
<div class="block-wrapper">content</div>
<div class="block-wrapper">content</div>
<div class="block-wrapper">content</div>
</div><!-- end masonry-container js-masonry -->
notes
- the class "masonry-container" can be either a class or an id and can be any name you choose, just be sure to adjust for it in the TaS-masonryInitializer.js file
- to my recollection, the class "js-masonry" is required for Masonry to find the opening div and cannot be renamed without meddling with the script itself.
- each div classed "block-wrapper" is a different block element that you are applying the masonry alignment effect to.
- "block-wrapper", like "masonry-container", can be any name you choose and either an id or class.
in footer.php
make certain to have included wp_footer()
before your closing body tag.
<?php wp_footer(); ?>
</body>
</html>
notes
- wp_footer is used by wordpress to enable scripts on your page in one single action. The scripts you enqueued in functions.php are hooked into wp_footer. (Excuse my terminology, I'm sure I misused a couple of words there)
in header.php
make sure you have..
<?php wp_head(); ?>
right before </head>
and as most people are probably using Masonry for a mobile friendly site these days, be sure to include the following code (again, between head and /head) to make things work on mobile browsers..
<meta name="viewport" content="width=device-width, initial-scale=1">
Please let me know of any misunderstandings I have and errors I've overlooked and I'll try to correct them.
Mad props to David DeSandro for writing a hella good script. Check out his website, he's created some other wicked cool stuff.
Related Topics
How to Get All the Applied Styles of an Element by Just Giving Its Id
Should I Use Window.Navigate or Document.Location in JavaScript
Adding Images to an HTML Document with JavaScript
Clean Way to Programmatically Use CSS Transitions from Js
Jquery .Animate() Stop Scrolling When User Scrolls Manually
Jquery Mobile Prevent Scroll-To-Top Before Page Transition
Removing Address Bar from Browser (To View on Android)
How to Format a Float in JavaScript
What Are the Common Defenses Against Xss
Move the Mouse Pointer to a Specific Position
How to Get the Title of HTML Page with JavaScript
Target='_Blank' to Show in New Window, Not New Tab, Possible
Most Elegant Way to Force a Textarea Element to Line-Wrap, *Regardless* of Whitespace
Cannot Set Property 'Display' of Undefined
How to Use Materialize-CSS with Angular
Capture Keys Typed on Android Virtual Keyboard Using JavaScript