0
votes

I have a Backbone.js application with require.js, underscore.js. And now I want to use jquery lazy loading plugin with the Eislider banner.

The banner works well before applying the lazy loading script.

This is how I did in my backbone view :

 render: function(options){
        var _banner = _.template(BaTem);
        var homebanner = new ProWeb();
        homebanner.getPrCallBack(this.options.type, function(result) {
            $(this.el).html(_banner({type : this.options.type,result:result}));
            $("img.lazy").lazyload({
                 event : "click"
            });
        }.bind(this));
        return this;
}

Here is the template in html file by using text.js

<ul class="ei-slider-large">
 <li>
    <img class="lazy" data-original=images/05056ba1e25.png" alt="slide show" width="640" height="480"/>
 <a href="#itemDet">
    <img class="lazy" data-original=images/05056ba1e25.png" alt="slide show" width="640" height="480"/>
 </a>
 <a href="#item">
    <img class="lazy" data-original=images/05056ba1e25.png" alt="slide show" width="640" height="480"/>
 </a>
 </li>
</ul>

After applying lazy loading script, the images are stop showing.

Any idea what could be causing this.

2

2 Answers

0
votes

It looks as though your call to .bind() is a little off. Maybe try Underscore _bindAll() to get context of this inside the callback:

render: function(options) {
    var _banner = _.template(BaTem);
    var homebanner = new ProWeb();

    _.bindAll(homebanner, 'getPrCallBack');

    homebanner.getPrCallBack(this.options.type, function(result) {
        $(this.el).html(_banner({type : this.options.type,result:result}));
        $("img.lazy").lazyload({
             event : "click"
        });
    });

    return this;
}

http://underscorejs.org/#bindAll

Binds a number of methods on the object, specified by methodNames, to be run in the context of that object whenever they are invoked. Very handy for binding functions that are going to be used as event handlers, which would otherwise be invoked with a fairly useless this. methodNames are required.

Does that help?

0
votes

I would strongly discourage from using jQuery lazyload and similar plugin to use in general and in particular on highly dynamic webpages. jQuery lazyload is in general slow, but everytime you run $("img.lazy").lazyload(); a new Observer/Lazyload instance is created with strong references to all images you have put in there.

While you can improve this a little bit, by providing more specific context: $("img.lazy", this.el).lazyload(); it still is quite inefficient.

In general i would assume, that you need to trigger a synthetic scroll event:

$(this.el).html(_banner({type : this.options.type,result:result}));
$("img.lazy", this.el).lazyload({event : "click"});
$(window).trigger("scroll");

But instead of doing this and using jQuery lazyload at all, I would suggest that you try to use lazySizes. I developed it with dynamic pages and SPAs in mind. You will not need to invoke a special function or trigger an event inside your render function(s) (= you can simply remove the call to $.lazyload) (This helps with separation of concerns).

You need to just add the script to your page and use data-src instead of data-original and the class lazyload instead of lazy (Of course you can also configure the options so that you don't need to change even the markup).

<ul class="ei-slider-large">
 <li>
    <img class="lazyload" data-src=images/05056ba1e25.png" alt="slide show" width="640" height="480"/>
 <a href="#itemDet">
    <img class="lazyload" data-src=images/05056ba1e25.png" alt="slide show" width="640" height="480"/>
 </a>
 <a href="#item">
    <img class="lazyload" data-src=images/05056ba1e25.png" alt="slide show" width="640" height="480"/>
 </a>
 </li>
</ul>

Additionally: The Eislider banner seems to need the size of your images to work properly. This means you need to define width and height, before they are loaded via CSS. In case these images are static (i.e.: 640x480) you won't need to change anything. In case you have a responsive layout with responsive images you need to use the CSS intrinsic pattern to solve this.

This could look something like this:

.ei-slider-large li {
    position: relative;
    height: 0;
    padding-bottom: 75%;
    width: 100%;
}
.ei-slider-large img {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
}

I'm pretty sure you will like it.