Bir arka plan resminin yüklü olup olmadığını nasıl kontrol edebilirim?


154

Vücut etiketinde bir arka plan görüntüsü ayarlamak, sonra bazı kod çalıştırmak istiyorum - böyle:

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

Arka plan resminin tam olarak yüklendiğinden nasıl emin olabilirim?


4
Etkinliği Image()olan nesneye aynı URL'yi atamanız onloadyeterlidir.
Gölge Sihirbazı Sizin İçin

2
css url sarmak emin olunurl()
bluescrubbie

Yanıtlar:


274

bunu dene:

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

bu bellekte yeni bir görüntü oluşturur ve src'nin ne zaman yüklendiğini tespit etmek için load olayını kullanır.


10
Görüntü hiçbir sebep olmadan iki kez yüklenecek gibi görünüyor.
HyderA

49
@gAMBOOKa Tarayıcı belleğinde kaldıkları için bir kez yüklenir. Bu aynıdır, gizli resimleri sayfanızın üstüne koyduktan sonra CSS'ye ayarladığınızda - böylece resimler css dosyasından önce indirilmeye başlar - buna önyükleme denir.
jcubic

4
Çok emin değilim ama bence önbellekten bahsediyorsun. Varlıkların saklandığı tarayıcı belleği diye bir şey olduğunu sanmıyorum. Önbelleğe başvuruyorsanız, fazladan bir HTTP isteği eklediğinizi ve tüm istemcilerin önbelleği etkin olmayabilir.
HyderA

7
Bunu jquery: olan herhangi bir sayfaya girin 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)'); }))ve Firebug'da HTTP isteklerini kontrol edin. Bu görüntü başka bir sekmede açılmış titreşim sayfasını açtıysam, herhangi bir HTTP isteği yapmaz, sadece bu resmi anında gösterir. ve önbelleği temizlediğimde ve çalıştırdığımda bir istek vardı.
jcubic

26
Arasında bir karşılaştırma bu test ve bu bir çağrı yapmak zorunda gösterileri .remove()üzerine $('<img/>')bir bellek sızıntısı önlemek için nesnenin. İlk testte sabit bellek tüketimi ve ikincisinde bellek artışı görmelisiniz. Chrome 28'de birkaç saat çalıştıktan sonra ilk test 80MB, ikincisi 270MB alır.
benweet

23

Arka plan resimleri indirildiğinde algılayabilir denilen bir jQuery eklentisiwaitForImages var.

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

Bu eklenti, eachgeri aramayı kullanarak yükleme ilerlemesini gösterebilmek için de mükemmeldir .
Soviut

1
@alex, Bir sınıftaki her öğe için her bir arka plan resmini nasıl kontrol etmeliyim? Bunu denedim ama doğru gibi görünmüyor. $ ('. user_main_photo_thumb'). waitForImages (function () {$ (this) .parents ('. photoThumbFrame'). delay (1000) .slideDown ();}, işlev (yüklü, sayım, başarı) {});
Relm

@Relm Doğru kullanmıyorsunuz. İkinci geri arama görüntü başına yapılır. Ayrıca, delay()böyle çalışmaz.
alex

16

Bunun gibi bir şey:

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

merhaba ... bg.replace olarak ayarladığım halde bu işe yarıyor gibi görünüyor bg.replace( ... , my_src ). Ama sorum şu: $ ('<img>') yüklendikten sonra, bununla tam olarak ne oluyor <img>... Yani aslında gerçek değil - sadece kukla bir yer tutucu, değil mi?
dsdsdsdsd

Sağ. <img>DOM sokulur hiçbir zaman; sadece tarayıcıyı görüntü dosyasını önbelleğe yüklemek için "kandırmak" için kullanılır.
Colin



8

ön yükleyici ekleyecek, arka plan resmini ayarlayacak ve daha sonra olay dinleyicisi ile birlikte çöp toplama için ayarlayacak saf JS çözümü :

Kısa versiyon:

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

Hoş opaklık geçişiyle biraz daha uzun:

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
Yetersiz çözüm.
Tom Thomson

1
@TomThomson teşekkürler Tom, görüntü geçişi düzgün çalışmadı, sabit
buldum

6

İşte tam olarak bunu yapmanıza izin vermek için yaptığım küçük bir eklenti, aynı zamanda birden fazla arka plan görüntüsü ve birden fazla öğe üzerinde çalışıyor:

Makaleyi oku:

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

veya doğrudan eklenti koduna gidin:

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

Bu yüzden sadece eklentiyi ekleyin ve ardından öğeye çağırın:

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

Açıkçası eklentiyi indirin ve kendi barındırma üzerinde saklayın.

Varsayılan olarak, arka plan yüklendikten sonra eşleşen her öğeye ek bir "bg yüklü" sınıf ekler, ancak bunu aşağıdaki gibi farklı bir işlev ileterek kolayca değiştirebilirsiniz:

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

İşte çalıştığını gösteren bir kodlama.

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


3

Benim için daha iyi çalışan ve birkaç resim ile kullanılabilir olma avantajına sahip bir çözüm buldum (bu örnekte gösterilmemiştir).

@ Adeneo'nun bu soruya verdiği yanıttan :

Arka plan resmi olan bir öğeniz varsa, bunun gibi

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

Resim URL'sini alıp bir yükleyici ile javascript'te bir resim nesnesi için kullanarak arka planın yüklenmesini bekleyebilirsiniz.

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

Bunu mümkün kılmak için saf bir javascript kesmek yaptım.

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

Veya

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

css:

.image_error {
    display: none;
}

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.