Wie kann ich überprüfen, ob ein Hintergrundbild geladen ist?


154

Ich möchte ein Hintergrundbild für das Body-Tag festlegen und dann einen Code ausführen - wie folgt:

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

Wie kann ich sicherstellen, dass das Hintergrundbild vollständig geladen ist?


4
Weisen Sie dem Image()Objekt, das ein onloadEreignis hat, einfach dieselbe URL zu .
Schatten-Assistent ist Ohr für Sie

2
url()
Stellen Sie

Antworten:


274

Versuche dies:

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

Dadurch wird ein neues Image im Speicher erstellt und mithilfe des Ladeereignisses erkannt, wann der Quellcode geladen wird.


10
Scheint, als würde das Bild ohne Grund zweimal geladen.
HyderA

49
@gAMBOOKa Sie werden einmal geladen, weil sie im Browserspeicher bleiben. Dies ist auch dann der Fall, wenn Sie versteckte Bilder oben auf Ihrer Seite platzieren und dann in CSS festlegen. Die Bilder werden also vor der CSS-Datei heruntergeladen. Dies wird als Vorladen bezeichnet.
Jcubic

4
Ich bin mir nicht sicher, aber ich denke, Sie beziehen sich auf den Cache. Ich glaube nicht, dass es so etwas wie einen Browserspeicher gibt, in dem Assets gespeichert sind. Wenn Sie sich auf den Cache beziehen, denken Sie daran, dass Sie eine zusätzliche HTTP-Anforderung hinzufügen und möglicherweise nicht für alle Clients der Cache aktiviert ist.
HyderA

7
Geben Sie dies auf jeder Seite mit jquery: ein 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)'); }))und überprüfen Sie die HTTP-Anforderungen in Firebug. Wenn ich eine Flimmern-Seite mit diesem Bild geöffnet habe, das in einem anderen Tab geöffnet wurde, werden keine HTTP-Anforderungen ausgeführt. Dieses Bild wird nur sofort angezeigt. und als ich den Cache löschte und ausführte, gab es eine Anfrage.
Jcubic

26
Ein Vergleich zwischen diesem Test und diese hier zeigt , dass Sie anrufen müssen .remove()auf $('<img/>')Objekt einen Speicherverlust zu vermeiden. Sie sollten beim ersten Test einen stabilen Speicherverbrauch und beim zweiten einen Speicheranstieg feststellen. Nach einigen Stunden auf Chrome 28 dauert der erste Test 80 MB und der zweite 270 MB.
Benweet

23

Ich habe ein jQuery-Plugin namens waitForImages, das erkennen kann, wann Hintergrundbilder heruntergeladen wurden.

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

Dieses Plugin eignet sich auch hervorragend, um den Ladevorgang mithilfe des eachRückrufs anzuzeigen.
Soviut

1
@alex, Wie soll ich jedes Hintergrundbild für jedes Element in einer Klasse überprüfen? Ich habe es versucht, aber es scheint nicht richtig zu sein. $ ('. user_main_photo_thumb'). waitForImages (function () {$ (this) .parents ('. photoThumbFrame'). delay (1000) .slideDown ();}, function (geladen, count, success) {});
Relm

@Relm Du benutzt es nicht richtig. Der zweite Rückruf erfolgt pro Bild. Funktioniert auch delay()nicht so.
Alex

16

Etwas wie das:

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

hallo ... das scheint zu funktionieren, obwohl ich den bg.replace auf gesetzt habe bg.replace( ... , my_src ). Aber meine Frage ist: Sobald das $ ('<img>') geladen ist, was genau passiert damit <img>... Ich meine, es ist nicht wirklich real - es ist nur ein Dummy-Platzhalter, oder?
dsdsdsdsd

Richtig. Das <img>wird niemals in das DOM eingefügt. Es wird nur verwendet, um den Browser zum Laden der Bilddatei in den Cache zu "täuschen".
Colin

hilfreich, wenn Sie jQuery nicht aufrufen möchten
vwvan


8

reine JS-Lösung, die Preloader hinzufügt, das Hintergrundbild festlegt und es dann zusammen mit dem Ereignis-Listener für die Garbage Collection einrichtet :

Kurzfassung:

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

Ein bisschen länger mit schönem Deckkraftübergang:

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
Unterschätzte Lösung.
Tom Thomson

1
@ TomThomson danke Tom, ich fand, dass der Bildübergang nicht richtig funktionierte, behoben
godblessstrawberry

6

Hier ist ein kleines Plugin, das ich erstellt habe, damit Sie genau dies tun können. Es funktioniert auch mit mehreren Hintergrundbildern und mehreren Elementen:

Lesen Sie den Artikel:

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

oder gehen Sie direkt zum Plugin-Code:

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

Fügen Sie einfach das Plugin hinzu und rufen Sie es dann für das Element auf:

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

Laden Sie das Plugin herunter und speichern Sie es auf Ihrem eigenen Hosting.

Standardmäßig wird jedem übereinstimmenden Element eine zusätzliche "bg-geladene" Klasse hinzugefügt, sobald der Hintergrund geladen ist. Sie können dies jedoch leicht ändern, indem Sie ihm eine andere Funktion wie die folgende übergeben:

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

Hier ist ein Codepen, der die Funktionsweise demonstriert.

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


3

Ich habe eine Lösung gefunden, die für mich besser funktioniert und die den Vorteil hat, dass sie mit mehreren Bildern verwendet werden kann (Fall in diesem Beispiel nicht dargestellt).

Aus der Antwort von @ adeneo auf diese Frage :

Wenn Sie ein Element mit einem Hintergrundbild haben, wie dieses

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

Sie können warten, bis der Hintergrund geladen ist, indem Sie die Bild-URL abrufen und sie mit einem Onload-Handler für ein Bildobjekt in Javascript verwenden

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

Ich habe einen reinen Javascript-Hack durchgeführt, um dies zu ermöglichen.

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

Oder

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

CSS:

.image_error {
    display: none;
}

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.