Come posso verificare se un'immagine di sfondo è caricata?


154

Voglio impostare un'immagine di sfondo sul tag body, quindi eseguire un po 'di codice - in questo modo:

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

Come posso assicurarmi che l'immagine di sfondo sia completamente caricata?


4
Basta assegnare lo stesso URL Image()all'oggetto che ha un onloadevento.
Shadow Wizard is Ear For You,

2
assicurati di racchiudere l'URL CSSurl()
bluescrubbie il

Risposte:


274

prova questo:

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

questo creerà una nuova immagine in memoria e utilizzerà l'evento load per rilevare quando viene caricato l'src.


10
Sembra che l'immagine verrebbe caricata due volte senza motivo.
HyderA,

49
@gAMBOOKa Vengono caricati una volta perché rimangono nella memoria del browser. Questo è lo stesso, quando metti le immagini nascoste in cima alla tua pagina e poi le imposti in CSS - quindi le immagini iniziano a scaricarsi prima del file css - si chiama precaricamento.
jcubic,

4
Non sono troppo sicuro, ma penso che ti riferisci alla cache. Non penso che ci sia qualcosa come la memoria del browser in cui sono archiviate le risorse. Se ti riferisci alla cache, ricorda che stai aggiungendo una richiesta HTTP aggiuntiva e che tutti i client potrebbero non avere la cache abilitata.
HyderA,

7
Inseriscilo in qualsiasi pagina che abbia 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)'); }))e controlla le richieste HTTP in Firebug. Se ho aperto la pagina dello sfarfallio con questa immagine aperta in un'altra scheda non fa alcuna richiesta HTTP ma mostra immediatamente questa immagine. e quando svuoto la cache ed eseguo c'era una richiesta.
jcubic,

26
Un confronto tra questo test e questo mostra che è necessario chiamare .remove()l' $('<img/>')oggetto per evitare una perdita di memoria. Dovresti vedere un consumo di memoria stabile nel primo test e un aumento della memoria nel secondo. Dopo alcune ore di esecuzione su Chrome 28, il primo test richiede 80 MB e il secondo 270 MB.
benweet,

23

Ho un plug-in jQuery chiamato in waitForImagesgrado di rilevare quando le immagini di sfondo sono state scaricate.

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

Questo plugin è ottimo anche per poter mostrare l'avanzamento del caricamento usando il eachcallback.
Soviet

1
@alex, come devo controllare ogni immagine di sfondo per ogni elemento in una classe? Ho provato questo ma non sembra farlo bene. $ ('. user_main_photo_thumb'). waitForImages (function () {$ (this) .parents ('. photoThumbFrame'). delay (1000) .slideDown ();}, funzione (caricato, conteggio, successo) {});
Relm

@Relm Non lo stai usando correttamente. Il secondo callback è per immagine. Inoltre, delay()non funziona così.
alex

16

Qualcosa come questo:

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

ciao ... sembra funzionare, anche se ho impostato bg.replace su bg.replace( ... , my_src ). Ma la mia domanda è: una volta caricato $ ('<img>'), cosa succede esattamente con quello <img>... Voglio dire, non è proprio reale - è solo un segnaposto fittizio, giusto?
dsdsdsdsd,

Destra. Il <img>non viene mai inserito nel DOM; è solo usato per "ingannare" il browser nel caricamento del file immagine nella cache.
Colin,

utile se non vuoi invocare jQuery
vwvan il


8

soluzione JS pura che aggiungerà il precaricatore, imposta l'immagine di sfondo e quindi la configura per la garbage collection insieme al suo listener di eventi :

Versione breve:

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

Un po 'più a lungo con una piacevole transizione all'opacità:

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
Soluzione sottovalutata.
Tom Thomson,

1
@TomThomson grazie Tom, ho scoperto che la transizione dell'immagine non ha funzionato correttamente, risolto
godblessstrawberry

6

Ecco un piccolo plugin che ho creato per permetterti di fare esattamente questo, funziona anche su più immagini di sfondo e più elementi:

Leggi l'articolo:

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

o vai direttamente al codice del plugin:

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

Quindi basta includere il plug-in e quindi chiamarlo sull'elemento:

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

Ovviamente scarica il plugin e memorizzalo sul tuo hosting.

Per impostazione predefinita, aggiunge una classe "caricata da bg" aggiuntiva a ciascun elemento corrispondente una volta caricato lo sfondo, ma puoi facilmente cambiarlo passando una funzione diversa come questa:

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

Ecco un codice che lo dimostra funzionare.

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


3

Ho trovato una soluzione che ha funzionato meglio per me e che ha il vantaggio di essere utilizzabile con diverse immagini (caso non illustrato in questo esempio).

Dalla risposta di @adeneo su questa domanda :

Se hai un elemento con un'immagine di sfondo, in questo modo

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

Puoi attendere il caricamento dello sfondo ottenendo l'URL dell'immagine e utilizzandolo per un oggetto immagine in javascript con un gestore onload

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

Ho fatto un puro hack javascript per renderlo possibile.

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

O

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

css:

.image_error {
    display: none;
}

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.