2010-09-05 10 views
159

Können Sie mir sagen, ob die Funktion, die ich unten geschrieben habe, ausreicht, um Bilder in den meisten, wenn nicht allen heute üblichen Browsern zu laden?JavaScript Bilder vorladen

function preloadImage(url) 
{ 
    var img=new Image(); 
    img.src=url; 
} 

Ich habe eine Reihe von imageURLs dass I Schleife und rufen die preloadImage Funktion für jede URL.

+9

Beachten Sie, dass einige (alle?) Browser das Bild nach einigen Sekunden loslassen, wenn Sie es nicht benutzt haben. Um dies zu vermeiden, behalten Sie einen Verweis auf das Objekt 'img', z. in einem Array im übergeordneten Bereich. – Tamlyn

+1

Was meinst du mit "Bild freilassen"? Wenn es vom Browser zwischengespeichert wurde, wird es dort bleiben, oder? – Francisc

+2

Es wird im Cache zwischengespeichert, aber nicht im RAM und manchmal ist die Festplatte zu langsam (z. B. Animation einer Sequenz). – Tamlyn

Antwort

82

Ja. Dies sollte in allen gängigen Browsern funktionieren.

18

CSS2 Alternative: http://www.thecssninja.com/css/even-better-image-preloading-with-css2

body:after { 
    content: url(img01.jpg) url(img02.jpg) url(img03.jpg); 
    display: none; 
} 

CSS3 Alternative: https://perishablepress.com/preload-images-css3/ (H/T Linh Dam)

.preload-images { 
    display: none; 
    width: 0; 
    height: 0; 
    background: url(img01.jpg), 
       url(img02.jpg), 
       url(img03.jpg); 
} 

HINWEIS: Bilder in einem Behälter mit display:none möglicherweise nicht vorzuladen. Vielleicht Sichtbarkeit: versteckt wird besser funktionieren, aber ich habe das nicht getestet. Danke Marco Del Valle für den Hinweis darauf

+0

Danke mplungjan. Obwohl es mir in diesem speziellen Fall nicht hilft, ist es gut zu wissen. – Francisc

+4

Habe ich Recht damit, dass das Laden der Seite verlangsamt wird, weil diese Bilder heruntergeladen werden müssen, bevor die Seite das Loadereignis starten kann? – Jakub

+0

Möglicherweise. Warum nicht versuchen? – mplungjan

9

Dieser Ansatz ist ein wenig aufwendiger. Hier speichern Sie alle vorgeladenen Bilder in einem Container, eventuell ein div. Und nachdem Sie die Bilder zeigen oder verschieben Sie sie innerhalb des DOM an die richtige Position.

function preloadImg(containerId, imgUrl, imageId) { 
    var i = document.createElement('img'); // or new Image() 
    i.id = imageId; 
    i.onload = function() { 
     var container = document.getElementById(containerId); 
     container.appendChild(this); 
    }; 
    i.src = imgUrl; 
} 

Try it here, ich habe auch einige Kommentare

+1

Downvotes sollten kommentiert werden – freedev

+0

Bitte, bitte, ich sorge mich wirklich um meine Antwort.Bitte kommentieren Sie Ihre Stimmen unten, um mich meine Antwort zu verbessern. – freedev

+0

Ich denke, dass die Downvotes sind, weil Sie Zugriff auf die Dom, wenn die Funktion aufgerufen wird, die problematisch sein könnte, wenn Sie eine andere Funktion Zugriff auf die Dom, um das Element gleichzeitig zu suchen – Programmer

10

empfehle ich Ihnen einen try/catch verwenden, um einige mögliche Probleme zu vermeiden:

OOP:

var preloadImage = function (url) { 
     try { 
      var _img = new Image(); 
      _img.src = url; 
     } catch (e) { } 
    } 

Standard:

function preloadImage (url) { 
     try { 
      var _img = new Image(); 
      _img.src = url; 
     } catch (e) { } 
    } 

Auch wenn ich DOM liebe, können alte dumme Browser Probleme mit DOM haben, also vermeide es IMHO im Gegensatz zu Freedevs Beitrag. Image() hat bessere Unterstützung in alten Papierkorb-Browsern.

+7

