如何检查是否加载了背景图像?


154

我想在body标签上设置背景图片,然后运行一些代码-像这样:

$('body').css('background-image','http://picture.de/image.png').load(function() {
    alert('Background image done loading');
    // This doesn't work
});

如何确定背景图像已完全加载?


4
刚分配相同的URL Image()对象,它确实有onload事件。
暗影巫师为您耳边

2
确保将css网址包装在url()
bluescrubbie 2012年

Answers:


274

试试这个:

$('<img/>').attr('src', 'http://picture.de/image.png').on('load', function() {
   $(this).remove(); // prevent memory leaks as @benweet suggested
   $('body').css('background-image', 'url(http://picture.de/image.png)');
});

这将在内存中创建新映像,并使用load事件检测何时加载src。


10
似乎图像会无故加载两次。
HyderA 2011年

49
@gAMBOOKa由于它们停留在浏览器内存中,因此已加载一次。这是相同的,当您将隐藏的图像放在页面顶部,然后在CSS中进行设置时-因此图像将在css文件之前开始下载-这称为预加载。
2011年

4
我不太确定,但我认为您指的是缓存。我认为浏览器内存不会存储资产。如果您指的是缓存,请记住您要添加一个额外的HTTP请求,并且所有客户端可能未启用缓存。
HyderA 2011年

7
在具有jquery:的任何页面中输入此内容,javascript:void($('<img/>').attr('src', 'http://farm6.static.flickr.com/5049/5220175127_5693faf952.jpg').load(function() { $('html').css('background-image', 'url(http://farm6.static.flickr.com/5049/5220175127_5693faf952.jpg)'); }))然后在Firebug中检查HTTP请求。如果我打开了闪烁页面,并且在另一个选项卡中打开了该图像,则它不执行任何HTTP请求,而只是立即显示该图像。当我清除并运行缓存时,有一个请求。
jcubic 2011年

26
之间的比较这个测试这一个节目,你要调用 .remove()$('<img/>')对象以避免内存泄漏。您应该在第一个测试中看到稳定的内存消耗,而在第二个测试中看到内存增加。在Chrome 28上运行几个小时后,第一次测试需要80MB,第二次测试需要270MB。
benweet

23

我有一个jQuery插件称为waitForImages当背景图片下载,可以检测。

$('body')
  .css('background-image','url(http://picture.de/image.png)')
  .waitForImages(function() {
    alert('Background image done loading');
    // This *does* work
  }, $.noop, true);

这个插件也非常适合能够使用each回调显示加载进度。
苏联2013年

1
@alex,如何检查类中每个元素的每个背景图像?我试过了,但似乎做得不好。$('。user_main_photo_thumb')。waitForImages(function(){$(this).parents('。photoThumbFrame')。delay(1000).slideDown();},function(loaded,count,success){});
Relm

@Relm您没有正确使用它。第二个回调是每个图像。另外,delay()也不是那样。
Alex

16

像这样:

var $div = $('div'),
  bg = $div.css('background-image');
  if (bg) {
    var src = bg.replace(/(^url\()|(\)$|[\"\'])/g, ''),
      $img = $('<img>').attr('src', src).on('load', function() {
        // do something, maybe:
        $div.fadeIn();
      });
  }
});

你好...这似乎可行,尽管我将bg.replace设置为bg.replace( ... , my_src )。但是我的问题是:一旦加载了$('<img>'),它到底发生了什么<img>……我的意思是它实际上不是真实的-它只是一个虚拟的占位符,对吗?
dsdsdsdsd 2013年

对。将<img>永远不会插入到DOM; 它只是用来“愚弄”浏览器以将图像文件加载到缓存中。
Colin 2013年

如果您不想调用jQuery会
很有帮助


8

纯JS解决方案,它将添加预加载器,设置背景图像,然后将其与事件监听器一起设置为垃圾回收

精简版:

const imageUrl = "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png";
let bgElement = document.querySelector("body");
let preloaderImg = document.createElement("img");
preloaderImg.src = imageUrl;

preloaderImg.addEventListener('load', (event) => {
    bgElement.style.backgroundImage = `url(${imageUrl})`;
    preloaderImg = null;
});

具有更好的不透明度过渡,时间更长:

const imageUrl = "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png";
let bgElement = document.querySelector(".bg-lazy");
bgElement.classList.add("bg-loading");
let preloaderImg = document.createElement("img");
preloaderImg.src = imageUrl;

preloaderImg.addEventListener('load', (event) => {
  bgElement.classList.remove("bg-loading");
  bgElement.style.backgroundImage = `url(${imageUrl})`;
  preloaderImg = null;
});
.bg-lazy {
  height: 100vh;
  width: 100vw;
  transition: opacity 1s ease-out;
}

.bg-loading {
  opacity: 0;
}
<div class="bg-lazy"></div>


3
被低估的解决方案。
汤姆·汤姆森

1
@TomThomson谢谢汤姆,我发现图像转换
无法

6

这是我制作的一个小插件,可让您执行此操作,它也可用于多个背景图像和多个元素:

阅读文章:

http://catmull.uk/code-lab/background-image-loaded/

或直接转到插件代码:

http://catmull.uk/downloads/bg-loaded/bg-loaded.js

因此,只需包含插件,然后在元素上调用它即可:

<script type="text/javascript" src="http://catmull.uk/downloads/bg-loaded/bg-loaded.js"></script>
<script type="text/javascript">
   $('body').bgLoaded();
</script>

显然,下载插件并将其存储在您自己的主机上。

默认情况下,一旦加载了背景,它将为每个匹配的元素添加一个额外的“ bg-loaded”类,但是您可以通过向其传递一个不同的函数来轻松地更改它,如下所示:

<script type="text/javascript" src="http://catmull.uk/downloads/bg-loaded/bg-loaded.js"></script>
<script type="text/javascript">
   $('body').bgLoaded({
      afterLoaded : function() {
         alert('Background image done loading');
      }
   });
</script>

这是一个Codepen演示它的工作原理。

http://codepen.io/catmull/pen/Lfcpb


3

我找到了一个对我来说效果更好的解决方案,它的优点是可以使用多个图像(本示例中未说明的情况)。

来自@adeneo对这个问题的回答:

如果您的元素带有背景图片,则像这样

<div id="test" style="background-image: url(link/to/image.png)"><div>

您可以通过获取图像URL并将其用于带有onload处理程序的javascript中的图像对象来等待背景加载

var src = $('#test').css('background-image');
var url = src.match(/\((.*?)\)/)[1].replace(/('|")/g,'');

var img = new Image();
img.onload = function() {
    alert('image loaded');
}
img.src = url;
if (img.complete) img.onload();

2

我做了一个纯JavaScript hack来使之成为可能。

<div class="my_background_image" style="background-image: url(broken-image.jpg)">
<img class="image_error" src="broken-image.jpg" onerror="this.parentElement.style.display='none';">
</div>

要么

onerror="this.parentElement.backgroundImage = "url('image_placeHolder.png')";

CSS:

.image_error {
    display: none;
}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.