1

I am working on simple gallery with pictures. I wanted to use bLazy plugin to load images, all works fine except the fact that I wanted to load image list via external JSON file and because of that images elements are not created fast enough, so when bLazy script is loaded, it can't see images yes.

If I use setTimeout it works, but it is a nasty way of doing things... Any ideas how to refactor my code?

Please note that it work in progress and I will use routers later...

app.js:

var allPics = Vue.extend({
el: function () {
    return "#gallery";
},
data: function () {
    return {
        pics: {},
        folders: {
            full: "img/gallery/full_size/",
            mid: "img/gallery/mid/",
            small: "img/gallery/small/",
            zoom: "img/gallery/zoom/"
        }
    };
},
created: function () {
    this.fetchData();
},
ready: function () {
    setTimeout(function () {
        var bLazy = new Blazy({

        });
    }, 1000);

},
methods: {
    fetchData: function () {
        var self = this;
        $.getJSON("js/gallery.json", function (json) {
            self.pics = json;
        })
    }
}
});
var router = new VueRouter({
});

 router.start(allPics, 'body', function () {

  });

HTML:

    <div id="gallery" class="gallery">
        <div v-for="pic in pics.gallery" class="gallery_item">
            <div class="img_div">
                <img class="b-lazy" 
                     src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
                     data-src= "{{* folders.mid + pic.name}}" 
                     alt="{{pic.alt}}" >
            </div>
        </div>
TheFullResolution
  • 1,251
  • 1
  • 15
  • 26

4 Answers4

1

You might want to check https://github.com/aFarkas/lazysizes, it detects DOM changes automatically, so you don't have to do any setTimeout hacks.

Only add the script and add the class lazyload as also use data-src instead of src and you are done.

alexander farkas
  • 13,754
  • 4
  • 40
  • 41
  • It does work more stable, thanks! I still had to play around css to make it looks nice and ajax request to avoid empty get requests, nevertheless your script works really nice. Thanks and big respect! – TheFullResolution Jan 24 '16 at 17:53
1

I am also working with a small gallery of images and using image-background on divs instead of < img > tags since they offer more control over nested elements positioning and allows to use background-size: cover property.

What i do to preload images is something like this:

var imageUrl = ....
var img = new Image();
img.onload = function() {
    this.$els.divId.style.backgroundImage = "url(" + imageUrl + ")";
    $(this.$els.divId).fadeIn(1000); // fade in div using jquery
};
img.src = imageUrl;

That way when the image is loaded and cached in the browser i can fade in the image div for a smooth effect.

Note that the divId element is hidden (using display: false) from the start and no background-image property is assigned.

Also onload event should be set before assigning imageUrl to img.src so you don't miss the onload event if the image is already cached.

This functionality can also be added to a mixin or an utils class and keeps things simple. It can also adapted to < img > by setting the onload listener, fadeIn and src on an existing img element.

TiagoLr
  • 2,782
  • 22
  • 16
0

Use Vue.nextTick. Reference.

Defer the callback to be executed after the next DOM update cycle

Vue.nextTick(() => {
    new Blazy();
});
tony19
  • 125,647
  • 18
  • 229
  • 307
mcont
  • 1,749
  • 1
  • 22
  • 33
0

You can trying to revalidate: "blazy.revalidate()", after fetch function.Or to revalidate in the "updated". I was helped.