tebdilikiyafet
tebdilikiyafet

Reputation: 405

Jquery lazyload with ajax

I use lazyload() on my ecommerce website. lazyload() works great. I use this code to do that:

$(function(){
  $("img.lazy").lazyload({ 
  effect : "fadeIn"
          });
});

Also there are some filter like color, price etc. which is run an ajax and show new result. When new result come, lazyload() doesn't work. I know that I have to use lazyload() with live(), delegate() or on(). But I am a newbie on jquery and I couldn't do that. Can anyone help me please? My jquery version is 1.7.2 and we can use on().

Upvotes: 10

Views: 41204

Answers (8)

Dipen
Dipen

Reputation: 1064

For my scenario when the page is loaded I will get list of template with template Id. Based on that template Id I use jQuery Lazy to load base64 encoded images using ajax and load image lazily on my page.

Hope you will get some idea of my approach

$(document).ready(function() {
  let imageArray = [0, 1, 10, 100, 1000, 1001];

  let parsedImageArray = $.map(imageArray, function(value) {
    return "<div class='lazy' data-loader='ajaxLoader' data-src='/echo/html/' data-method='post' contentId='" + value + "'></div><br>";
  });

  $("#content").html(parsedImageArray);

  console.log("Here" + parsedImageArray)
});


$(document).bind('DOMNodeInserted', function(e) {
  $('.lazy').lazy({
    effect: "fadeIn",
    event: "scrollstop",
    skip_invisible: true,
    removeAttribute: false,
    ajaxLoader: function(element, response) {
      let thumbnailId = element.attr("contentId");
      console.log("Here" + thumbnaiId);
      $.get("https://picsum.photos/id/" + thumbnailId, function(srcValue, status) {
        //for me i have to pull the base64 encode image from my server 
        let defaultImageDom = generateThumbnailImage(tempSrc);
        element.html(defaultImageDom);
        element.removeClass('lazy');
      }).fail(function(jqXHR, textStatus, errorThrown) {
        let defaultImageDom = generateThumbnailImage("");
        element.html(defaultImageDom);
        element.append("<em>Error Getting Thumbnail Preview</em>");
        element.removeClass('lazy');
      });
    },
  });
});

function generateThumbnailImage(srcValue) {
  let defaultImageDom = new Image();
  defaultImageDom.height = 200;
  defaultImageDom.style.borderColor = "#d5d5d5";
  defaultImageDom.style.borderWidth = "1px";
  defaultImageDom.style.borderStyle = "solid";

  if (srcValue && srcValue.length > 0) {
    defaultImageDom.src = srcValue;
  } else {
    //set your fallback image link
    defaultImageDom.src = "data:image/gif;base64,R0lGODdhAQABAPAAAMPDwwAAACwAAAAAAQABAAACAkQBADs=";
  }
  return defaultImageDom;
}
.lazy {
  width: 700px;
  height: 467px;
  display: block;
  /* optional way, set loading as background */
  background-image: 'data:image/gif;base64,R0lGODdhAQABAPAAAMPDwwAAACwAAAAAAQABAAACAkQBADs=';
  background-repeat: no-repeat;
  background-position: 50% 50%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery.lazy/1.7.9/jquery.lazy.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery.lazy/1.7.9/jquery.lazy.plugins.min.js"></script>

<div id="content">
</div>

Upvotes: 0

antoniputra
antoniputra

Reputation: 4351

I have same problem, when using waypoints infinite scroll with lazy load image. (but not work on ajax content).

and I fixed that issue with this :

$("img.lazy").lazyload({
    effect : "fadeIn",
    event: "scrollstop",
    skip_invisible : true
}).removeClass('lazy');

$(document).bind('DOMNodeInserted', function(e) {
    $("img.lazy").lazyload({
        effect : "fadeIn",
        event: "scrollstop",
        skip_invisible : true
    }).removeClass('lazy');
});

I bind the lazy load configuration on DOMNodeInserted event.

Upvotes: 0

RafaSashi
RafaSashi

Reputation: 17205

In addition to AbdelHady's answer you can lazy load new images on success as a callback or use when() this way:

   $.when(load_new_image()).done(function(i){

            if($('img.lazy').length){

                 $('img.lazy').lazyload({ 

                          effect:'fadeIn'

                 }).removeClass('lazy').addClass('lazyloaded');

            }

        });

        function load_new_image() {

            return $.ajax({
                url: "your url here",
                type: "Post",
                success: function(response){

                     //append new content
                    $('#container').append(response);

                }
            });
        }

NOTA BENE

Upvotes: 1

Cymen
Cymen

Reputation: 14419

NOTE: At the time this answer was accepted, this worked. The lazy loading plugin changed and now it is broken. I cannot unaccept the answer nor can I delete it.

There is another Q&A that suggests handling it as part of the AJAX request responsible for inserting the additional DOM:

Binding image lazy loading to new images inserted after ajax request

However, this is how I would do it:

$(document).on('DOMNodeInserted', 'img.lazy', function() {
    $(this).lazyload({
        effect: 'fadeIn'
    });
});

Demo: jsfiddle

Upvotes: 2

AbdelHady
AbdelHady

Reputation: 9702

Shortly, the best optimized way to do this is to call the lazyload in your ajax's success function:

$.ajax({
    url: "your url here",
    type: "Post",
    success: function(response){
        // handle your success callback here
        $("img.lazy").lazyload({ 
              effect : "fadeIn"
        });
    }
});

But if you want to centralize your call to the lazyload plugin, you have 2 options:

First: (not recommended due to performance hit)

$(document).on('DOMNodeInserted', '#container', function() {
    $("img.lazy").lazyload({
        effect: 'fadeIn'
    });
});

but note here the "#container", it is the container's selector where you will show your new loaded stuff, so the code above will listen inside this container for any newly added stuff to run the lazyload again on new images,

Second: (recommended)

Calling your custom lazyload by adding it to your JQuery:

$.fn.myLazyLoad = function() {
    this.lazyload({ 
          effect : "fadeIn"
    });
};

then, call it in all your AJAX requests:

$.ajax({
    url: "your url here",
    type: "Post",
    success: function(response){
        // handle your success callback here
        $("img.lazy").myLazyLoad();
    }
});

Upvotes: 6

Mark
Mark

Reputation: 876

Lazyload for images loaded after window load (e.g. AJAX) will not display any images before a scroll event. This is because it is internally hardcoded to trigger the initial update after the window load event. All the above answers, for now, are wrong.

Upvotes: 1

alexzg
alexzg

Reputation: 845

   $(document).ajaxStop(function() {$('.loading').removeClass('in');
    $("img.lazy").lazyload({
                effect: "fadeIn",
               container: $("#scrollable"),
               threshold: 100,
            })

      });

works for ajax images. but however, not showing the first image by default. the update is not triggered.

Upvotes: -2

tebdilikiyafet
tebdilikiyafet

Reputation: 405

I use the code below and it worked:

$(document).on('ajaxStop', function() {
   $("img.lazy").lazyload({
        effect: 'fadeIn'
    });
});

Upvotes: -2

Related Questions