Imagesloaded not working with Infinite Ajax Scroll and Masonry - javascript

I have a website the uses bootstrap and the news that I have created with masonry, I used the Infinite Ajax Scroll, that call other news in a different div instead the pre-default. Very often, however, if one scrolls the page quickly, or if you have a slow connection, the elements overlap and do not return to their place, and I think this is due to the fact that it can't load images.
I tried to integrate Imagesloaded but it seems not work properly... and I don't know what to do...
Here is the source as I have proceeded,
HTML:
<div class="row masonry_base altre">
{$news}
</div>
<div class="row masonry altre">
<div class="col-lg-4 col-md-6 col-xs-12 post-grid">
{$news_scroll}
</div>
</div>
JS:
<script>
(function($) {
"use strict";
var $container = $('.masonry_base');
$($container).imagesLoaded( function(){
$($container).masonry({
itemSelector: '.post-grid',
columnWidth: '.post-grid'
});
});
})(jQuery);
</script>
<script type="text/javascript">
var container = document.querySelector('.masonry');
var msnry = new Masonry( container, {
itemSelector: '.post-grid',
gutterWidth: 20
});
msnry.reloadItems()
var $container = $('.masonry');
$($container).imagesLoaded( function(){
$($container).masonry({
itemSelector: '.post-grid',
columnWidth: '.grid',
gutterWidth: 20
});
});
var ias = $.ias({
container: ".masonry",
item: ".post-grid",
pagination: "#pagination",
next: ".next a",
delay: 1200
});
ias.on('render', function(items) {
$(items).css({ opacity: 0 });
});
ias.on('rendered', function(items) {
msnry.appended(items);
});
ias.extension(new IASSpinnerExtension());
ias.extension(new IASNoneLeftExtension({
html: '<div class="btn btn-info btn-block btn-icon-left ias-noneleft" style="text-align:center"><p><em>No news</em></p></div>'
}));
</script>

This code :
$($container).imagesLoaded( function(){
$($container).masonry({
itemSelector: '.post-grid',
columnWidth: '.grid',
gutterWidth: 20
});
});
Only applies imagesLoaded to whatever $container happens to be at its execution. It doesn't apply to dynamically added content. You should call this function again to the dynamic content added. Perhaps in your rendered callback.
Also, you should just call msnry.layout() to adjust content after the images had been loaded (It's not necessary to call $.masonry again)
Hope it helps

Related

Masonry Grid overlapping footer content

I have used masonry layout in grid class and grid-items are the column. I am loading masonry on load event like below
$(window).load(function () {
$('.grid').masonry({
// options
itemSelector: '.grid-item',
horizontalOrder: true,
isAnimated: true,
animationOptions: {
duration: 1000,
easing: 'linear',
queue: false
}
});
});
and my HTML is below, I'm loading items via ajax. some times it is load proper and sometimes overlaps my footer content or div. as shown in the below screenshot.
<div class="grid">
<div class="grid-item">
<img src="images/grid1.jpg" alt="Banner"></a>
</div>
</div>
The Masonry is firing before images are fully loaded. You can use imagesLoaded (which is being loaded on your page) to determine when the images are loaded into a container. Then fire off Masonry. Something like:
var $container = $('#masonry-grid');
$container.imagesLoaded(function(){
runMasonry();
});
I just found out an alternative fix: I created a canvas element with the correct sizes instead of only loading and placing the images. This »canvas« is used as a placeholder for ratio calculations. The images sits with position absolute on top.
Caveat: you need to know the image sizes/ratio. In my wordpress case they are embedded in the json call.
It even works in Internet Explorer 11.
What fixed the issue for me was just appending the elements in a setTimeout function.
$.ajax({
url: ajaxURL,
type: 'post',
data: {
page: page,
action: 'load_more'
},
success: function(response) {
let el = $(response)
that.data('page', newPage);
setTimeout(function() {
$('#masonry').append(el).masonry('appended', el, true);
}, 1000);
},
error: function(response) {
console.log(response);
}
});

Masonry Overlapping (Imbalance2 Bug)

I built my site with Wordpress.org and the theme calls Imbalance2. I noticed that this theme has a bug and I searched topics about the overlapping issue because of Masonry js. I use the imagesLoaded (from user Leger at Using masonry with imagesloaded, thanks!): it works but sometimes my Chrome stills overlapping. I decide to add a pagination instead the "Lazy Load" (to avoid more problems…) but I can't merge imagesLoaded for #boxes and #related…
Could you please help me? Here my site address
Thanks so much for your time!!!
<script src="http://imagesloaded.desandro.com/imagesloaded.pkgd.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
// grid
var $boxes = $('.box');
$boxes.hide();
var $container = $('#boxes');
$container.imagesLoaded( function() {
$boxes.fadeIn();
$container.masonry({
itemSelector: '.box',
columnWidth: 290,
gutterWidth: 40
});
});
$('#related').masonry({
itemSelector: '.box',
columnWidth: 290,
gutterWidth: 40
}).masonry('reload');
});
</script>
This tweak is a fix on chrome and safari browser.
Add this line.
jQuery("img").load(function() {
jQuery(".container_class").masonry(); //this tweak is a fix on chrome and safari browser
});
Here the solution I found. As I said I changed the "Lazy Load" for pagination and I wrote the code below thanks to some users that shared their solutions in this Forum.
<script src="http://imagesloaded.desandro.com/imagesloaded.pkgd.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
// grid
var $boxes = $('.box');
$boxes.hide();
var $container = $('#boxes');
$container.imagesLoaded( function() {
$boxes.fadeIn();
$('#boxes').masonry({
itemSelector: '.box',
columnWidth: 286,
gutterWidth: 40
});
});
var $container = $('#related');
$container.imagesLoaded( function() {
$('#related').masonry({
itemSelector: '.box',
columnWidth: 286,
gutterWidth: 40
});
});
});
</script>

