I am calling an isotope layout for multiple containers on the same page. The catch it I would like each container ID to the be the same. Using http://isotope.metafizzy.co v.2.1.0
Isotope will work for the first block, but doesn't trigger for the second block. My feeling is once isotope layout hits the first ID of the first container it stops and doesn't look for the same container again. I've tried using .each() - doesn't seem to want to work however.
<div id="isotope-cat-list">
<div class="grid-sizer"></div>
<div class="box">
<h1>TITLE</h1>
</div>
<div class="box">
<h1>TITLE</h1>
</div>
</div>
I then need to call another isotope block layout again:
<div id="isotope-cat-list">
<div class="grid-sizer"></div>
<div class="box">
<h1>TITLE</h1>
</div>
<div class="box">
<h1>TITLE</h1>
</div>
</div>
Full HTML would look like this:
<div id="isotope-cat-list">
<div class="grid-sizer"></div>
<div class="box">
<h1>TITLE</h1>
</div>
<div class="box">
<h1>TITLE</h1>
</div>
</div>
<div id="isotope-cat-list">
<div class="grid-sizer"></div>
<div class="box">
<h1>TITLE</h1>
</div>
<div class="box">
<h1>TITLE</h1>
</div>
</div>
Obviously there are more elements in those .box elements but for simplicity sake I whittled it down. The reason for multiple calls is they will be for different categories and have other elements in between then and I'd rather not have to call a bunch of container ID's.
When I try to trigger the #isotope-cat-list in my .js library it will run for the first block - but won't trigger for the second block. I've tried doing some jQuery .each() but that didn't work.
Here's the JS:
var mainEl = $('#isotope-cat-list');
mainEl.isotope({
animationEngine: 'best-available', //CSS3 if browser supports it, jQuery otherwise
itemSelector: '.box',
animationOptions: {
duration: transitionDuration
},
containerStyle: {
position: 'relative',
overflow: 'visible'
},
masonry: {
columnWidth: columnWidth,
gutter: 1
}
});
I've tried doing .each():
var mainEl = [$('#isotope-cat-list')];
$.each(mainEl, function (j) {
this.isotope({
animationEngine: 'best-available', //CSS3 if browser supports it, jQuery otherwise
itemSelector: '.box',
animationOptions: {
duration: transitionDuration
},
containerStyle: {
position: 'relative',
overflow: 'visible'
},
masonry: {
columnWidth: columnWidth,
gutter: 1
}
});
});
But it still doesn't trigger for the second HTML block. Any help here would be much appreciated! Thanks!
As I stated, ID's are unique. You can use a class multiple times like so ( some of your functions are missing so I had to modify your code for that reason). You are calling isotope using v1.56 options, not v2.
Updated code
jsfiddle
var mainEl = $('.isotope-cat-list');
mainEl.isotope({
itemSelector: '.box',
transitionDuration: '0.3s',
masonry: {
columnWidth: '.grid-sizer',
gutter: 10
}
});
You are using isotope V2 and it only uses css3 for animations, therefore you should not apply animationEngine or animationOption. Also you are using "grid-sizer" and that should be what you apply in your columnWidth. E.g. columnWidth: '.grid-sizer'. Also the containerStyle is position: relative as a default, therefore it is useless to say it in the options. Also the gutter is pointless in your case as you can simply use margins in css for your items.
For your question you'd do:
var mainEl = $('.isotope-cat-list');
mainEl.isotope({
itemSelector: '.box',
masonry: {
columnWidth: '.grid-sizer'
}
});
var mainEl2 = $('.isotope-cat-list-2');
mainEl2.isotope({
itemSelector: '.box',
masonry: {
columnWidth: '.grid-sizer'
}
});
Related
I have my HTML as below
<div class="blog-box">
<div class="blog-item" >...</div>
<div class="blog-item" >...</div>
<div class="blog-item" >...</div>
</div>
and javascript with jquery and isotope js as
var $container=$('.blog-box');
try{
$container.imagesLoaded( function(){
$container.show();
$container.isotope({
filter:'*',
layoutMode:'masonry',
animationOptions:{
duration:750,
easing:'linear'
}
});
});
} catch(err) {
}
When I try to add more blog item elements dynamically using javascript, the width of the blog-box item becomes zero. I have tried rerunning the js above every time I add items to the blog-box but it's not working out. How do I be able to add more blog-items without interfering with the layout?
Is there a way to move scrollbar position on initialisation when using slimscroll? I found it's possible to do this using jQuery on native scrollbar with "scrollTop", but don't see how would I be able to do it using slimscroll. Here is a fiddle. http://jsfiddle.net/c8d3ohue/
Basically I want the first div to be scrolled down on init, like in this picture.
My code:
<div class="slimScroll" style="overflow-y:auto;height:200px;width:250px">
<div class="child-height-1" style="height:50%;overflow:hidden;position:relative">
<div class="child-content" style="height:300px;background-color:lightgreen">asd</div>
</div>
<div class="child-height-2" style="height:50%;overflow:hidden;position:relative">
<div class="child-content" style="height:300px;background-color:lightyellow">asd</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slim-scroll/1.3.2/slimscroll.min.js"></script>
<script>
$(function () {
new slimScroll($('.child-height-1')[0]);
new slimScroll($('.child-height-2')[0]);
});
</script>
If you use jquery.slimscroll.min.js instead of slimscroll.min.js, you can do this like this.
For your same HTML above, in the document ready you can do like this,
var itemContainer1 = $(".child-height-1");
itemContainer1.slimScroll({
height: '200px',
start: 'bottom',
alwaysVisible: true
});
var itemContainer2 = $(".child-height-2");
itemContainer2.slimScroll({
height: '200px',
start: 'top',
alwaysVisible: true
});
See a fiddle,
http://jsfiddle.net/anjanasilva/uypabr6o/
How it looks,
Hope this helps.
I'm developing an wordpress theme and I'm using Isotope or Masonry for the masonry layout. Also I'm using Visual Composer to insert custom elements that i mapped to Visual Composer. I have a container which has no styles and all these items have a div with a class "overlay" that's absolutely positioned and has 100% width and height. It's purpose is to position the white box ( class "content" ) inside of it. Isotope has been giving me a hard time in a previous wordpress theme.. I have no idea why. Here's the image.
Here's the markup for an item:
<div class="masonry-item">
<img/>
<div class="overlay">
<div class="content">
<!-- Just some text here
</div>
</div>
</div>
ANY suggestions are more than welcome, because I can't seem to get it to work in ANY way. Most of the layout methods just end up overlapping all of the items in the most top left corner of the container. Yes, I've tried using ImagesLoaded.js, and it hasn't made a difference.
Masonry JS:
$(".masonry-grid").isotope({
itemSelector: '.masonry-item'
});
.masonry-item CSS:
.masonry-item {
position: relative;
margin-bottom: 30px;
}
It would seem that if they ALL have equal width like 50% it will work flawlessly. Like Deepak Thomas noted in the comments. But as soon as i put a random style for each element, like 30, 40, 50, 60, 70% width it starts to break. In some cases it would put elements next to each other, most of the time leaving a gap between them if they are not in the first row, and the other times it would just stack them one on top of another even though the two items can clearly be put side to side and still have room to spare.
EDIT: Tried removing the image. No difference.
Thanks in advance!
try this :
var $post_masonry = $('.masonry-grid');
$(document).ready(function () {
if ($post_masonry.length) {
$post_masonry.isotope({
itemSelector: '.masonry-item',
layoutMode: 'masonry',
percentPosition: true,
masonry: {
columnWidth: '.masonry-item'
}
});
}
});
Recommended to use imagesloaded.pkgd.min.js to apply isotope when images already loaded.
var $post_masonry = $('.masonry-grid');
$(document).ready(function () {
if ($post_masonry.length) {
var $masonry = $post_masonry.imagesLoaded(function() {
$masonry.isotope({
itemSelector: '.masonry-item',
layoutMode: 'masonry',
percentPosition: true,
masonry: {
columnWidth: '.masonry-item'
}
});
});
}
});
if ($post_masonry.length) --> is optional. Usually applied with dynamic ajax.
From the code you shared, it seems masonry does not provide default sizes to its items.
For every masonry-item, give an additional class
E.g:
.half { width: 50% }
.full { width: 100% }
.pad { padding: 15px }
And use this on the items as you find them apt.
E.g:
<div class="masonry-item half">
<div class="pad">
<img src="xyz" />
<div class="overlay">
<div class="content">I'm the overlay content</div>
</div>
</div>
</div>
That should solve it.
The problem is that the first masonry item is being taken as the columnWidth option for isotope. So just make sure that the first time is the smallest one of your columns.
I'm trying to set up Masonry with Infinite Scroll, it works but it currently loads all items and then when I click on the next page link it loads them all again.
Nav:
<div class="more" id="navigation">
MORE IDEAS
</div>
JS:
$(document).ready( function() {
(function() {
// Main content container
var $container = $('.grid');
// Masonry + ImagesLoaded
$container.imagesLoaded(function(){
$container.masonry({
itemSelector: '.grid-item',
columnWidth: '.grid-sizer',
gutter: '.gutter-sizer',
percentPosition: true
});
});
// Infinite Scroll
$container.infinitescroll({
// selector for the paged navigation (it will be hidden)
navSelector : "#navigation",
// selector for the NEXT link (to page 2)
nextSelector : "#navigation a",
// selector for all items you'll retrieve
itemSelector : ".grid-item",
},
// 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 );
});
});
// Pause Infinite Scroll
$(window).unbind('.infscr');
// Resume Infinite Scroll
$('.more a').click(function(){
$container.infinitescroll('retrieve');
return false;
});
})();
});
Content:
<div class="grid">
<div class="grid-sizer"></div>
<div class="gutter-sizer"></div>
<div class="grid-item">Item 1</div>
<div class="grid-item">Item 2</div>
<div class="grid-item">Item 3</div>
<div class="grid-item">Item 4</div>
<div class="grid-item">Item 5</div>
<div class="grid-item">Item 6</div>
</div>
Currently it loads all items, 1 to 6, then when I click the Load More button it loads items 1 to 6 again. I've looked on the couple of other questions which are similar to this but they are different circumstances. It's probably something simple, any help would be most appreciated.
Figured it out.
You need to take part of the content you want loaded second out and put it in another html page. Then you need to set the navigation link to go to that page. As it was just set to ?page=2 it was just loading the same page again.
The nature of the elements are that each one will be varied in height (due to image and the title) and its height is unknown before applying masonry. Though the width of each element is fixed with .col-lg-3.
On the rendered page where each row has 4 elements, the 5 element is visually on a row on its own and the 6, 7, 8 got pushed down to 3rd row.
html code
<div class="section-details">
<div class="container">
<div class="">
<div class="masonry" id="elements" data-reference="0">
<!-- elements will be pulled over dynamically -->
</div>
</div>
</div>
</div>
and the content of each new element is wrapped in something like the following
<div class="col-lg-3 element">
</div>
css
.element {
padding: 10px 10px 0px;
}
javascript code
// layout the elements
var layout = function(elements, $container, selector) {
$container.imagesLoaded(function () {
$container.masonry({
itemSelector: selector,
columnWidth: selector,
isAnimated: true,
animationOptions: {
duration: 750,
easing: 'linear',
queue: false
}
}).append(elements).masonry('appended', elements, true);
});
};
and it's got called in the following way
layout(elements, $('#elements'), '.element');
So anything could go wrong here?
Debugged into the masonry source code and figured out the cause, it's how the elements got prepared that matters - each of the element that got pushed to the elements array should be an HTMLElement. And once I got that fixed, the issue was gone.