How to add Masonry options to isotope using images loaded - javascript

I'm having an issue with firefox and chrome not rendering the proper amount of columns when using Jquery Isotope and the images loaded option. Safari shows 3 columns all the time. However firefox and chrome sometimes only show 2. All of my images have the same width 28.333%. I have tried changing that to a lower number but it does not effect anything.
Here is what I currently have:
$(document).ready(function() {
var $container = $('#artContent'),
filters = {};
$container.imagesLoaded( function(){
$container.isotope({
itemSelector : '.isotopeItem'
});
});
I tried this which resulted in breaking all the jQuery
$(document).ready(function() {
var $container = $('#artContent'),
filters = {};
$container.imagesLoaded( function(){
$container.isotope({
itemSelector : '.isotopeItem',
masonry: { columnWidth: 33.333% }
});
});
Has anyone else had this issue? Or know of how to fix it.

If your using % in columnWidth, it needs to be like so (note the single quotes):
$(document).ready(function() {
var $container = $('#artContent'),
filters = {};
$container.imagesLoaded( function(){
$container.isotope({
itemSelector : '.isotopeItem',
masonry: { columnWidth: '33.333%' }
});
});

Related

jQuery Isotope Glitch

My Isotope somehow does strange things, when it loads it zooms like crazy and when you filter, the images zoom and scale. It only happens once but it looks super strange. I already tried to place the jQuery at first before all the other code and I also tried to disable the CSS animations for the hover but none of these worked out.
My jQuery is:
// init Isotope
var $grid = $('.grid').isotope({
itemSelector: '.grid-item',
percentPosition: true,
masonry: {
columnWidth: '.grid-sizer'
}
});
// Make filtering work
$('.filter-button-group').on( 'click', 'button', function() {
var filterValue = $(this).attr('data-filter');
$grid.isotope({ filter: filterValue });
});
// layout Isotope after each image loads
$grid.imagesLoaded().progress( function() {
$grid.isotope('layout');
});
// Highlight the active filter
$('.button-group').each( function( i, buttonGroup ) {
var $buttonGroup = $( buttonGroup );
$buttonGroup.on( 'click', 'button', function() {
$buttonGroup.find('.is-checked').removeClass('is-checked');
$(this).addClass('is-checked');
});
});
and a live demo can be found here:
http://dominikwierl.com/develop/v+v/projects
This can be closed.
I've found the answer with some more searching. It's called Isotope Shaking and it can happen when there are too many animations on one object.
See: https://isotope.metafizzy.co/faq.html#items-jump-after-transitioning-position

Re apply javascript after pageload

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

Masonry Events: Call event after imagesLoaded and layoutComplete

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();

How do I make this JavaScript only work for users on browsers with a min-width of 1036px?

In the code below, I want to make the columnWidth 240 only when the site is viewed on a browser with a min-width of 1036px. So, generally only for desktop users. For any browser width below 1036px, I want the columnWidth to be 320. Is this possible?
if(jQuery().isotope) {
$container = jQuery('.home #masonry');
$container.imagesLoaded( function() {
$container.isotope({
itemSelector : '.item',
masonry: {
columnWidth: 240
},
getSortData: {
order: function($elem) {
return parseInt($elem.attr('data-order'));
}
},
sortBy: 'order'
}, function() {
// Isotope Chrome Fix
setTimeout(function () {
jQuery('.home #masonry').isotope('reLayout');
}, 1000);
});
});
// filter items when filter link is clicked
$container = jQuery('#masonry');
jQuery('#filter li').click(function(){
jQuery('#filter li').removeClass('active');
jQuery(this).addClass('active');
var selector = jQuery(this).find('a').attr('data-filter');
$container.isotope({ filter: selector });
return false;
});
}
You're asking two things, how to find out the screen size and how to make it work for your code.
For screen size you can use the screen object (global scope), so screen.width is the width of the screen. Or you can use outerWidth or innerWidth which should return window related sizes (they have their quirks though).
Now, regarding your problem, owwyess is suggesting you mix javascript and json notation which isn't possible, so you should do something like
masonry: {
columnWidth: screen.width >= 1036 ? 240 : 320
}
(If you don't know the syntax, it's called ternary operator, just through it into google)
Uhm I don't think you can check for the screensize?(not sure), but the browser size is done like this, (if it suits your needs as well):
if ($(window).width() < 1024) {
// foo
} else {
// bar
}
you can also try and change $(window).width() to these if it helps:
$(document).width()
$('body').width()
Your code:
if(jQuery().isotope) {
$container = jQuery('.home #masonry');
$container.imagesLoaded( function() {
$container.isotope({
itemSelector : '.item',
masonry: {
$(window).resize(function() {
if (screen.width >= 1036) {
columnWidth: 240
} else {
columnWidth: 320
}
});
},
getSortData: {
order: function($elem) {
return parseInt($elem.attr('data-order'));
}
},
sortBy: 'order'
}, function() {
// Isotope Chrome Fix
setTimeout(function () {
jQuery('.home #masonry').isotope('reLayout');
}, 1000);
});
});
// filter items when filter link is clicked
$container = jQuery('#masonry');
jQuery('#filter li').click(function(){
jQuery('#filter li').removeClass('active');
jQuery(this).addClass('active');
var selector = jQuery(this).find('a').attr('data-filter');
$container.isotope({ filter: selector });
return false;
});
}

Creating and calling a function with JQuery

I have a JQuery script that I run multiple times, with multiple events. I would like to save space and turn it into a function to call whenever I need it. How do I do this in JQuery?
My JQuery Script:
var $container = $('#timeline-posts-wrap');
$container.imagesLoaded( function(){
$container.masonry({
itemSelector : '.post-wrap'
});
});
You can simply extract the function:
var $container = $('#timeline-posts-wrap');
$container.imagesLoaded(afterImagesLoaded);
function afterImagesLoaded(){
$container.masonry({
itemSelector : '.post-wrap'
});
}
It's not "jQuery specific", simply javascript functions.

Categories