jQuery Isotopewrapper: possible to resize all isotopeItems to same height (per row)?

I have a website that is using jquery's isotope wrapper with html code like this:
<div class="isotopeWrapper clearfix isotope">
<article class="col-sm-4 isotopeItem isotope-item">
<!-- item1 --->
</article>
<article class="col-sm-4 isotopeItem isotope-item">
<!-- item2 --->
</article>
<!-- ... unknown amount of items with unknown height -->
</div>
The template I am using is using this javascript code to initialize the isotope-stuff:
if($('.isotopeWrapper').length){
var $container = $('.isotopeWrapper');
var $resize = $('.isotopeWrapper').attr('id');
// initialize isotope
$container.isotope({
itemSelector: '.isotopeItem',
resizable: false, // disable normal resizing
masonry: {
columnWidth: $container.width() / $resize
}
});
var rightHeight = $('#works').height();
$('#filter a').click(function(){
$('#works').height(rightHeight);
$('#filter a').removeClass('current');
$(this).addClass('current');
var selector = $(this).attr('data-filter');
$container.isotope({
filter: selector,
animationOptions: {
duration: 1000,
easing: 'easeOutQuart',
queue: false
}
});
return false;
});
$(window).smartresize(function(){
$container.isotope({
// update columnWidth to a percentage of container width
masonry: {
columnWidth: $container.width() / $resize
}
});
});
}
This leads to a "masonary" kind of arrangement where the rows have different position absolute top-positions. However, this is unwanted and the content elements have an unknown height (depending on user input).
I am not really familiar with this isotope/masonary type of content and got the following question: how can I give all article.isotopeItem elements the same height (or atleast make each row have an upper solid line ? There is no dynamic adding/deleting of elements in my case, as this is all done on server-side with complete page reloads.
I assume this is the plugin: http://isotope.metafizzy.co
So just use fitRows and the tops of each row will line up - http://isotope.metafizzy.co/layout-modes/fitrows.html
So:
// initialize isotope
$container.isotope({
itemSelector: '.isotopeItem',
resizable: false, // disable normal resizing
layoutMode: 'fitRows'
});

How to setup infinite scrolling with masonry?

I recently ran into some problems trying to setup Infinite scroll on my tumblr with masonry. I found some code, and it worked perfectly on the demo website: http://www.jquery4u.com/demos/infinite-scrolling-demo1/ But on my tumblr only the Masonry part works, but not the infinite scrolling part. Here is my Javascript:
<script>
$(function(){
var $container = $('SECTION');
$container.imagesLoaded(function () {
$container.masonry({
itemSelector: '.item',
columnWidth: '.item',
isFitWidth: true
});
});
$container.infinitescroll({
navSelector : '#page-nav', // selector for the paged navigation
nextSelector : '#nextPage', // selector for the NEXT link (to page 2)
itemSelector : '.item', // selector for all items you'll retrieve
loading: {
finishedMsg: 'No more pages to load.',
img: 'http://i.imgur.com/6RMhx.gif'
}
},
// trigger Masonry as a callback
function( newElements ) {
// hide new items while they are loading
var $newElems = $( newElements ).css({ opacity: 0 });
// ensure that images load before adding to masonry layout
$newElems.imagesLoaded(function(){
// show elems now they're ready
$newElems.animate({ opacity: 1 });
msnry.appended( $newElems );
});
}
);
});
</script>
Here is the html for the next Page link:
{block:Pagination}
<nav id="page-nav">
{block:NextPage}
<a style="color:red;" id="nextPage" href="{NextPage}">Next</a>
{/block:NextPage}
</nav>
{/block:Pagination}
I do already have the Masonry, ImageLoaded, and Infinite Scrolling scripts linked. As I said, The masonry works fine, but the infinite scroll seems to be doing nothing at all. The next link is also working too, since I tested it and it does take me to the next page. But again the Infinite scrolling does nothing whatsoever. If anyone could help it would be very appreciated, or if you have any other suggestions or alternatives, that would also be nice.
Its hard to tell without a demo link, but looking at the example you used for reference:
msnry.appended( $newElems );
There should throw an error saying undefined. This is due to msnry.appended.
The line should be:
$container.masonry( 'appended', $newElems, true );
Source: http://www.jquery4u.com/demos/infinite-scrolling-demo1/

Appending div to dynamic grid layout

I am using this jquery plugin http://packery.metafizzy.co/ to create a dynamic grid layout. The plugin is working perfectly.
The problem is :
I am trying to create an option to add a dynamic grid on click event. If I hand code the html code for grid then the grid shows up perfectly but if I append the grid code to my template layout using jquery then the grid shows up from the very top of the layout and the plugin doesn't seem to adjust the grid position.
You can check my code and see the problem live here: http://jsfiddle.net/A7ubj/2/
I think the plugin is not adjusting the grid because my jquery append code is making the grid seat on the top.
Could you please tell me how to append the grid so that the plugin can adjust the grid perfectly?
This is how I am appending:
$(function(){
$('#myID').click(function(){
$( "#container" ).append( $( '<div class="item diff">Grid</div>' ) );
});
});
And this is my entire code:
JS:
<script src="http://code.jquery.com/jquery-1.10.2.min.js" type="text/javascript"></script>
<script src="packery.pkgd.min.js" type="text/javascript"></script>
<script>
$( document ).ready(function() {
var $container = $('#container');
// initialize
$container.packery({
itemSelector: '.item',
gutter: 10
});
});
</script>
<script>
$(function(){
$('#myID').click(function(){
$( "#container" ).append( $( '<div class="item diff">Grid</div>' ) );
});
});
</script>
CSS:
#container{
background-color:#F00;
width: 1130px;
margin:0px auto;
}
.item { width: 275px; background-color:#0C0;}
.item.w2 { width: 560px; background-color:#036; }
.diff{
min-height:300px;
}
.diff2{
min-height:250px;
}
HTML:
<button id="myID">Click</button>
<div id="container">
<div class="item diff">Grid</div>
<div class="item w2 diff2">Grid</div>
</div>
You can call packery.reload() or just use the packery initialization function again after you have append the images and to calculate every new image position. I use the masonry plugin and masonry.reload().
Update: To make masonry work with infinitescroll use a callback function: How to enable infinite scrolling with masonry?
Here is the code from my website. I use jquery templates and prepend. You can see that it call masonry('reload') after the prepend. It also init masonry from the new container. It also correct the width and the height of each image because I think there is an error in masonry. I think it's not really what you need because I don't cache the brick but I rebuild the entire container when I need it to show a new category. In your example you physically add a brick but I don't understand why it didn't work. The result is the same but not so clean.
$j.getJSON($j("#tag") function(response)
{
// Start masonry animated
if (response && response.length)
{
var container = $j('#container');
container.masonry({
itemSelector: '.brick',
columnWidth: brick_width,
isAnimated: !Modernizr.csstransitions
});
boxCount = response.length;
counter = 0;
$j.each(response, function(idx, ele)
{
container.prepend($j("#brickTemplate").tmpl(ele)).masonry('reload');
}
container.imagesLoaded(function()
{
$j("#brick").each(function()
{
var content = $j(this).find(">div");
var height = $j(this).find("img").attr("height");
if ( height == undefined )
{
content.css({
height: "300px"
});
} else {
content.css({
height: height
});
}
// bricks fade in
$j(this).delay(Math.floor(Math.random() * 1600)).fadeIn('slow');
// Bind Mousemove
$j(this).mousemove(function()
{
.....
}
}
}
}

Categories

Resources