Ich glaube nicht, dass Sie so Fehler beim Laden von Image in Javascript finden - es gibt etwas wie _img.onerror, das (sollte?) Verwendet werden kann. – Greg0ry

+1

Was sind "mögliche Probleme"? – Kissaki

+0

Probleme wie Unterstützung für den Befehl. Auf der Website "can i use" können Sie nachsehen, ob ein Browser, den Sie unterstützen müssen, Unterstützung für einen JavaScript-Befehl bietet. – Dave

30

Versuchen Sie dies, ich denke, das ist besser.

var images = []; 
function preload() { 
    for (var i = 0; i < arguments.length; i++) { 
     images[i] = new Image(); 
     images[i].src = preload.arguments[i]; 
    } 
} 

//-- usage --// 
preload(
    "http://domain.tld/gallery/image-001.jpg", 
    "http://domain.tld/gallery/image-002.jpg", 
    "http://domain.tld/gallery/image-003.jpg" 
) 

Quelle: http://perishablepress.com/3-ways-preload-images-css-javascript-ajax/

+1

ordentlich und ordentlich! – JackDev

+3

es gibt keinen 'Onload'-Handler für eines der Bilder – Benny

+1

Können Sie erklären, warum das besser ist? – JJJ

3

Ja, das wird funktionieren, jedoch Browser Grenze (zwischen 4-8) den tatsächlichen Anrufe und somit nicht cache/vorzuladen alle gewünschten Bilder.

Ein besserer Weg, dies zu tun ist onload aufrufen, bevor das Bild wie so mit:

function (imageUrls, index) { 
    var img = new Image(); 

    img.onload = function() { 
     console.log('isCached: ' + isCached(imageUrls[index])); 
     *DoSomething..* 

    img.src = imageUrls[index] 
} 

function isCached(imgUrl) { 
    var img = new Image(); 
    img.src = imgUrl; 
    return img.complete || (img .width + img .height) > 0; 
} 
+0

Kannst du bitte eine Referenz über dieses Browserlimit verlinken? – nulll

+0

Es ist schwer eine Referenz zu finden (zumindest habe ich nie eine gefunden), aber Ich habe mein eigenes Projekt verwendet, um dies zu testen, während ich genau untersucht habe, was von Cache- und Serveranrufen über den Chrome-Tab "Netzwerk" in den Chrome-Entwicklertools (f12) geladen wurde. Ich habe das gleiche Verhalten in Firefox und mit Handy gefunden. – Robin

7

In meinem Fall war es sinnvoll, einen Rückruf an Ihre Funktion für onload Ereignis hinzuzufügen:

function preloadImage(url, callback) 
{ 
    var img=new Image(); 
    img.src=url; 
    img.onload = callback; 
} 

Und es dann wickeln für Fall einer Anordnung von Urls Bilder mit Rückruf werden vorinstalliert alles getan ist: https://jsfiddle.net/4r0Luoy7/

function preloadImages(urls, allImagesLoadedCallback){ 
    var loadedCounter = 0; 
    var toBeLoadedNumber = urls.length; 
    urls.forEach(function(url){ 
    preloadImage(url, function(){ 
     loadedCounter++; 
      console.log('Number of loaded images: ' + loadedCounter); 
     if(loadedCounter == toBeLoadedNumber){ 
     allImagesLoadedCallback(); 
     } 
    }); 
    }); 
    function preloadImage(url, anImageLoadedCallback){ 
     var img = new Image(); 
     img.src = url; 
     img.onload = anImageLoadedCallback; 
    } 
} 

// Let's call it: 
preloadImages([ 
    '//upload.wikimedia.org/wikipedia/commons/d/da/Internet2.jpg', 
    '//www.csee.umbc.edu/wp-content/uploads/2011/08/www.jpg' 
], function(){ 
    console.log('All images were loaded'); 
}); 
01 Hier
1

ist mein Ansatz:

var preloadImages = function (srcs, imgs, callback) { 
    var img; 
    var remaining = srcs.length; 
    for (var i = 0; i < srcs.length; i++) { 
     img = new Image; 
     img.onload = function() { 
      --remaining; 
      if (remaining <= 0) { 
       callback(); 
      } 
     }; 
     img.src = srcs[i]; 
     imgs.push(img); 
    } 
};