Implementing Jquery Isotope on images added dynamically - javascript

I am trying to write a module for Drupal which would have the functionality to handle images using isotope. What I am trying to do is taking an input link from user, then loading that image in #content-images div. I am facing problems in implementing isotope plugin on those images.
Here is the jsfiddle: http://jsfiddle.net/xu4k7/1/ for my code.
When I change the above code to the following code, images do not show up.
(function ($) {
$(document).ready(function () {
$("#input-box-to-obtain-image-links").change(function() {
var value = $(this).val();
$('#content-images').append('<div class="image"><img class="isotope-images" src="'+value+'"></div>');
});
$('#content-images').isotope({
itemSelector: '.image'
});
});
})(jQuery);
I just want to know how can I implement isotope on those images so that when I resize my browser, images align themselves.
Thanks

Your isotope wrapper has a 0px height, that's why images are not visible. Maybe isotope init is done too early, so it can't compute its wrapper height ? See
Isotope jquery plugin doesn't show properly on chrome
or
Isotope intermittently returns 0px height on div
(first link really seems to be your solution : put isotope init in a callback fired after the actual DOM update)

Related

Image resize within the div on manual browser width change

thanks to some external resources and help of some great people the following codepen.io image(post) grid with zoom in effect on hoover was created. There is only one small feature that actually I can't figure out is if for example the user will decide to resize his browser width the images will behaive very very badly, this JS code in some kind destroy responsive behavior of images, but if you refresh the page everything will look nice again.
JS CODE
$(function(){
$('.item-inner').each(function(){
var img = $(this).find('img');
$(this).css({height:img.height(), width:img.width()});
})
})
This code should be put inside a resize() event and also on ready()
function updateImageSize(){
$('.item-inner').each(function(){
var img = $(this).find('img');
$(this).css({height:img.height(), width:img.width()});
})
}
$(window).on('resize',updateImageSize);

Skrollr.js Plugin Not Parallaxing Inside Bootstrap Carousel - Fiddle Provided

I am having a problem with the SKrollr.js plugin for Parallax and smooth scrolling. Everything works fine except Bootstrap carousel's, and im sure any carousel for that matter. It's clearly a display:none problem when the plugin is setting itself up on load and can't see any of the .item classes. But I can't figure out how on earth to get Skrollr to see all of the slides/.item classes when it's rendering.
I even tried this kinda stuff. My Skrollr markup isn't the problem that code always works for me.
Skrollr Markup
data-10p-top-bottom="background-position-y: 100%;" data-bottom-top="background-position-y: 0%;"
CSS
.displaying {
display: block !important;
}
JS
var sk = skrollr.init({
forceHeight: false,
beforerender: function(data) {
$(".item").addClass('displaying');
},
render: function(data) {
$(".item").removeClass('displaying');
}
});
EDIT
I made a JSFiddle for it here or you can see it fullscreen for debugging here
Sorry I was being vague and general because I know my HTML is solid. Check the fiddle. The slider functions just fine it's Skrollr not being able to see the hidden slides at runtime that is the problem. I just need a better solution to solve this.
I'm guessing that you need to do a refresh since I notice it works if I resize the browser.
Try this code:
setTimeout(function () {
skrollr.get().refresh();
}, 0);
You can change the timeout to 1000 if necessary to ensure everything loads.

Masonry & LazyLoad doesn't want to work together

