简体   繁体   English

如何延迟加载 div 背景图片

[英]How to Lazy Load div background images

As many of you know it is widely used to lazy load images.众所周知,它被广泛用于延迟加载图像。

Now i want to use this as lazy load div background images.现在我想将其用作延迟加载 div 背景图像。

How can i do that ?我怎样才能做到这一点 ?

I am currently able to use http://www.appelsiini.net/projects/lazyload that plugin我目前可以使用http://www.appelsiini.net/projects/lazyload该插件

So i need to modify it in a way that it will work with div backgrounds所以我需要修改它以使其适用于 div 背景

Need help.需要帮忙。 Thank you.谢谢你。

The below part i suppose lazy loads images下面的部分我想延迟加载图像

$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 plugin lazy load jQuery插件延迟加载

First you need to think off when you want to swap.首先,您需要考虑何时要交换。 For example you could switch everytime when its a div tag thats loaded.例如,您可以在每次加载 div 标签时进行切换。 In my example i just used a extra data field "background" and whenever its set the image is applied as a background image.在我的示例中,我只是使用了一个额外的数据字段“背景”,并且每当设置它时,图像就会被应用为背景图像。

Then you just have to load the Data with the created image tag.然后你只需要使用创建的图像标签加载数据。 And not overwrite the img tag instead apply a css background image.并且不覆盖 img 标签,而是应用 css 背景图像。

Here is a example of the code change:这是代码更改的示例:

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 );
}

the loading stays the same负载保持不变

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

and in this example you need to modify the html code like this:在本例中,您需要像这样修改 html 代码:

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

but it would also work if you change the switch to div tags and then you you could work with the "data-original" attribute.但如果您将开关更改为 div 标签,然后您可以使用“data-original”属性,它也会起作用。

Here's an fiddle example: http://jsfiddle.net/dtm3k/1/这是一个小提琴示例:http: //jsfiddle.net/dtm3k/1/

EDIT : the post from below is from 2012 and absolete by now!编辑:下面的帖子是 2012 年的,现在已经过时了!

I do it like this:我这样做:

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

and load with并加载

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

});

Mid last year 2020 web.dev posted an article that shared some new ways to do this with the the new IntersectionObserver which at the time of writing this answer is supported in all major browsers.去年年中2020 年web.dev发布了一篇文章,分享了使用新的IntersectionObserver执行此操作的一些新方法,在撰写本文时,所有主要浏览器都支持此答案。 This will allow you to use a very light weight background image, or background color placeholder while you wait for the image to come to the edge of the viewport and then it is loaded.这将允许您在等待图像到达视口边缘然后加载它时使用重量非常轻的背景图像或背景颜色占位符。

CSS CSS

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

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

Javascript 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);
    });
  }
});

I've found this on the plugin's official site:我在插件的官方网站上找到了这个:

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

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

I've created a "lazy load" plugin which might help.我创建了一个“延迟加载”插件,它可能会有所帮助。 Here is the a possible way to get the job done with it in your case:这是在您的情况下完成工作的一种可能方法:

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

It is simple like maosmurf's example but still gives you the "lazy load" functionality of event firing when the element comes into view.它像 maosmurf 的示例一样简单,但仍然为您提供了在元素出现时触发事件的“延迟加载”功能。

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

It's been a moment that this question is asked, but this doesn't mean that we can't share other answers in 2020. Here is an awesome plugin with jquery: jQuery Lazy有人问这个问题已经有一段时间了,但这并不意味着我们不能在 2020 年分享其他答案。这是一个很棒的 jquery 插件: jQuery Lazy

The basic usage of Lazy: Lazy的基本用法:

HTML HTML

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

JS JS

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

and your background images are lazy loading.并且您的背景图像是延迟加载的。 That's all!就这样!

To see real examples and more details check this link lazy-doc .要查看真实示例和更多详细信息,请查看此链接lazy-doc

I had to deal with this for my responsive website .我必须为我的响应式网站处理这个问题。 I have many different backgrounds for the same elements to deal with different screen widths.对于相同的元素,我有许多不同的背景来处理不同的屏幕宽度。 My solution is very simple, keep all your images scoped to a css selector, like "zoinked".我的解决方案非常简单,将所有图像都限制在一个 CSS 选择器中,例如“zoinked”。

The logic:逻辑:

If user scrolls, then load in styles with background images associated with them.如果用户滚动,则加载具有相关背景图像的样式。 Done!完毕!

Here's what I wrote in a library I call "zoinked" I dunno why.这是我在一个我称之为“zoinked”的库中写的,我不知道为什么。 It just happened ok?刚刚发生好吗?

(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);

For the CSS I'll have all my styles like this:对于 CSS,我将拥有像这样的所有样式:

