Görüntünün ne zaman yüklendiğini bilmek için bir JavaScript geri çağrısı nasıl oluşturulur?


Yanıtlar:


159

.complete + geri arama

Bu, ekstra bağımlılıkları olmayan standartlara uygun bir yöntemdir ve gereğinden fazla beklemez:

var img = document.querySelector('img')

function loaded() {
  alert('loaded')
}

if (img.complete) {
  loaded()
} else {
  img.addEventListener('load', loaded)
  img.addEventListener('error', function() {
      alert('error')
  })
}

Kaynak: http://www.html5rocks.com/en/tutorials/es6/promises/


4
Görüntü img.completeçağrı ile çağrı arasında tamamlanırsa bu yanlış olabilir addEventListenermi?
Thomas Ahle

@ThomasAhle Uzman değilim, ama bu mümkün görünüyor. Bakalım kimsenin bir çözümü var mı.
Ciro Santilli 法轮功 20 病 六四 事件 法轮功

Sanırım bu sadece çoğu javascript muhtemelen değil paralel kod için bir sorun olurdu ..
Thomas Ahle

4
@ThomasAhle Bunu yapamaz, çünkü tarayıcı yalnızca olay sırası döndürüldüğünde load olayını tetikler. Dedi ki,load olay dinleyicisi olay tetiklenmeden önce gerçekleşebileceği gibi bir maddede olmalıdır , bu nedenle eğer potansiyel olarak iki kez arayamazdınız (bunun yalnızca olay yangınları). elseimg.completeloadloadedimg.complete
gsnedders

72

Image.onload () genellikle işe yarar .

Bunu kullanmak için, src niteliğini ayarlamadan önce olay işleyiciyi bağladığınızdan emin olmanız gerekir.

İlgili Bağlantılar:

Örnek Kullanım:

    window.onload = function () {

        var logo = document.getElementById('sologo');

        logo.onload = function () {
            alert ("The image has loaded!");		
        };

        setTimeout(function(){
            logo.src = 'https://edmullen.net/test/rc.jpg';         
        }, 5000);
    };
 <html>
    <head>
    <title>Image onload()</title>
    </head>
    <body>

    <img src="#" alt="This image is going to load" id="sologo"/>

    <script type="text/javascript">

    </script>
    </body>
    </html>


26
FYI: W3C spesifikasyonuna göre, onload IMG elemanları için geçerli bir olay değildir. Açıkçası tarayıcılar bunu destekliyor, ancak spesifikasyonu önemsiyorsanız ve hedeflemek istediğiniz tüm tarayıcıların% 100 emin değilseniz, bunu yeniden düşünmek veya en azından akılda tutmak isteyebilirsiniz.
Jason Bunting

3
kaynağı ayarlamak için 5 saniye beklemek neden kötü bir fikir gibi görünüyor?
quemeful

8
@quemeful bu yüzden buna "örnek" denir.
Diego Jancic

3
@JasonBunting loadEtkinliğin geçerli olmadığını düşündüren neye bakıyorsunuz ? html.spec.whatwg.org/multipage/webappapis.html#handler-onload , onload olay işleyicisinin tanımıdır .
gsnedders

4
@gsnedders - farkettim ki, bu yorumu yazdığımda, işaret ettiğinden değil, 4.5 yıldan daha yeni olan mevcut standarda atıfta bulunduğumu varsayıyorum. O zaman sorsaydın, belki de işaret edebilirdim. Web'in doğası böyle, değil mi? İşler eskimiş, taşınmış ya da değiştirilmiş vs.
Jason Bunting

20

Javascript image sınıfının .complete özelliğini kullanabilirsiniz.

Ekrana dinamik olarak eklenecek bir dizi görüntü nesnesini sakladığım bir uygulama var ve yüklenirken sayfadaki başka bir div için güncellemeler yazıyorum. İşte bir kod snippet'i:

var gAllImages = [];

function makeThumbDivs(thumbnailsBegin, thumbnailsEnd)
{
    gAllImages = [];

    for (var i = thumbnailsBegin; i < thumbnailsEnd; i++) 
    {
        var theImage = new Image();
        theImage.src = "thumbs/" + getFilename(globals.gAllPageGUIDs[i]);
        gAllImages.push(theImage);

        setTimeout('checkForAllImagesLoaded()', 5);
        window.status="Creating thumbnail "+(i+1)+" of " + thumbnailsEnd;

        // make a new div containing that image
        makeASingleThumbDiv(globals.gAllPageGUIDs[i]);
    }
}

function checkForAllImagesLoaded()
{
    for (var i = 0; i < gAllImages.length; i++) {
        if (!gAllImages[i].complete) {
            var percentage = i * 100.0 / (gAllImages.length);
            percentage = percentage.toFixed(0).toString() + ' %';

            userMessagesController.setMessage("loading... " + percentage);
            setTimeout('checkForAllImagesLoaded()', 20);
            return;
        }
    }

    userMessagesController.setMessage(globals.defaultTitle);
}

Daha önce işimde benzer kodu kullandım. Bu, tüm tarayıcılarda iyi çalışır.
Gabriel Hurley

2
Tamamlama kontrolü ile ilgili sorun, IE9 ile başlayarak OnLoad olaylarının tüm görüntüler yüklenmeden önce tetiklenmesi ve şimdi kontrol fonksiyonu için bir tetikleyici bulmak zor olmasıdır.
Gene Vincent


