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

IT技术 javascript jquery
2021-01-13 01:40:11

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

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

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

6个回答

试试这个:

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

编辑:在 Vanilla JavaScript 中,它看起来像这样:

var src = 'http://picture.de/image.png';
var image = new Image();
image.addEventListener('load', function() {
   body.style.backgroundImage = 'url(' + src + ')';
});
image.src = src;

它可以抽象为返回Promise的方便函数:

function load(src) {
    return new Promise((resolve, reject) => {
        const image = new Image();
        image.addEventListener('load', resolve);
        image.addEventListener('error', reject);
        image.src = src;
    });
}

const image = 'http://placekitten.com/200/300';
load(image).then(() => {
   body.style.backgroundImage = `url(${image})`;
});
似乎图像会无缘无故地加载两次。
2021-03-21 01:40:11
@gAMBOOKa 它们被加载一次,因为它们留在浏览器内存中。这是相同的,当您将隐藏图像放在页面顶部,然后在 CSS 中设置它时——因此图像在 css 文件之前开始下载——这称为预加载。
2021-04-03 01:40:11
我不太确定,但我认为您指的是缓存。我认为没有像浏览器内存这样的东西来存储资产。如果您指的是缓存,请记住您正在添加一个额外的 HTTP 请求,并且所有客户端可能都没有启用缓存。
2021-04-06 01:40:11
之间的比较这个测试这一个节目,你要调用 .remove()$('<img/>')对象以避免内存泄漏。您应该在第一个测试中看到稳定的内存消耗,在第二个测试中看到内存增加。在 Chrome 28 上运行几个小时后,第一个测试需要 80MB,第二个需要 270MB。
2021-04-06 01:40:11
在任何具有 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 请求,只会立即显示此图片。当我清除缓存并运行它时,有一个请求。
2021-04-10 01:40:11

我有一个名为jQuery 插件waitForImages,它可以检测背景图像何时下载。

$('body')
  .css('background-image','url(http://picture.de/image.png)')
  .waitForImages(function() {
    alert('Background image done loading');
    // This *does* work
  }, $.noop, true);
@alex,我应该如何检查类中每个元素的每个背景图像?我试过这个,但似乎做得不对。$('.user_main_photo_thumb').waitForImages(function() { $(this).parents('.photoThumbFrame').delay(1000).slideDown(); }, function(loaded, count, success) { });
2021-03-18 01:40:11
这个插件也非常适合能够使用each回调显示加载进度
2021-03-20 01:40:11
@Relm 你没有正确使用它。第二个回调是每个图像。此外,delay()也不能那样工作。
2021-04-05 01:40:11

CSS 资产没有 JS 回调。

感谢您的快速答复。有关变通解决方案的任何想法?
2021-03-14 01:40:11
但是对于那些正在寻找stackoverflow.com/questions/5057990/...
2021-03-23 01:40:11

像这样的东西:

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();
      });
  }
});
对。<img>永远不会插入到DOM; 它只是用来“欺骗”浏览器将图像文件加载到缓存中。
2021-03-25 01:40:11
如果您不想调用 jQuery,则很有帮助
2021-03-27 01:40:11
你好......这似乎有效,虽然我将 bg.replace 设置为bg.replace( ... , my_src ). 但我的问题是:一旦 $('<img>') 加载,究竟会发生什么<img>......我的意思是它实际上不是真的 - 它只是一个虚拟的占位符,对吧?
2021-04-02 01:40:11

纯 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>

@bytangle 这将增加很少需要的加载优先级
2021-03-16 01:40:11
@TomThomson 感谢 Tom,我发现图像转换无法正常工作,已修复
2021-03-22 01:40:11
有趣的解决方案。你怎么看使用<link>标签预加载:<link rel="preload" href=cat.jpg as=image imagesrcset="cat.jpg 1x, cat-2x.jpg 2x">
2021-03-22 01:40:11
被低估的解决方案。
2021-04-05 01:40:11
这是一个很好的答案。
2021-04-07 01:40:11