I am setting up a site for a photographer. It should be built using the Bootstrap 3 framework, and he wants to have a masonry with over 400 images on one page. For this to work LazyLoad is a must. I have now spent several days trying to get LazyLoad to work with Desandros Masonry but with no success..
I've tried all of the examples that one finds googling, but most posts/sites/forums just redirects you, or have copied this stackoverflow answer:
Combining LazyLoad and Jquery Masonry
I've tried both methods but unfortunately I get nothing but grey hair..... :(
Here is a simplified live version of the page im working on:
http://nr.x10.mx
In this example I have added a fade-in on page-load, but left the LazyLoad out since I can get it to work.
And here you have a FIDDLE of the following
var container = document.querySelector('#ms-container');
imagesLoaded( container, function()
{
var msnry = new Masonry(container,
{ itemSelector: '.ms-item',
columnWidth: '.ms-item',});
});
You can also download the whole pack here, including the jquery.lazyload.js HERE
Any help would be highly appreciated
UPDATE
Here you can have 4 different examples of the different problems that occur.
I also found to my joy that the Bootstrap .img-responsive class is interfering with LazyLoad.
1 - Masonry without LazyLoad
2 - Masonry and Lazyload - Masonry breaks down and LazyLoad has no effect
3 - LazyLoad without Masonry - LazyLoad has no effect
4 - LazyLoad without Masonry and Bootsrap "img-responsive" removed
5 - Masonry & LazyLoad using first method of SO answer mentioned above
6 - Masonry & LazyLoad using second method of SO answer mentioned above Both of the last ones gives the following error: [Error] TypeError: 'undefined' is not a function (evaluating '$container.imagesLoaded')
global code (5.html, line 110)
Updated zip HERE
Again, any asisstance would be highly appreciated, thank you
I made your 5.html work by using the javascript files of the fiddle present on the SO link you posted, answered by Nathan Do. So you probably just had bad versions of the scripts.
The scripts linked on that page are: http://cdn.jsdelivr.net/masonry/2.1.08/jquery.masonry.min.js and http://cdn.jsdelivr.net/jquery.lazyload/1.8.4/jquery.lazyload.js
Here's your original fiddle updated with that page's method: http://jsfiddle.net/L9RLe/
In your case, though you are creating masonry and adding lazyload effect, the images get overlapped.
You need to follow steps as :
Create Dynamic HTML structure for images along with their respective aspect ratio height and width. Note: images should have the required attributes for applying lazy load effect i.e. class="lazy" data-original="actual image url" and src="dummy imageurl".
Apply lazy load effect.
Then create Masonry.
Lets have an example :
Suppose I am having a javascript array with some image related data as,
var gallery_itemList= [
{url: "images/example1.jpg", width:"1170", height:"460"},
{url: "images/example2.jpg", width:"800", height:"320"},
{url: "images/example3.jpg", width:"1200", height:"870"}];
And below prototype for creating dynamic html, applying lazyload effect and creating Masonry effect as :
var masonryGallery = {
gallery :'', // gallery to create
genarateGallery : function() {
// generate each item html
var inHTML="", i;
for(i=0;i<gallery_itemList.length;i++){
var iWidth, iHeight, fHeight=0;
iWidth=parseInt(gallery_itemList[i].width);
iHeight=parseInt(gallery_itemList[i].height);
fHeight = Math.round((iHeight*300)/iWidth);
inHTML+='<div class="item" style="height:'+fHeight+'px">';
inHTML+='<img class="lazy" src="images/loading.gif" data-original="'+gallery_itemList[i].url+'"/>';
inHTML+='</div>';
}
//add generated html to gallery
$(masonryGallery.gallery).append(inHTML);
},
applyLazyload : function(){
$("img.lazy").lazyload();
},
createMasonry : function(){
// create Masonry
$(masonryGallery.gallery).masonry({
columnWidth: 350,
itemSelector: '.item',
isFitWidth: true,
isAnimated: !Modernizr.csstransitions
}).imagesLoaded(function() {
$(this).masonry('reload');
});
},
init : function(givenGallery) {
masonryGallery.gallery = givenGallery; // set gallery
masonryGallery.genarateGallery(); // generate gallery html
masonryGallery.applyLazyload(); // apply lazyload effect
masonryGallery.createMasonry(); // apply masonry effect
}
};
/* Gallery Intialisation */
(function(){masonryGallery.init('div#content');})();
If you have the problem images get overlapped, I found the solution at the site below, although it is in Japanese.
http://www.webdesignleaves.com/wp/jquery/1340/
The point is use following;
$('img.lazy').load(function(){ ... })
HTML
<div id="works_list">
<div class="work_item">
<img class="lazy" src="images/dummy.gif" data-original="images/works/thumb/001.jpg" alt="">
<p>title 1</p>
</div><!-- end of .work_item-->
<div class="work_item">
<img class="lazy" src="images/dummy.gif" data-original="images/works/thumb/002.jpg" alt="">
<p>title 2</p>
</div><!-- end of .work_item-->
....
</div><!-- end of #works_list -->
jQuery
$("img.lazy").lazyload({
effect: 'fadeIn',
effectspeed: 1000,
threshold: 200
});
$('img.lazy').load(function() {
masonry_update();
});
function masonry_update() {
var $works_list = $('#works_list');
$works_list.imagesLoaded(function(){
$works_list.masonry({
itemSelector: '.work_item', 
isFitWidth: true, 
columnWidth: 160
});
});
}
Just want to contribute my solution to this thorny problem.
Basically you need to call masonry's layout() function every time an image is lazyloaded, because that's when you know what it's dimensions are going to be. So you setup lazyload's load() function to call masonry.layout(). This can cause a new problem, because on your initial page load, all of your images will have a zero or near-zero height (depending on your css), and thus stack up in the top of the viewport. When you initialize lazyload, it will see all these images in the viewport, and try to load them all at once. This causes you to download tons of images, and even worse, calls masonry dozens or hundreds of times. Not very speedy.
My solution is to force a minimum height on unloaded images until they are lazyloaded. This restricts the number of images that will be found in the viewport initially, limiting the number of lazyload and masonry calls to a reasonable amount.
Once an image is loaded, you remove the .unloaded class in order to deconstrict the height and allow it to conform to the height of the image.
HTML
<div id="masonry-container">
<div class="masonry-item unloaded"><img class="lazy" data-original="image.jpg"></div>
<!-- Repeat as needed -->
</div>
CSS
.masonry-item {
width: 33.3%; // I'm doing a 3-column masonry layout
}
.unloaded {
min-height: 200px;
// set a minimum default height for image containers
// this prevents too many images from appearing in the viewport
// thus causing lazy load to load too many images at once
// we will use the lazyload .load() callback to remove this fixed
}
JS
$( document ).ready(function() {
// Initialize Masonry
var container = document.querySelector('#masonry-container');
var msnry = new Masonry( container, { transitionDuration: 0 } );
msnry.layout(); // run masonry for first time
function doMasonry() { msnry.layout(); } // gives us a function handler to call later with window.setTimeout()
// Initialize lazyload
$("img.lazy").lazyload({
effect : "fadeIn", // optional
load : function() {
$(this).parent().removeClass("unloaded"); // select the div containing the image and remove the "unloaded" class, thus deconstricting the min-height
window.setTimeout(doMasonry,100); // trigger masonry again with a 100 ms delay, if we do it too soon, the image may not have loaded, and masonry will layout with the wrong image dimensions (this might be a bit of a hacky way to do it)
}
});
});

