Jquery懒加载与ajax

10

我在我的电子商务网站上使用了lazyload()。 lazyload()效果很好。 我使用以下代码来实现:

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

此外,还有一些过滤器,例如颜色、价格等,这些过滤器会运行ajax并显示新结果。当新结果出现时,lazyload()将无法正常工作。我知道我必须使用lazyload()与live()、delegate()或on()一起使用。但我是一个jquery的新手,我无法做到这一点。请问有人可以帮助我吗?我的jquery版本是1.7.2,我们可以使用on()。


1
请尝试另一个答案并取消接受我的答案,好吗?我的答案已经不再适用,而且人们一直在给它投反对票。 - Cymen
8个回答

6

简单来说,最优化的方法是在你的ajax成功后调用懒加载函数:call the lazyload in your ajax's success

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

但是,如果您想将懒加载插件的调用集中管理,则有两个选项

第一种方法:(不建议使用,因为会影响性能)

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

注意这里的“#container”,它是您将显示新加载的内容的容器选择器,因此上面的代码将在此容器内侦听任何新添加的内容,以再次运行懒加载以加载新图像。

第二步:(推荐)

通过将其添加到您的JQuery中调用自定义懒加载:

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

然后,在所有的AJAX请求中调用它:

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

@tebdilikiyafet 这是一个有效的工作答案,如果它符合您的需求,您可以接受它。 - AbdelHady
不,你打算在每个ajax调用中都重复这样做吗?如果你有20个jQuery插件而不是1个呢?这样做一次并监听DOM更改(例如MutationObserver)是唯一可靠的方式。 - Mike Doe
@emix,如果你想监听DOM节点的变化,那么你可以使用这里提到的第一种方法,它依赖于 DOMNodeInserted.. 但从性能上来说,它可能不是最好的选择,因为即使更改没有插入新图像,此监听器也会随着任何DOM插入而运行,这肯定会影响性能。 - AbdelHady
就像使用防抖函数一样容易。我无论如何都在和@Alex交谈。 - Mike Doe
仅仅为了分享知识,很多类似于懒加载的库,由于它们操作Dom对象的方式,会产生回流(reflow),而回流会阻塞浏览器的UI线程,从而降低渲染帧率,当频繁使用时会严重影响性能。因此,使用第三方库应该谨慎,不仅仅是为了代码方便。 - AbdelHady

2

注意:在接受此答案时,它是有效的。懒加载插件已更改,现在已失效。我无法取消接受答案,也无法删除它。

还有另一个问答建议将其作为负责插入其他DOM的AJAX请求的一部分来处理:

如何绑定图片懒加载到在AJAX请求后插入的新图像

但是,这是我会这样做的方式:

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

演示: jsfiddle

我看到了,但它不是用on()的。你认为ajaxstop怎么样?ajaxstop和on哪个更好? - tebdilikiyafet
我会使用 on。我已经更新了我的答案,并提供了一个使用 DOMNodeInserted 插入事件的示例。我认为这样更清晰,因为它将其与通过 AJAX 加载数据的关注点分离开来。 - Cymen
我添加了我的解决方案作为一个新答案。你认为它怎么样?有效吗? - tebdilikiyafet
@tebdilikiyafet 看起来不错。它非常相似。可能稍微更有效率一些,如 $(document).on('ajaxStop', 'img.lazy', function() { $(this).lazyload({effect: 'fadeIn' }); }); 但我认为在性能方面并没有太大关系。 - Cymen
DOMNodeInserted事件已被弃用。 - kuboon
显示剩余2条评论

1
除了AbdelHady的回答外,你可以将Lazy Load作为回调函数在成功时加载新的图像,或者使用when()这种方式:
   $.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


1
Lazyload对于在窗口加载后(例如AJAX)加载的图像不会在滚动事件之前显示任何图像。这是因为它在内部硬编码以在窗口加载事件后触发初始更新。目前,以上所有答案都是错误的。

那是原始的问题吗?我不这么认为。为什么不把这个问题作为一个新问题来询问呢? - Cymen
是的Cymen,我的回答很相关。这个问题涉及使用Ajax时遇到的延迟加载问题,我指出延迟加载并不适用于这种情况。 - Mark
我认为发生的情况是jQuery lazyload更改了实现方式。我知道在我回答的时候,我的jsfiddle是工作的。但现在它不再起作用了。这就是为什么重新提问处理为什么会出问题或向lazyload团队提交错误报告以获得修复更有意义的原因。 - Cymen

0
对于我的场景,当页面加载时,我将获取模板列表及其模板ID。根据该模板ID,我使用jQuery Lazy通过ajax加载base64编码图像,并在页面上懒加载图像。
希望你能对我的方法有一些了解。

$(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>


0

我遇到了同样的问题,当使用路点无限滚动和懒加载图片时(但不适用于ajax内容)。

我通过以下方式解决了这个问题:

$("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');
});

我在DOMNodeInserted事件上绑定了延迟加载配置。


-2

我使用下面的代码,它有效:

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

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

      });

适用于Ajax图片。但是,默认情况下不显示第一张图片。更新未被触发。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接