So I have a site that has 2 containers #container and #container2. I use jquery to append content that is of a certain size to one container, and the others to the other. Here is that code:
$(document).ready(function() {
$('.entry').each(function() {
if ($(this).height() > 200) {
$('#container2').append(this);
}
else {
$('#container').append(this);
}
});
});
So my issue is that with the infinite scroll and masonry, when the new content becomes available, the jquery does not run again in order to append the content to the right container. What can I add so that it will be able to append the content to the correct container?
Note: Each container can have tens of thousands of images.
Update:
Here is my masonry code:
$(window).load(function() {
var $wall = $('#container');
$wall.imagesLoaded(function() {
$wall.masonry({
itemSelector: '.entry, .entry_photo',
isAnimated: false
});
});
$wall.infinitescroll({
navSelector: '#page-nav',
nextSelector: '#page-nav a',
itemSelector: '.entry, .entry_photo',
bufferPx: 2000,
debug: false,
errorCallback: function() {
$('#infscr-loading').fadeOut('normal');
}},
function(newElements) {
var $newElems = $(newElements);
$newElems.hide();
$newElems.imagesLoaded(function() {
$wall.masonry('appended', $newElems, {isAnimated: false}, function() {
$newElems.fadeIn('slow');
});
});
});
$('#container').show(500);
});
So what happens is that the next posts when they load, all load into #container regardless of their height. This clearly shows that masonry is working fine, but it's just not calling the jquery again when they load. Is there any way to insure that it calls the jquery I need? How do I do that?
I think you have to initialize masonry plugin after adding your content in containers
like,
$(document).ready(function(){
$('.entry').each(function(){
if($(this).height()>200){
$('#container2').append(this);
}
else{
$('#container').append(this);
}
});
// masonry plugin initialization after adding content to div
});
Related
I have an issue with my masonry code.
It works fine on pageload, but the items that are inside the masonry can be filtered, I am doing this using ajax and I'm replacing the entire div with elements to show the filtered items.
After this happens, the masonry code is not applied again and it falls apart.
How can I make sure the masonry stays applied even when content changes after pageload?
In my footer I have the following code:
<script type="text/javascript">
$(document).ready(function() {
$('.gridlist').isotope({
itemSelector: '.masonryitem',
layoutMode: 'masonry',
});
});
</script>
Then in my custom.js I have the following:
$( document ).ready(function() {
/* Ajax code voor aanbiedingen */
$("#branche").on('change', function() {
var option = $('#branche > option').filter(':selected');
if(option.val() == 'default'){
$.post("includes/ledenall.php", {
filter: option.val()
}, function(result){
$("#content1").html(result);
});
}else{
$.post("includes/leden.php?option=" + option.val(), {
filter: option.val()
}, function(result){
$("#content1").html(result);
});
}
});
});
Which returns my php file, but this time without the masonry being applied.
What can I do about this?
You can try reapplying your isotope library after changing the DOM:
/* Ajax code voor aanbiedingen */
$("#branche").on('change', function() {
var option = $('#branche > option').filter(':selected');
if(option.val() == 'default'){
$.post("includes/ledenall.php", {
filter: option.val()
}, function(result){
$("#content1").html(result);
$('.gridlist').isotope({
itemSelector: '.masonryitem',
layoutMode: 'masonry',
});
});
}else{
$.post("includes/leden.php?option=" + option.val(), {
filter: option.val()
}, function(result){
$("#content1").html(result);
$('.gridlist').isotope({
itemSelector: '.masonryitem',
layoutMode: 'masonry',
});
});
}
});
I don't know if .gridlist is totally replaced in your updated DOM. If not, you may need to somehow "remove" the old isotope instance, but something like this is what you need to do.
Add your code to a function
function func() {
$('.gridlist').isotope({
itemSelector: '.masonryitem',
layoutMode: 'masonry',
});
}
Then you can call the function and apply your isotope at any point you want
I'm using Featherlite as my lightbox and my problem is, I have a lot of images (thumbnails) to load on my page and when it's loading and I click one of the loaded image, the lightbox doesn't work. Therefore, it will go to the jpeg file on to the other page instead of a modal window.
How can I make my lightbox even after all the images are all loaded. By the way, I'm putting this on my WordPress but I don't want to use a plugin. Also I'm using FoundationPress.
Here's the code I use to initiate my lightbox
$(document).ready(function(){
$('a.gallery').featherlight({
targetAttr: 'href'
});
});
I have images loaded script but I'm using it on my masonry. How can I put the lightbox scripts inside the images loaded plugin?
(function() {
// Main content container
var $container = $('.grid');
var $grid = $('.grid').masonry({
// options
columnWidth: '.grid-sizer',
itemSelector: '.grid-item',
percentPosition: true
});
// layout Masonry after each image loads
$grid.imagesLoaded().progress( function() {
$grid.masonry('layout');
});
// Infinite Scroll
$container.infinitescroll({
navSelector : '.pagination', // selector for the paged navigation
nextSelector : '.pagination a.next', // selector for the NEXT link (to page 2)
itemSelector : '.grid-item', // selector for all items you'll retrieve
loading: {
msg: null,
msgText: '<i class="fa fa-circle-o-notch fa-spin"></i>',
finishedMsg: '<i class="fa fa-check"></i>',
img: null
}
},
// 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 });
$container.masonry( 'appended', $newElems, true );
});
});
})();
I'm not exactly sure if I understood correctly what solution you would like, but you could use
https://github.com/desandro/imagesloaded
which is specifically made for use cases like masonry plugin layouts,
to check if all images have finished loading and then execute functions / other scripts.
For example:
$('#your-container').imagesLoaded( {
},
function() {
$('a.gallery').featherlight({
targetAttr: 'href'
});
}
);
Hope this helps a bit?
So here's what I'm trying to do. I have a grid with a lot of images, so I'm using the imagesLoaded library along with masonry.
Here's my CSS:
.grid {
opacity:0;
}
And HTML:
<div class="grid">
<div class="grid-sizer"></div>
<div class="gutter-sizer"></div>
<div class="item">image</div>
<div class="item">image</div>
<div class="item">image</div>
</div>
And here's my JS:
var $container = $('.grid');
// initialize Masonry after all images have loaded
$container.imagesLoaded( function() {
$container.masonry({
columnWidth: '.grid-sizer',
itemSelector: '.item',
gutter: '.gutter-sizer'
});
$container.masonry('on', 'layoutComplete', function(){
console.log('got here');
$container.animate({'opacity':1});
});
});
My goal is to have the grid hidden until all images are load and the layout is complete, and then fade it in. For some reason in my code above, it's never getting into the on layoutComplete block.
If I move that block outside of imagesLoaded, $container.masonry is undefined that point.
Any ideas?
FIDDLE HERE
If you change the grid opacity to 1 you can see everything is getting laid out fine. Just trying to figure out how to get the layoutComplete to call to set the opacity to 1.
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
jQuery(document).ready(function($){
var wdm_wait = function(){
jQuery("body").find("img").each(function(i) {
if(!this.complete)
{
return false;
}
});
// when code reaches here Its assured that all the images are loaded
clearInterval(waiting);
console.log('got here');
var $container = $('.grid');
// initialize Masonry after all images have loaded
$container.masonry({
columnWidth: 100,
itemSelector: '.item',
gutter: 10
});
$container.animate({'opacity':1});
}
waiting = setInterval(wdm_wait,100);
});
This would certainly assure that your js code executes only after all the images have been loaded (rendered)
Hope this helps! :)
have you ever try this one, I think this is your answer
var $container = $('.grid').masonry({
columnWidth: 200,
itemSelector: '.item',
gutter: 10
});
$container.masonry( 'on', 'layoutComplete', function() {
$container.animate({'opacity':1});
});
$container.masonry();
i had implemented infinite scroll with masonry i got stucked in addthis share button not working when i scroll to next loading images the addthis button getting displayed but it is not sharing appropriate images.
if i remove following three lines from masonry function
addthis.toolbox('.addthis_toolbox');<br/>
addthis.counter('.addthis_counter');<br/>
addthis.init();
i am only able see addthis share button on first list of images after i scroll to next list of images the addthis share gets hidden
Javascript Code
<script type="text/javascript">var addthis_config = { "data_track_addressbar": false ;</script>
<script src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-4e142f1d185c5361"></script>
<script src="js/jquery.masonry.min.js"></script>
<script src="js/jquery.infinitescroll.min.js"></script>
<script type="text/javascript">
$(function () {
var $container = $('#container');
$container.imagesLoaded(function () {
$container.masonry({
itemSelector: '.box',
columnWidth: 95
});
});
$container.infinitescroll({
navSelector: '#page-nav', // selector for the paged navigation
nextSelector: '#page-nav a', // selector for the NEXT link (to page 2)
itemSelector: '.box', // selector for all items you'll retrieve
loading: {
finishedMsg: 'No more photos 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 });
$container.masonry('appended', $newElems, true);
addthis.toolbox('.addthis_toolbox');
addthis.counter('.addthis_counter');
addthis.init();
});
$('.listing_img_wrapper').hover(
function () { $(this).find('.hover_img').fadeIn("slow"); },
function () { $(this).find('.hover_img').fadeOut("slow"); }
);
// console.log("called");
// window.addthis.toolbox('.addthis_toolbox');
}
);
});
</script>
i had solved the solution by adding
addthis.counter('.addthis_counter');
and
if (window.addthis) {
window.addthis.ost = 0;
window.addthis.ready();
}
I'm using infinite scroll with masonry everything works fine and lines up correctly. I have a button that when i click it makes that div bigger and shows extra content. the button works and loads fine when the page initially loads but when i scroll down and infinite loads new items and if i click the button to show more it jumps to the top of the screen.
I'm guessing i have to do some callback? Im kinda confused on this. How should I approach it?
this is the code im using:
$(function(){
$(".fancybox").fancybox();
var $container = $('.main_containera');
$container.imagesLoaded(function(){
$container.masonry({
itemSelector: '.item1',
columnWidth: 0
});
});
var nextSelector = '.pagination-next a';
var origNextUrl = $(nextSelector).attr('href');
var offsetRegex = /(offset=)([0-9]+)/;
var offset = origNextUrl.match(offsetRegex)[2];
$container.infinitescroll({
navSelector : '.paginate', // selector for the paged navigation
nextSelector : '.pagination-next a', // selector for the NEXT link (to page 2)
itemSelector : '.item1', // 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 });
$container.masonry( 'appended', $newElems, true );
});
}
);
$('.comment_tr').click(function (e) {
$(this).toggleClass('disabled');
$(this).parent().parent().parent().find('form').slideToggle(250, function () {
$('.main_containera').masonry();
});
e.preventDefault();
});
});
Try changing
$('.comment_tr').click(function (e) {
$(this).toggleClass('disabled');
$(this).parent().parent().parent().find('form').slideToggle(250, function () {
$('.main_containera').masonry();
});
e.preventDefault();
});
to
$('.comment_tr').click(function (e) {
$(this).toggleClass('disabled');
$(this).parent().parent().parent().find('form').slideToggle(250, function () {
$('.main_containera').masonry();
});
e.preventDefault();
e.stopPropagation( );
});
The click event may be propagating up to another link element which has an empty href or one that returns the user to the same page which usually just takes you back to the top. Alternatively, you could replace e.preventDefault(); and e.stopPropagation(); with return false;.
It's hard to say for sure that that's the issue without seeing the HTML though.
Could you post the HTML if that change doesn't work?