Why doesn't Lazyload show pictures?

I tried all the solution given on stackoverflow.
Jquery LazyLoad.js Issue with Loading after Window Resize
Lazy Load won't load visible images
jQuery LazyLoad do not load images until scroll
LazyLoad images not appearing until after a scroll
Add a width height in css
Add a width height in HTML
$(window).resize();
.trigger("lazyload");
skip_invisible:true
failure_limit : 1000
I also tried an alternative http://luis-almeida.github.io/unveil/
But the problem still the same. Unless I resize the window, (or $(window).resize(); in the console) picture don't show.
However, if I put a threshold of 300, the pictures in the 300 first pixels will appear, not the others...
The most strange is that the problem is the same for the 2 plugins.
Any suggestion?
This is an issue because your content, which contains the images, is loaded after the lazyload
Try calling lazyload in setInterval function or at the end of window.load.
var interval = setInterval(function(){
$("img.lazy").lazyload();
clearInterval(interval);
},1000);

Masonry and Infinite Scroll breaking layout when scrolling at certain speed

I have a fluid width theme and I am using jQuery Masonry and Infinite Scroll. The Problem is that if you scroll at a certain speed (not too fast and not too slow) the page it can cause a break in the grid. I have only seen this with two columns and in Firefox:
Anyone know why this is happening? I know it could be a number of things but if anyone has had experience with this and knows what is going on it would help greatly.
UPDATE:
The break happens right after the last post on the page. The ones that come after are being generated by infinite scroll's callback.
Well, I can not see the link to your page to look at (and the image is not available) but from my past experiences with masonry, whenever there is a major change in the page size (re-sizing, scrolling, re-sized divs) you need to trigger it again:
jQuery(document).ready(function() {
jQuery("#somediv").click(function() {
jQuery('#leftcol').toggle(700); //div resizing start here
jQuery('#somediv2').toggleClass("minside");
jQuery('#somediv').toggleClass("full"); // evoke again after change..
jQuery('#container').masonry({
itemSelector : '.item',
columnWidth : 240
});
});
});
Add this as callback for infinite scrolls and your problem will be gone... at least works for me:
// 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);
});
});
Check the $container just in case you've changed it.

Categories