简体   繁体   中英

Content lazy loading

The idea is to load content ex: <div> when it is near to visible display area.

For example I can do this with images:

 $(function() { $("img.lazy").lazyload({ effect: "fadeIn", threshold : 200 }); }); 
 <script src="https://code.jquery.com/jquery-1.11.0.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.lazyload/1.9.1/jquery.lazyload.min.js"></script> <img class="lazy" data-original="http://www.aripaev.ee/storyimage/EA/20150529/NEWS/150529839/AR/0/Ainar-Sulumets.jpg&ExactW=640&ExactH=420&Q=95" width="450" height="280" /> <img class="lazy" data-original="http://www.dumpaday.com/wp-content/uploads/2015/05/pictures-1106-700x280.jpg" width="450" height="280" /> <img class="lazy" data-original="http://www.dumpaday.com/wp-content/uploads/2015/05/thumb37-700x280.jpg" width="450" height="280" /> <img class="lazy" data-original="http://www.dumpaday.com/wp-content/uploads/2015/05/160-700x280.jpg" width="450" height="280" /> <img class="lazy" data-original="http://www.dumpaday.com/wp-content/uploads/2015/05/fun-facts-1-700x280.jpg" width="450" height="280" /> <img class="lazy" data-original="http://www.dumpaday.com/wp-content/uploads/2015/05/pictures-1105-700x280.jpg" width="450" height="280" /> 

My question is, what is the cleanest way to do this for <div> and it's content?


Edit:

I can write ad-hoc solutions myself, that would work, but I was hoping for existing lib.

        var $myElt = $('#item');
        var $window = $(window);
        var myTop = $myElt.offset().top;
        var myBot = myTop + myElt.height();
        var windowTop = $window.scrollTop();
        var windowBottom = windowTop + $window.height();

        if ((myTop > windowTop && myTop < windowBottom) 
        || (myBot > windowTop && myBot < windowBottom)) {
           //load item

Assuming that your are using the the jQuery lazyload plugin, there is an option available in the plugin where we can create an anchor element having a class with its href equal to the URL which will load the next content. This anchor element will be at the end of the container and when the anchor enters the viewport the ajax call for loading the next content will be fired.

I have used it in the past, but I dont remember the exact syntax.

I think, for better performance, it is better if you implement it without a third party library. A possible solution is, for example if you have "this.images_queue" as an array of image objects, you then:

  • Bind scroll to the window

  • You choose a scroll percent to load content when scroll percent exceeded. (The percent will seem static, but the length of the scroll bar is raising when lazy scrolling, so it will be smoothly dynamic)

  • You choose a number if initially rendered images (here I chose 12)

  • Choose a number of how many images to append when you scroll (here I chose 4)

  • The "offset" will be 0 at the beginning, after that it will be updated on each load, the "end" also will be calculated, these two params will determine the part of the array to slice, that part will be appended to template on each load.

  • For the initial load, you can call the function "loadMore" on the initialization of the page:

this is a possible example (with BackboneJS) but normally it will be suitable:

var self = this;
this.offset = 0;
$(window).bind('scroll', function(ev) {
self.loadMore(ev);
});
loadMore: function() {
    var s = $(window).scrollTop(),
        d = $(document).height(),
        c = $(window).height();
    var scrollPercent = (s / (d - c)) * 100; // The percent of the scroll
        if (this.offset < this.images_queue.length && (this.offset == 0 || scrollPercent >= 70)) { // For firefox you can find the scroll bar scrolled on reload while offset=0
        var end = 0;
        if (this.offset == 0) {
            end = Math.min(12, this.images_queue.length);
        } //the min is used in case (12) exceeds the images_queue boundary
            else {
            end = Math.min(this.offset + 4, this.images_queue.length);
        } //the min is used in case (offset + 4) exceeds the images_queue boundary
            data = this.images_queue.slice(this.offset, end)
        var some_images = "";
        for (i = 0; i < data.length; i++) {
            var x = '<img class="lazy" data-original="' + data[i].image_url + '" width="450" height="280" />'
            some_images = some_images + x + '\n'; //normally works '\n'
        }
$(".divContainingImages").append(some_images); //Append the images from the sliced array
        this.offset = end;
    } //end if
} //end loadmore fun
  • Attention: You MUST UNBIND SCROLL FROM WINDOW $(window).unbind('scroll'); on all thy other pages (on initialize of each page or on the base page if you have).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM