I'm implementing Masonry with Infinite Scroll on a Tumblr theme -- something I've successfully done before, but I just can't get this one to stop "breaking" and scattering the images around. Getting desperate!
Live demo at neuraldamage-theme4.tumblr.com (password is guest).
I've tried removing everything from the body tag except for the #posts div and its contents (and of course the script), but the problem persisted -- so it seems like this shouldn't be an issue with the surrounding divs.
Here's my script:
$(document).ready(function() {
$('#post-video iframe').attr('width', '300'); // resize embedded videos
});
var $container = $('#posts');
$container.imagesLoaded( function(){
$container.masonry({
itemSelector : '.post',
columnWidth : 300
});
});
$container.infinitescroll({
navSelector : '#pagination', // selector for the paged navigation
nextSelector : '#pagination li a.pagination_nextlink', // selector for the NEXT link (to page 2)
itemSelector : '.post', // selector for all items you'll retrieve
loading: {
finishedMsg: '',
img: 'http://static.tumblr.com/6u5yyqj/iUtmgivzo/loading.gif', // http://static.tumblr.com/6u5yyqj/iUtmgivzo/loading.gif, http://static.tumblr.com/6u5yyqj/yWkmgj1jq/loadingdark.gif
}
},
// trigger Masonry as a callback
function( newElements ) {
var $newElems = $( newElements );
$container.masonry( 'appended', $newElems );
}
);
And here's what I have embedded, just made sure it was all up to date:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://static.tumblr.com/6u5yyqj/MPKmktfkv/jquery.masonry.min.js"></script>
<script src="http://static.tumblr.com/6u5yyqj/nsQmkth3k/jquery.infinitescroll.min.js"></script>
And if you'd like to see the full code: gist.github.com/neuraldamage/5307289
If anyone could take a crack at this, I'd be greatly appreciative!
It's running into a bunch of problems because you actually have multiple <div id="posts"> on the page. Likely a problem with your Tumblr code spitting out more than it should.
The issue is this:
<div id="posts" style="position: relative; height: 483px;" class="masonry">
change that height to accommodate your content (as it's not large enough), or simply don't declare it at all.
When I inspected the element, I simply removed the height value and everything moved into place.
Related
I know alot has been written about this, but I feel I am close to solving the issue.
I am trying to use a theme which has masonry installed, but now the client is asking for infinite scroll and this is causing me issues.
Initially I was seeing errors in the console for both the masonry and infinite scroll plugins, now at least I am only seeing a masonry error. And it does look as though the infinite scroll function is calling subsequent pages of posts, it's just that Masonry is struggling to append them to the page in the right layout.
I think it is something to do with my callback function, but worried I may also need to call an imagesLoaded function (this plugin is also called via the theme).
I have a copy of the current theme here: http://kod-temp.tumblr.com/
The inline script looks like this:
var $wall = $('#posts');
$(window).load(function () {
// Grid
$wall.masonry({
columnWidth: 84,
itemSelector: '.post:visible'
});
// infinite scroll
$('#posts').infinitescroll({
navSelector : ".pagination", // selector for the paged navigation (it will be hidden)
nextSelector : ".pagination a:first", // selector for the NEXT link (to page 2)
itemSelector : "#posts .post" // selector for all items you'll retrieve
},
// trigger Masonry as a callback
function( newElements ) {
var $newElems = $( newElements );
$wall.masonry( 'appended', $newElems );
}
);
The markup follows a simple block like this:
<div id="posts">
<article class="post"></div>
</div>
The error is:
Uncaught TypeError: undefined is not a function
masonry.js:10
(http://static.tumblr.com/qlf79cn/tGeleg9g0/masonry.js)
Well I finally have some working code on this. The js now looks like this:
(function () {
var $tumblelog = $('#posts');
$tumblelog.infinitescroll({
navSelector: ".pagination",
nextSelector: ".pagination a:last-child",
itemSelector: "article",
}, function (newElements) {
var $newElems = $(newElements).css({
opacity: 0
});
$newElems.imagesLoaded(function(){
$newElems.animate({
opacity: 1
});
$tumblelog.masonry('appended', $newElems);
});
});
$tumblelog.imagesLoaded(function(){
$tumblelog.masonry({
columnWidth: 84
});
});
})();
The imagesLoaded script was required (as this question has also been raised by me here).
I'm using the masonry script for one of my webpages.
This is the JS (using jQuery, Typescript and the ImagesLoaded Plugin):
$(function(){
// or with jQuery
var $container;
function triggerMasonry() {
// don't proceed if $container has not been selected
if ( !$container ) {
return;
}
// init Masonry
$container.imagesLoaded( function() {
$container.masonry({
itemSelector : '.item',
stamp: '.stamp',
gutter:20
});
});
}
// trigger masonry on document ready
$(function(){
$container = $('#container');
triggerMasonry();
});
// trigger masonry when fonts have loaded
Typekit.load({
active: triggerMasonry,
inactive: triggerMasonry
});
});
This is working very good.
But now I need to shuffle the items before they are rendered and displayed my masonry. Is this somehow possible?
I tried to use Isotope and looked at packery but both doesn't worked out at my website.
Thank you for every help!
shuffle the items before they are rendered and displayed
Do the items have any JavaScript event listeners assigned to them.
If not (meaning if the 'container' only contains markup and no script dependency) then I would suggest:
creating an array that stores the markup of each individual masonry-item as HTML string.
Shuffle the array and
dump the array contents into the 'container'
A crude solution for sure. But, hope this gets the job done.
Hey so here's the website I'm working http://trevormsmith.com/linx/art.html
Trying to build a filter system (in the footer), and when you click on the specific categories (minimalist, typographic, abstract) masonry resets the images into a single column, instead of the grid. If you resize the browser, it'll readjust to normal.
This is what I have calling masonry to the containers with the images
Also, when I set the #minimalist, #typographic, #abstract to display:show instead of display:none (which it needs to be), the layout is fine and it works smoothly.
Any suggestions?
Edit: So here's the code that is working only for #minimalist, except the masonry is not being triggered and the images stay floated instead of tiling:
EditEdit: here's the current code, #containers fade in as a single column instead of grid layout: http://jsfiddle.net/T6SDb/1/
Calling the masonry:
$( function() {
$('#container-all, #minimalist, #typographic, #abstract').masonry({
itemSelector: '.item, .item-m, .item-t, .item-a',
columnWidth: 7 }); });
And then the fadein/fadeout for the filter:
$('#btn-all').click(function(e){
$('#minimalist, #typographic').fadeOut('slow', function(){
$('#container-all').delay(1000).fadeIn('slow', function(){
});
});});
$('#btn-m').click(function(e){
$('#container-all, #typographic').fadeOut('slow', function(){
$('#minimalist').delay(1000).fadeIn('slow', function(){
$('#container-all').masonry('layout');
});
}); });
$('#btn-t').click(function(e){
$('#container-all, #minimalist').fadeOut('slow', function(){
$('#typographic').delay(2000).fadeIn('slow', function(){
$('#container-all').masonry('layout');
});
}); });
$('#btn-a').click(function(e){
$('#container-all, #typographic, #minimalist').fadeOut('slow', function(){
$('#abstract').delay(2000).fadeIn('slow', function(){
$('#container-all').masonry('layout');
});
}); });
Try calling masonary('layout') after fading in the selected images, i.e. for the container-all (from your filter.js file) try this:
$('#btn-all').click(function(e){
$('#minimalist, #typographic').fadeOut('slow', function(){
$('#container-all').delay(1000).fadeIn('slow', function(){
$('#container-all').masonry('layout');
});
});
});
I'm only testing this from the JavaScript console so you might need to tweak the timing / positioning. I'm doing it when the fade is complete, you might want to try doing just after the start of the fade.
Edit
It may be because of the way your containers are put together and how you start masonary, perhaps you can do this in your main source:
var mason;
$( function() {
mason = $('#container-all, #minimalist, #typographic, #abstract').masonry({
itemSelector: '.item, .item-m, .item-t, .item-a',
columnWidth: 7});
});
});
Then later you can use mason.masonary('layout') in each of your click functions rather than referring to a single container, i.e. for the first one try:
$('#btn-all').click(function(e){
$('#minimalist, #typographic').fadeOut('slow', function(){
$('#container-all').delay(1000).fadeIn('slow', function(){
mason.masonary('layout');
});
});
});
Depending when you want things to appear and rearrange you might want to fadeTo a certain value then do the layout and then complete the fade (or you could do that on a delay too).
Maybe look at the Masonary functions hide and reveal to remove given elements.
It may also make things easier to work with the items themselves rather than the containers (since everything gets rearranged) and just have one outside container for everything.
I'd also suggest trying a simpler example (maybe just colored divs or something), working with that, and posting it if you still have issues. There may be some interaction between the libraries you are using.
Edit 2
Added Fiddle, that uses the separate mason variable above. It works but, again, you might need to do something about the timing of the fade in / fade out -- of course you can't arrange the things until they're visible which is an issue. I'm not sure of the best way to fix that.
I have a problem and it's giving me headaches since I started looking for it yesterday.
I have a couple of jQuery scripts and my page includes .load jQuery ajax (at the bottom of the page).
I use a hover effect for the images and a fixed position of the header that is located in js/tools.js
The problem is that, randomly my browsers won't load the tools.js into the ajax. So sometimes you don't see the image hover effect in the loaded ajax content. When refreshing the page it woks fine.
My first bet was that the scripts I use collide or that there's a problem with the order in which the content or the .js loads.
js:
$(document).ready(function() {
$('.cta-btn, .portf1, .portf2, .portf3, .portf4, .portf5, .btn-facebook, .btn-twitter, .btn-linkedin, .btn-studiofacebook, .btn-studiotwitter,.btn-studiolinkedin,.newsitem1, .newsitem2, .newsitem3').append('<span class="hover"></span>').each(function () {
var $span = $('> span.hover', this).css('opacity', 0);
$(this).hover(function () {
$span.stop().fadeTo(200, 1);
}, function () {
$span.stop().fadeTo(400, 0);
});
});
});
$(function(){
var stickyHeaderTop = $('#stickyheader').offset().top;
$(window).scroll(function(){
if( $(window).scrollTop() > stickyHeaderTop ) {
$('#stickyheader').css({position: 'fixed', top: '0px'});
$('#stickyalias').css('display', 'block');
} else {
$('#stickyheader').css({position: 'static', top: '0px'});
$('#stickyalias').css('display', 'none');
}
});
});
html:
<!-- portfolio -->
<div id="portfoliowrapper">
<div id="portfolioitems"></div>
<script>$("#portfolioitems").load("werk.html #portfolio");</script>
<div class="clear"></div>
<h2 class="btn">Werk</h2>
</div>
Any ideas? Thanks in advance!
You need to show some code, you can't expect us to dig through your site.
It's very likely that you're using
$(function(){
// code that depends on images being loaded here
});
However, that will not wait for the images to load, it only waits until the DOM is ready to be modified. The event that waits for images is the load event of the window.
$(window).load(function(){
// here all images in the HTML are guaranteed to be loaded
});
The second time your page is run, the images are in the cache and they are already loaded when the DOM is ready, that is from your $(document).ready() handler
The issue is here:
$("#portfolio").offset() is null
Line 33
According to Firebug. Looks like you are trying to call a function before the page has been completely rendered, this is causing an error as it cannot calculate the offset and it breaks the rest of the function.
I've been trying to get Masonry to stack my posts on this blog for the past two days:
topheavypilesofbooks.com. The posts should stack neatly with no whitespace. Instead posts float as usual, with lots of vertical whitespace.
This is a Wordpress blog, and I've added the javascript with the enqueue function. According to Firebug, the javascripts are loading correctly.
The last script I load is the function to trigger Masonry, it is this:
jQuery((window).load(){
jQuery('#content').masonry({
// options
itemSelector : '.post',
columnWidth : 240
});
});
It looks like you have an error with your brackets.
Try this... I ran it on your site and it functions. Might require some tweaking, that I currently dont have time to do :)
jQuery(function () {
jQuery('#content').masonry({
itemSelector: '.post',
columnWidth: 240
});
})