Як я можу перевірити, чи завантажено фонове зображення?


154

Я хочу встановити фонове зображення на тезі тіла, а потім запустити якийсь код - наприклад:

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

Як я можу переконатися, що фонове зображення завантажено повністю?


4
Просто призначте ту саму URL-адресу Image()об’єкту, який має onloadподію.
Shadow Wizard is Ear for You

2
переконайтеся, що url()
вставте

Відповіді:


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

це створить нове зображення в пам'яті та використовуватиме подія завантаження для виявлення, коли src завантажений.


10
Здається, що зображення буде завантажено двічі без жодної причини.
HyderA

49
@gAMBOOKa Вони завантажуються один раз, оскільки вони залишаються в пам'яті браузера. Це те саме, коли ви поміщаєте приховані зображення вгорі сторінки, а потім встановлюєте їх у CSS - тому зображення починають завантажуватись до файлу css - це називається попередньою завантаженням.
jcubic

4
Я не надто впевнений, але я думаю, що ви маєте на увазі кеш. Я не думаю, що існує така річ, як пам’ять браузера, де зберігаються активи. Якщо ви маєте на увазі кеш, пам’ятайте, що ви додаєте додатковий запит HTTP, і, можливо, для всіх клієнтів не ввімкнено кеш.
HyderA

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)'); }))і перевірте HTTP-запити в Firebug. Якщо я відкрив мерехтіння сторінки з цим зображенням, відкритим на іншій вкладці, він не робить жодних HTTP-запитів, просто показуйте це зображення миттєво. і коли я очищаю кеш і запускаю його, був один запит.
jcubic

26
Порівняння цього тесту і цього показує, що вам потрібно зателефонувати .remove()на $('<img/>')об'єкт, щоб уникнути витоку пам'яті. Ви повинні побачити стабільне споживання пам'яті на першому тесті та збільшення пам'яті на другому. Після кількох годин роботи на Chrome 28, перший тест займає 80 МБ, а другий - 270 МБ.
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зворотного дзвінка.
Радянський

1
@alex, Як я повинен перевірити кожне фонове зображення для кожного елемента в класі? Я спробував це, але, здається, це не правильно. $ ('. user_main_photo_thumb'). waitForImages (function () {$ (this) .parents ('. photoThumbFrame'). затримка (1000) .slideDown ();}, функція (завантажено, рахувати, успіх) {});
Рельм

@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

Правильно. The <img>ніколи не вставляється в DOM; він просто використовується для того, щоб "обдурити" браузер для завантаження файлу зображення в кеш.
Колін

корисно, якщо ви не хочете посилатися на jQuery
vwvan


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 дякую Томе, я виявив, що перехід зображення не працює належним чином, виправив його
godblessstrawberry

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" до кожного відповідного елемента після завантаження фону, але ви можете легко змінити це, передавши йому іншу функцію, як це:

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

Ось кодекс, що демонструє його роботу.

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


3

Я знайшов рішення, яке працювало краще для мене, і яке має перевагу у використанні декількох зображень (випадок не проілюстрований у цьому прикладі).

З відповіді @ adeneo на це запитання :

Якщо у вас є елемент із фоновим зображенням, як це

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

Ви можете зачекати, коли фон завантажиться, отримавши URL-адресу зображення та використовуючи його для об’єкта зображення у 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, щоб зробити це можливим.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.