8

Hayat jquery için çok kısa.

function waitForImageToLoad(imageElement){
  return new Promise(resolve=>{imageElement.onload = resolve})
}

var myImage = document.getElementById('myImage');
var newImageSrc = "https://pmchollywoodlife.files.wordpress.com/2011/12/justin-bieber-bio-photo1.jpg?w=620"

myImage.src = newImageSrc;
waitForImageToLoad(myImage).then(()=>{
  // Image have loaded.
  console.log('Loaded lol')
});
<img id="myImage" src="">


1
Bu harika bir cevap ama bu kadar koda bile ihtiyacınız olduğunu düşünmüyorum. srcJS ile ekleyerek kafa karıştırıcı görünmesini sağlıyorsunuz .
Brandon Benefield

1
Zaman programlamada büyük bir kısıtlamadır. Deneyimlerimden, okunabilir (bir süre uzunken) kod yazmak büyük bir zaman avantajı sağlar.
Idan Beker

Neden src'yi yalnızca bir sonraki satırda tüketmek için yeni bir değişkene saklıyorsunuz? Eğer kısalık amacınızsa, bu bir anti-kalıptır. myImage.src = https://pmchollywoodlife.files.wordpress.com/2011/12/justin-bieber-bio-photo1.jpg?w=620hile yapar.
Josiah

3

İşte jQuery eşdeğeri:

var $img = $('img');

if ($img.length > 0 && !$img.get(0).complete) {
   $img.on('load', triggerAction);
}

function triggerAction() {
   alert('img has been loaded');
}

1

Sorunun sorulduğu 2008 için uygun değil, ancak bu günlerde bu benim için iyi çalışıyor:

async function newImageSrc(src) {
  // Get a reference to the image in whatever way suits.
  let image = document.getElementById('image-id');

  // Update the source.
  img.src = src;

  // Wait for it to load.
  await new Promise((resolve) => { image.onload = resolve; });

  // Done!
  console.log('image loaded! do something...');
}

0

bu işlevler sorunu çözecektir, DrawThumbnailsişlevi uygulamanız ve görüntüleri saklamak için küresel bir değişkeniniz olması gerekir. Bunu bir sınıf nesnesi ile çalışmak için seviyorumThumbnailImageArrayÜye değişken , ama mücadele !

olarak adlandırıldı addThumbnailImages(10);

var ThumbnailImageArray = [];

function addThumbnailImages(MaxNumberOfImages)
{
    var imgs = [];

    for (var i=1; i<MaxNumberOfImages; i++)
    {
        imgs.push(i+".jpeg");
    }

    preloadimages(imgs).done(function (images){
            var c=0;

            for(var i=0; i<images.length; i++)
            {
                if(images[i].width >0) 
                {
                    if(c != i)
                        images[c] = images[i];
                    c++;
                }
            }

            images.length = c;

            DrawThumbnails();
        });
}



function preloadimages(arr)
{
    var loadedimages=0
    var postaction=function(){}
    var arr=(typeof arr!="object")? [arr] : arr

    function imageloadpost()
    {
        loadedimages++;
        if (loadedimages==arr.length)
        {
            postaction(ThumbnailImageArray); //call postaction and pass in newimages array as parameter
        }
    };

    for (var i=0; i<arr.length; i++)
    {
        ThumbnailImageArray[i]=new Image();
        ThumbnailImageArray[i].src=arr[i];
        ThumbnailImageArray[i].onload=function(){ imageloadpost();};
        ThumbnailImageArray[i].onerror=function(){ imageloadpost();};
    }
    //return blank object with done() method    
    //remember user defined callback functions to be called when images load
    return  { done:function(f){ postaction=f || postaction } };
}

11
Tüm addThumbnailImagesfonksiyonunuz dahil, bu kodun çoğu önemsizdir . İlgili koda kadar parlat ve -1'i kaldıracağım.
Justin Morgan

0

Amaç, img, tarayıcı resmi oluşturduktan sonra biçimlendirmekse:

const img = new Image();
img.src = 'path/to/img.jpg';

img.decode().then(() => {
/* set styles */
/* add img to DOM */ 
});

çünkü önce tarayıcı loads the compressed version of image, sonra decodes itnihayet paints. painttarayıcı decodedimg etiketine sahip olduktan sonra mantığınızı çalıştırmanız için herhangi bir etkinlik olmadığından .


-2

React.js kullanıyorsanız, bunu yapabilirsiniz:

render() {

// ...

<img 
onLoad={() => this.onImgLoad({ item })}
onError={() => this.onImgLoad({ item })}

src={item.src} key={item.key}
ref={item.key} />

// ...}

Nerede:

  • - onLoad (...) şimdi şöyle bir şeyle çağrılır: {src: " https: //......png ", anahtar: "1"} hangi görüntüleri bilmek için bunu "anahtar" olarak kullanabilirsiniz doğru yüklendi ve yüklenmedi.
  • - onError (...) aynı ama hatalar için.
  • - "öğe" nesnesi şöyle bir şeydir {anahtar: "..", src: ".."} görüntülerin URL'sini ve anahtarını görüntüler listesinde kullanmak için kullanabilirsiniz.

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