Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Isotope + Lazyload: image size

Two things to keep in mind before I expose my problem: 1. I'm not a programmer, therefore I have NO IDEA of what I'm doing 2. Talk to me like I'm stupid, and be very very patient (see 1.)

Alright, there are about a million things wrong in the way the site is set up, but right now I'm just trying to make Isotope work with Lazyload. I've probably read every single stackoverflow on the issue but so far I haven't been able to solve my problem. I'm using Stacey as CMS. Basically, what I'm trying to achieve is similar to xxx.aestheticallyloyal.com (or in fact, www.imageworkshop.com/lazyload-portfolio), but with clickable thumbnails arranged Isotope/Masonry style that open in their respective project pages. I tried getting Infinitescroll to work but I'm not entierely sure pagination is supported in Stacey, therefore I gave up on that. Enter Lazyload.

I got Isotope to work fine. I can get Lazyload to work fine, separatedly. But whenever I try to mix the two, I fail miserably. The problem is that the images are organized by Isotope before they're fully loaded, therefore they don't get aligned according to their actual size (which is variable) but get a fixed width and height (I'm ok with fixed width, that's the point, but height should scale accordingly). If I resize the window after that, though, the grid is adjusted accordingly, as it should.

This is the code I'm working with:

    <script>
$(function () {
    var $window = $(window);
    var $container = $('#container');
    var $imgs = $("img.lazy");

    $imgs.lazyload({
        event: 'scroll',
        effect: 'fadeIn',
        failure_limit: Math.max($imgs.length - 1, 0),
        appear: function () {}
    });

    $(function () {
        $container.imagesLoaded(function () {
            $container.isotope({
                onLayout: function () {
                    $window.trigger("scroll");
                },
                itemSelector: '.photo'
            });
        });
    });

    $window.load(function () {
        $container.isotope('reLayout');
    });
});
    </script>

It's probably wrong in so many ways... I don't know. Plus, as is, I think reLayout is doing absolutely nothing, and from there I really don't know where to go anyway. Can anybody have a look at my site flow.blukaet.com and let me know how to sort this mess? (Nevermind the menu on the left, I haven't even begun looking at that). Thanks.

UPDATE #1

I've been trying to use a different Lazyload script called Fasterize. Things seem to fare only marginally better, but I'm still having problems displaying the images that appear below the fold in a correct manner. Basically anything that loads in the viewport gets sorted fine by Isotope, but the remaining images don't get added based on their actual, final, visible size. I'd need to trigger something in Isotope to make it rearrange the new items after they are loaded. I don't know if it's possible at all. Can anybody help? Here's the site where you can see what's going on: flow.blukaet.com (The code above is no longer actual).

UPDATE #2

So this is the amended code thanks to the answer provided below (also, this is using fasterize/lazyload as opposed to appelsiini's lazyload):

<script>
$(window).load(function () {

var $container = $('#container');
var $imgs = $("img");

$container.imagesLoaded(function () {
    $container.isotope({
        itemSelector: '.photo'
    });
});

$(window).scroll(function () {
    $container.isotope('reLayout');
});
});
</script>

It's not super smooth, but it gets the job done.

Previously I tried something along the lines of:

<script>
$(function () {

var $container = $('#container');
var $imgs = $("img");

$container.imagesLoaded(function () {
    $container.isotope({
        itemSelector: '.photo'
    });
});

$imgs.load(function () {
    $container.isotope('reLayout');
});
});
</script>

Which actually ran much smoother, but somehow was giving the following console error:

cannot call methods on isotope prior to initialization; attempted to call method 'reLayout'

So I don't know.

Another thing to note is that the code works in FF and Opera. Apparently Safari ignores lazyloading altogether. I haven't tested in Chrome and IE. If anybody wants to check out: flow.blukaet.com

like image 986
hooverfocus Avatar asked Feb 06 '13 17:02

hooverfocus


People also ask

What is Lazyload image?

Lazy Loading Images is a set of techniques in web and application development that defer the loading of images on a page to a later point in time - when those images are actually needed, instead of loading them up front.

How do I check Lazyload?

If you want to test the execution of lazy loading, I can recommend that you clear your browser's cache and try reloading. In Chrome's Developer Console (F12), you can tweak the speeds and simulate modem speeds. Hit F12 -> Network tab -> Change the "No throttling" dropdown . Choose a slower speed to experiment.

Does lazy loading improve performance?

Lazy-loading images and video reduces initial page load time, initial page weight, and system resource usage, all of which have positive impacts on performance.

What is data Lazyload?

Lazy loading is the practice of delaying load or initialization of resources or objects until they're actually needed to improve performance and save system resources.


2 Answers

Huzzah! I think we have a final winner. I tinkered some more that half-solution I found — through trial and error, mind you, because I still haven't a clue about what I'm doing — and I think I finally got this right. The console is no longer returning the initialization error and the code seems to behave more or less correctly (I think?!).

<script>
$(document).ready(function () {

    var $container = $('#container');
    var $imgs = $("img");

    $container.imagesLoaded(function () {
        $container.isotope({
            itemSelector: '.photo'
        });
        $imgs.load(function () {
            $container.isotope('reLayout');
        }); 
    });
});
</script>

So 'reLayout' doesn't happen on scroll but when the images load, this way they won't get stuck if the scrolling doesn't go the whole way through.

In Safari Lazyload still does whatever it wants, and as usual I couldn't test on Chrome and IE, but in FF and Opera it seems to be ok. Check flow.blukaet.com for a working example.

like image 102
hooverfocus Avatar answered Oct 12 '22 16:10

hooverfocus


I have the same problem with a responsive grid. Check this image, the grid is okay on the left and broken on the right.

enter image description here

Grid is broken because specific height for image is needed and the responsive process pass the height value into "auto".

So here we have to relayout when images are loaded (giving specific height to process).

For now the solution I find is to relayout on scrool:

$(window).scroll(function() {
        $container.isotope('reLayout');
});

but I'm sure there is a better way to do this.

And try freetile for the grid, found it great and lighter than others. http://yconst.com/web/freetile/

like image 3
jjj Avatar answered Oct 12 '22 18:10

jjj