JS / Как показать блок, только когда картинка из CSS загрузилась?

Задача следующая - Есть некий блок обертка, внутри которого находиться div(с анимацией) большого размера. Вопрос - Как отследить что картинка которая задается через backgroud-image уже полностью загрузилась. И уже после этого показать этот блок?

Попробую сделать простой пример:

body {
  margin: 0;
}

.wrapper {
  display: none;
  padding: 10px;
  border: 1px solid #000;
}

.wrapper.active {
  display: block;
}

.myAnimation {
  display: inline-block;
  width: 200px;
  height: 300px;
  background: url("https://www.placecage.com/gif/200/300") 50% 50% no-repeat;
}

p {
  display: inline-block;
  width: 150px;
  vertical-align: top;
}
<div class="wrapper">
  <div class="myAnimation"></div>
  <p>Если ты это читаешь, значит большая картинка загрузилась</p>
</div>

Как узнать что картинка готова к показу, и можно, для блока .wrapper добавить класс .active . Но не раньше ? ПС В интернете есть довольно много примеров, как данная задача решается, если картинка б задавалась в теге img. (событие .onload) Но вот как быть если она CSS background-image ? (Реальная картинка порядка 20-30mB)


Ответы (1 шт):

Автор решения: OPTIMUS PRIME

Можно создать картинку через конструктор new Image(), скопировать туда адрес картинки и поймать его onload. Это не одно и то же, что поймать загрузку именно background-image, но гарантирует, что последний точно будет загружен перед выполнением функции.

awaitBgImgLoad();

function awaitBgImgLoad() {
  var div = document.querySelector('.myAnimation');
  var src = window.getComputedStyle(div).backgroundImage;
  console.log(src); // адрес хранится в виде `url("src")` — надо удалить лишние символы
  
  src = src.replace(/url\(|\)|"/g,"")
  loadAndRun(src, onload);
  
  /***/
  
  function onload() {
    console.log("Я загрузился!");
    document.querySelector('.wrapper').style.display = "block";
  }
}

/*****/

function loadAndRun(src, resolve, reject) {
  var img = new Image();
  img.onload = resolve;
  img.onerror = reject || function(){
    console.log("Не загрузилась " + src)
  };
  img.src = src;
}
body {
  margin: 0;
}

.wrapper {
  display: none;
  padding: 10px;
  border: 1px solid #000;
}

.wrapper.active {
  display: block;
}

.myAnimation {
  display: inline-block;
  width: 247px;
  height: 187px;
  background: url("https://gyazo.com/f5d013014306342a2241f8d3b8fb11ea.png") 50% 50% no-repeat;
}

p {
  display: inline-block;
  width: 150px;
  vertical-align: top;
}
<div class="wrapper">
  <div class="myAnimation"></div>
  <p>Я загрузился!</p>
</div>

→ Ссылка