【问题标题】:How to Lazy Load div background images如何延迟加载 div 背景图片
【发布时间】:2012-08-14 10:08:18
【问题描述】:

众所周知,它被广泛用于延迟加载图像。

现在我想将其用作延迟加载 div 背景图像。

我该怎么做?

我目前可以使用http://www.appelsiini.net/projects/lazyload那个插件

所以我需要修改它以使其适用于 div 背景

需要帮助。谢谢。

下面的部分我想延迟加载图片

$self.one("appear", function() {
    if (!this.loaded) {
        if (settings.appear) {
            var elements_left = elements.length;
            settings.appear.call(self, elements_left, settings);
        }
        $("<img />")
            .bind("load", function() {
                $self
                    .hide()
                    .attr("src", $self.data(settings.data_attribute))
                    [settings.effect](settings.effect_speed);
                self.loaded = true;

                /* Remove image from array so it is not looped next time. */
                var temp = $.grep(elements, function(element) {
                    return !element.loaded;
                });
                elements = $(temp);

                if (settings.load) {
                    var elements_left = elements.length;
                    settings.load.call(self, elements_left, settings);
                }
            })
            .attr("src", $self.data(settings.data_attribute));
    }
});

Jquery 插件延迟加载

【问题讨论】:

    标签: javascript jquery image background lazy-loading


    【解决方案1】:

    首先,您需要考虑何时要交换。例如,您可以在每次加载 div 标签时进行切换。在我的示例中,我只是使用了一个额外的数据字段“背景”,并且每当设置它时,图像就会被应用为背景图像。

    然后您只需使用创建的图像标签加载数据。并且不覆盖 img 标签,而是应用 css 背景图片。

    以下是代码更改示例:

    if (settings.appear) {
        var elements_left = elements.length;
        settings.appear.call(self, elements_left, settings);
    }
    var loadImgUri;
    if($self.data("background"))
        loadImgUri = $self.data("background");
    else
        loadImgUri  = $self.data(settings.data_attribute);
    
    $("<img />")
        .bind("load", function() {
            $self
                .hide();
            if($self.data("background")){
                $self.css('backgroundImage', 'url('+$self.data("background")+')');
            }else
                $self.attr("src", $self.data(settings.data_attribute))
    
            $self[settings.effect](settings.effect_speed);
    
            self.loaded = true;
    
            /* Remove image from array so it is not looped next time. */
            var temp = $.grep(elements, function(element) {
                return !element.loaded;
            });
            elements = $(temp);
    
            if (settings.load) {
                var elements_left = elements.length;
                settings.load.call(self, elements_left, settings);
            }
        })
        .attr("src", loadImgUri );
    }
    

    加载保持不变

    $("#divToLoad").lazyload();
    

    在本例中,您需要像这样修改 html 代码:

    <div data-background="http://apod.nasa.gov/apod/image/9712/orionfull_jcc_big.jpg" id="divToLoad" />​
    

    但如果您将开关更改为 div 标签,然后您可以使用“data-original”属性,它也会起作用。

    这是一个小提琴示例:http://jsfiddle.net/dtm3k/1/

    【讨论】:

    • 只是想指出,该小提琴中的 JS 有许多实例,其中自定义选择器函数被错误的名称调用。像这样的东西:“rightoffold”应该是“rightofscreen”。这是一个更新的小提琴,其中所有选择器扩展函数名称和调用都已更正:jsfiddle.net/dtm3k/93
    【解决方案2】:

    编辑:下面的帖子是 2012 年的,现在已经过时了!

    我是这样做的:

    <div class="lazyload" style="width: 1000px; height: 600px" data-src="%s">
        <img class="spinner" src="spinner.gif"/>
    </div>
    

    并加载

    $(window).load(function(){
    
        $('.lazyload').each(function() {
    
            var lazy = $(this);
            var src = lazy.attr('data-src');
    
            $('<img>').attr('src', src).load(function(){
                lazy.find('img.spinner').remove();
                lazy.css('background-image', 'url("'+src+'")');
            });
        
        });
    
    });
    

    【讨论】:

    • 你在哪里调用 $.lazyload()?
    • 我自己不调用它,但使用 $(window).load() 注册回调另见api.jquery.com/load-event/#entry-examples
    • 我看不到这个延迟加载页面中的图像的方式,如果页面加载时没有填充图像的 src 属性,$(window).load 将触发,然后您的所有图像都将被加载一下子……
    • 整个页面,因此除了图像之外的所有元素都会加载。所有可用的文本,JS 加载和解释。只有根据 data-src 加载图像 ae。您的浏览器对每个主机的连接数有限制,因此您不会一次加载所有图像
    • 我不认为延迟加载插件提供的行为相同。延迟加载插件仅在图像即将可见时加载图像,例如,当您向下滚动放置这些图像的位置时。这样,如果没有显示图像,则不会加载它们。即使浏览器对每个主机的连接有限制,它们都会被加载,这不是延迟加载。
    【解决方案3】:

    我在插件的官方网站上找到了这个:

    <div class="lazy" data-original="img/bmw_m1_hood.jpg" style="background-image: url('img/grey.gif'); width: 765px; height: 574px;"></div>
    
    $("div.lazy").lazyload({
          effect : "fadeIn"
    });
    

    来源:http://www.appelsiini.net/projects/lazyload/enabled_background.html

    【讨论】:

      【解决方案4】:

      去年年中2020web.dev 发表了一篇文章,分享了使用新的IntersectionObserver 执行此操作的一些新方法,在撰写此答案时,所有主要浏览器都支持该方法。这将允许您在等待图像到达视口边缘然后加载它时使用重量非常轻的背景图像或背景颜色占位符。

      CSS

      .lazy-background {
        background-image: url("hero-placeholder.jpg"); /* Placeholder image */
      }
      
      .lazy-background.visible {
        background-image: url("hero.jpg"); /* The final image */
      }
      

      Javascript

      document.addEventListener("DOMContentLoaded", function() {
        var lazyBackgrounds = [].slice.call(document.querySelectorAll(".lazy-background"));
      
        if ("IntersectionObserver" in window) {
          let lazyBackgroundObserver = new IntersectionObserver(function(entries, observer) {
            entries.forEach(function(entry) {
              if (entry.isIntersecting) {
                entry.target.classList.add("visible");
                lazyBackgroundObserver.unobserve(entry.target);
              }
            });
          });
      
          lazyBackgrounds.forEach(function(lazyBackground) {
            lazyBackgroundObserver.observe(lazyBackground);
          });
        }
      });
      

      【讨论】:

        【解决方案5】:

        我创建了一个“延迟加载”插件,它可能会有所帮助。在您的情况下,这是完成工作的一种可能方法:

        $('img').lazyloadanything({
            'onLoad': function(e, LLobj) {
                var $img = LLobj.$element;
                var src = $img.attr('data-src');
                $img.css('background-image', 'url("'+src+'")');
            }
        });
        

        它像 maosmurf 的示例一样简单,但仍然为您提供了在元素进入视图时触发事件的“延迟加载”功能。

        https://github.com/shrimpwagon/jquery-lazyloadanything

        【讨论】:

          【解决方案6】:

          这个问题被问到已经有一段时间了,但这并不意味着我们不能在 2020 年分享其他答案。这是一个很棒的 jquery 插件:jQuery Lazy

          Lazy的基本用法:

          HTML

          <!-- load background images of other element types -->
          <div class="lazy" data-src="path/to/image.jpg"></div>
          enter code here
          

          JS

           $('.lazy').Lazy({
              // your configuration goes here
              scrollDirection: 'vertical',
              effect: 'fadeIn',
              visibleOnly: true,
              onError: function(element) {
                  console.log('error loading ' + element.data('src'));
              }
          });
          

          而且你的背景图片是延迟加载的。就是这样!

          要查看真实示例和更多详细信息,请查看此链接lazy-doc

          【讨论】:

            【解决方案7】:

            我必须为我的响应式网站处理这个问题。我有许多相同元素的不同背景来处理不同的屏幕宽度。我的解决方案非常简单,将所有图像的范围限定为一个 CSS 选择器,例如“zoinked”。

            逻辑:

            如果用户滚动,则加载带有相关背景图像的样式。 完成!

            这是我在一个我称之为“zoinked”的库中写的,我不知道为什么。刚刚还好吗?

            (function(window, document, undefined) {   var Z = function() {
                this.hasScrolled = false;
            
                if (window.addEventListener) {
                  window.addEventListener("scroll", this, false);
                } else {
                  this.load();
                }   };
                 Z.prototype.handleEvent = function(e) {
                if ($(window).scrollTop() > 2) {
                  this.hasScrolled = true;
                  window.removeEventListener("scroll", this);
                  this.load();
                }   };
                 Z.prototype.load = function() {
                $(document.body).addClass("zoinked");   };
                 window.Zoink = Z; 
            })(window, document);
            

            对于 CSS,我的所有样式都是这样的:

            .zoinked #graphic {background-image: url(large.jpg);}
            
            @media(max-width: 480px) {.zoinked #graphic {background-image: url(small.jpg);}}
            

            我的技术是在用户开始滚动后立即加载顶部图像之后的所有图像。如果你想要更多的控制,你可以让“zoinking”更智能。

            【讨论】:

              【解决方案8】:

              使用上述插件延迟加载图像使用将侦听器附加到滚动事件或使用 setInterval 的传统方式,并且性能极差,因为每次调用 getBoundingClientRect() 都会强制浏览器 re-layout 整个页面并会向您的网站引入相当多的 jank。

              使用 Lozad.js(只有 569 字节,没有依赖关系),它使用 InteractionObserver 来高效地延迟加载图像。

              【讨论】:

              • 不错的选择,但目前应该提供对旧算法的回退,因为并非所有主要浏览器都支持此 API。
              • IntersectionObserver 的 Polyfill 可以根据需要动态加载,以防浏览器支持不可用npmjs.com/package/intersection-observer
              【解决方案9】:

              我知道这与图像加载无关,而是我在其中一项工作面试测试中所做的。

              HTML

              <div id="news-feed">Scroll to see News (Newest First)</div>
              

              CSS

              article {
                 margin-top: 500px;
                 opacity: 0;
                 border: 2px solid #864488;
                 padding: 5px 10px 10px 5px;
                 background-image: -webkit-gradient(
                 linear,
                 left top,
                 left bottom,
                 color-stop(0, #DCD3E8),
                 color-stop(1, #BCA3CC)
                 );
                 background-image: -o-linear-gradient(bottom, #DCD3E8 0%, #BCA3CC 100%);
                 background-image: -moz-linear-gradient(bottom, #DCD3E8 0%, #BCA3CC 100%);
                 background-image: -webkit-linear-gradient(bottom, #DCD3E8 0%, #BCA3CC 100%);
                 background-image: -ms-linear-gradient(bottom, #DCD3E8 0%, #BCA3CC 100%);
                 background-image: linear-gradient(to bottom, #DCD3E8 0%, #BCA3CC 100%);
                 color: gray;
                 font-family: arial;    
              }
              
              article h4 {
                 font-family: "Times New Roman";
                 margin: 5px 1px;
              }
              
              .main-news {
                 border: 5px double gray;
                 padding: 15px;
              }
              

              JavaScript

              var newsData,
                  SortData = '',
                  i = 1;
              
              $.getJSON("http://www.stellarbiotechnologies.com/media/press-releases/json", function(data) {
              
                 newsData = data.news;
              
                 function SortByDate(x,y) {
                   return ((x.published == y.published) ? 0 : ((x.published < y.published) ? 1 : -1 ));
                 }
              
                 var sortedNewsData = newsData.sort(SortByDate);
              
                 $.each( sortedNewsData, function( key, val ) {
                   SortData += '<article id="article' + i + '"><h4>Published on: ' + val.published + '</h4><div  class="main-news">' + val.title + '</div></article>';
                   i++;    
                 });
              
                 $('#news-feed').append(SortData);
              });
              
              $(window).scroll(function() {
              
                 var $window = $(window),
                     wH = $window.height(),
                     wS = $window.scrollTop() + 1
              
                 for (var j=0; j<$('article').length;j++) {
                    var eT = $('#article' + j ).offset().top,
                        eH = $('#article' + j ).outerHeight();
              
                        if (wS > ((eT + eH) - (wH))) {
                           $('#article' + j ).animate({'opacity': '1'}, 500);
                        }
                  }
              
              });
              

              我正在按日期对数据进行排序,然后对窗口滚动功能进行延迟加载。

              希望对你有帮助:)

              Demo

              【讨论】:

              • 这不是延迟加载,您正在从服务器返回所有数据,然后在向下滚动时设置项目的可见性。延迟加载是在用户滚动到内容时从服务器请求数据。如果你在面试中侥幸成功,那就太好了。
              【解决方案10】:

              使用 jQuery 我可以加载图像并检查它是否存在。将 src 添加到具有原始图像高度宽度的平面 base64 哈希字符串中,然后将其替换为所需的 url。

              $('[data-src]').each(function() {
                var $image_place_holder_element = $(this);
                var image_url = $(this).data('src');
                $("<div class='hidden-class' />").load(image_url, function(response, status, xhr) {
                  if (!(status == "error")) {
                    $image_place_holder_element.removeClass('image-placeholder');
                    $image_place_holder_element.attr('src', image_url);
                  }
                }).remove();
              });
              

              当然,我使用并修改了一些堆栈答案。希望它可以帮助某人。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2016-03-24
                • 2018-08-12
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2014-06-05
                相关资源
                最近更新 更多