.zoinked #graphic {background-image: url(large.jpg);}

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

My technique with this is to load all the images after the top ones as soon as the user starts to scroll.我的技术是在用户开始滚动后立即加载顶部图像之后的所有图像。 If you wanted more control you could make the "zoinking" more intelligent.如果你想要更多的控制,你可以让“zoinking”更智能。

Lazy loading images using above mentioned plugins uses conventional way of attaching listener to scroll events or by making use of setInterval and is highly non-performant as each call to getBoundingClientRect() forces the browser to re-layout the entire page and will introduce considerable jank to your website.使用上述插件延迟加载图像使用将侦听器附加到滚动事件或使用 setInterval 的传统方式,并且性能非常低,因为每次调用 getBoundingClientRect() 都会强制浏览器重新布局整个页面,并且会引入相当大的卡顿到您的网站。

Use Lozad.js (just 569 bytes with no dependencies), which uses InteractionObserver to lazy load images performantly.使用Lozad.js (只有 569 字节,没有依赖关系),它使用InteractionObserver来高效地延迟加载图像。

Without jQuery没有 jQuery

HTML HTML

background-image: url('default-loading-image');背景图像:url('默认加载图像');

data-src="image-you-want-to-load" data-src="图片-你想加载"

<div class="ajustedBackground"  style="background-image: url('default-loading-image');" data-src="image-you-want-to-load"><div>

 var tablinks = document.getElementsByClassName("ajustedBackground"); for (i = 0; i < tablinks.length; i++) { var lazy = tablinks[i]; var src = lazy.dataset.src; lazy.style.backgroundImage = 'url("'+src+'")'; }
 .ajustedBackground{ width: 100%; height: 300px; background-size: 100%; border-radius: 5px; background-size: cover; background-position: center; position: relative; }
 <div class="ajustedBackground" style="background-image: url('https://monyo.az/resources/img/ezgif-6-b10ea37ef846.gif');" data-src="https://monyo.az/resources-qrcode/img/Fathir_7%201.png"><div>

Finds all ajustedBackground classname in html and load image from data-src在 html 中查找所有ajustedBackground类名并从data-src加载图像

function lazyloadImages(){
    var tablinks = document.getElementsByClassName("ajustedBackground");
    for (i = 0; i < tablinks.length; i++) {
      var lazy = tablinks[i];
      var src = lazy.dataset.src;

      lazy.style.background =  'url("'+src+'")';
    }

}

Using jQuery I could load image with the check on it's existence.使用 jQuery,我可以加载图像并检查它的存在。 Added src to a plane base64 hash string with original image height width and then replaced it with the required url.将 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();
});

Of course I used and modified few stack answers.当然,我使用并修改了一些堆栈答案。 Hope it helps someone.希望它可以帮助某人。

This is an AngularJS Directive that will do this.这是一个将执行此操作的 AngularJS 指令。 Hope it helps someone希望它可以帮助某人

Usage:用法:

<div background-image="{{thumbnailUrl}}"></div>

Code:代码:

import * as angular from "angular";

export class BackgroundImageDirective implements angular.IDirective {

    restrict = 'A';

    link(scope: angular.IScope, element: angular.IAugmentedJQuery, attrs: angular.IAttributes) {
     
        var backgroundImage = attrs["backgroundImage"];

        let observerOptions = {
            root: null,
            rootMargin: "0px",
            threshold: []
        };

        var intersectionCallback: IntersectionObserverCallback = (entries, self) => {

            entries.forEach((entry) => {
                let box = entry.target as HTMLElement;

                if (entry.isIntersecting && !box.style.backgroundImage) {
                    box.style.backgroundImage = `url(${backgroundImage})`;
                    self.disconnect();
                }
            });
        }

        var observer = new IntersectionObserver(intersectionCallback, observerOptions);
        observer.observe(element[0]);
    }

    static factory(): angular.IDirectiveFactory {
        return () => new BackgroundImageDirective();
    }
}
<div class="lazy" data-bg="img/bmw_m1_hood.jpg" style="width: 765px; height: 574px;"></div>
    
var lazyLoadInstance = new LazyLoad({
  load_delay: 100,
  effect : "fadeIn"
});

using the vanilla lazyload https://www.npmjs.com/package/vanilla-lazyload使用香草延迟加载https://www.npmjs.com/package/vanilla-lazyload

I know it's not related to the image load but here what I did in one of the job interview test.我知道这与图像加载无关,而是我在其中一项工作面试测试中所做的。

HTML HTML

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

CSS 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 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);
          }
    }

});

I am sorting the data by Date and then doing lazy load on window scroll function.我按日期对数据进行排序,然后对窗口滚动功能进行延迟加载。

I hope it helps :)我希望它有帮助:)

Demo演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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