2013-02-06 10 views
5

Pracuję nad kodem, który będzie ładował sekwencję (20+) dużych obrazów (~ 500 KB każdy). Po załadowaniu każdego obrazu następuje jego zanik. Jako punkt wyjścia użyłem this fiddle z this discussion.Używanie jQuery do sekwencyjnego wczytania i zanikania elementów

Mam ładowanie obrazów tak, jak chcę, ale muszę zrobić kilka innych rzeczy bez przerywania tego sekwencyjnego ładowania. Potrzebuję załadować znacznik zawierający element iframe między trzecim a czwartym obrazem i muszę załadować łącze po obrazach. Oto przykład wyjścia znaczników muszę:

<div id="container"> 
    <img src="img-1.jpg" /> 
    <img src="img-2.jpg" /> 
    <img src="img-3.jpg" /> 
    <div><iframe></iframe></div> 
    <img src="img-4.jpg" /> 
    <img src="img-5.jpg" /> 
    <img src="img-6.jpg" /> 
    <img src="img-7.jpg" /> 
    <img src="img-8.jpg" /> 
    <img src="img-9.jpg" /> 
    <a href="/link/">Link text</a> 
</div> 

mogę załadować zdjęcia po prostu w porządku, ale jestem zakleszczony z jak załadować IFRAME dopiero pierwsze trzy zostały załadowane, a wtedy reszta obrazy ładują, a następnie link. Oto mój obecny javascript:

var no = 22, 
main = [], 
i; 

for (i = 1; i <= no; i++) { 
    main[i] = "path/to/image/folder/img-" + i + ".jpg"; 
} 

function loadImages(arr,loc) { 
if (arr.length === 0) { 
    return; 
} 

function imageLoaded(img) { 
$(img).hide().appendTo(loc).fadeIn(800); 
} 

function loadImage() { 
    var url = arr.shift(), 
    img = new Image(), 
    timer; 

    img.src = url; 

    if (img.complete || img.readyState === 4) { 
     imageLoaded(img); 
     if (arr.length !== 0) { 
      loadImage(); 
     } 
    } 
    else { 
     timer = setTimeout(function() { 
      if (arr.length !== 0) { 
       loadImage(); 
      } 
      $(img).unbind("error load onreadystate"); 
     }, 10000); 
     $(img).bind("error load onreadystatechange", function(e) { 
      clearTimeout(timer); 
      if (e.type !== "error") { 
       imageLoaded(img); 
      } 
      if (arr.length !== 0) { 
       loadImage(); 
      } 
     }); 
    } 
} 
    loadImage(); 
} 

loadImages(main,"#container"); 

„nie” zmienna ustawia liczbę zdjęć, aby przejść przez (muszę to zrobić na wielu stronach z różnych numerów obrazów), a funkcja loadImages trwa argumentów, dla których tablica do przełączania i gdzie umieścić obrazy. Ten kod prawdopodobnie byłby dużo czystszy, ale ja jestem nowy w javascript. Każda pomoc będzie bardzo ceniona!

Odpowiedz

0

możliwym rozwiązaniem byłoby odpytywać długość załadowanych zdjęć w każdym wywołaniu funkcji LoadImage jak tak

loadImage(){ 
//stuff 
if($('#container img').length == 4){ 
    insertIframeMarkup(); 
} 

//other stuff 

} 
+0

Doskonale nadaje się do wstawiania elementu iframe dokładnie tam, gdzie go potrzebuję. Nie mogę jednak załadować linka na końcu. Oto, jak wstawiam element iframe: 'if ($ (" # container img ") length == 3) { $ (" # container img: last-child ") after ("

"); ' Dla łącza na końcu, próbowałem wstawić ten wewnętrzny loadImages: ' if (arr.length === 0) { linkMarkup(); return; } ' i to wewnątrz loadImage: ' if ($ ("# container img"). Length == 22) { linkMarkup(); } ' Druga będzie działać dla obrazu od drugiego do ostatniego, ale nie ostatniego. –

+0

Mam to teraz. To był brakujący element. Dziękuję wszystkim. –

0

Here is an example of how i did it

To jest trochę inny niż swoim podejściu, ale myślę, że dać wynik, czego szukasz.

var imgArr = ['http://healthystartups.com/storage/600px-MA_Route_1.png?__SQUARESPACE_CACHEVERSION=1319542839834', 'http://upload.wikimedia.org/wikipedia/commons/thumb/5/54/MA_Route_2.svg/600px-MA_Route_2.svg.png', 'http://foo.com/foo_873.jpg', 'http://3.bp.blogspot.com/-Q_owQUxNjdQ/Te3ALCmT3oI/AAAAAAAAAnk/wv9r0b0MT-g/s1600/600px-MA_Route_3.svg_.jpg', 'http://honestreviewscorner.com/wp-content/uploads/2012/10/the-number-4-in-a-circle.jpg1.png', 'http://www.thefrugalette.com/wp-content/uploads/2011/09/number-5.png']; 

var count = 0; 

function LoadImages(images) { 
    img = images[count]; 
    img = new Image(); 
    img.src = images[count]; 

    //Between 3 and 4 
    if(count == 4) 
    { 
     $('<iframe src="http://www.w3schools.com"></iframe>').appendTo('body'); 
    } 


    if (img.complete || img.readyState === 4) { 
     $(img).hide().appendTo('body').fadeIn(function() { 
      count++; 
      if (count < images.length) LoadImages(images); 
      else $('body').append('<div>last line</div>') 
     }) 

    } else { 
     count++; 
     LoadImages(images) 
    } 

} 
LoadImages(imgArr); 
+0

Podoba mi się to ze względu na jego prostotę, ale otrzymuję rozmiar stosu wywołań przekroczony, gdy LoadImages (obrazy) jest wywoływana w instrukcji else. Jakieś pomysły? –

0

Oto working fiddle. Kod następująco:

var imgArr = ['http://healthystartups.com/storage/600px-MA_Route_1.png?__SQUARESPACE_CACHEVERSION=1319542839834', 
    'http://upload.wikimedia.org/wikipedia/commons/thumb/5/54/MA_Route_2.svg/600px-MA_Route_2.svg.png', 
    'http://1.bp.blogspot.com/-jiW5NeKtZBY/T-nyLRuSSZI/AAAAAAAACaA/Ro8wjmk32ow/s1600/red-number-8.jpg', 
    'http://3.bp.blogspot.com/-Q_owQUxNjdQ/Te3ALCmT3oI/AAAAAAAAAnk/wv9r0b0MT-g/s1600/600px-MA_Route_3.svg_.jpg', 
    'http://us.123rf.com/400wm/400/400/zoomzoom/zoomzoom1102/zoomzoom110200070/8913747-4--created-by-light-colorful-digits-over-black-background.jpg', 
    'https://twimg0-a.akamaihd.net/profile_images/1633986906/6digits-fist-Logo.png'], 
    images=[imgArr.length], 
    otherUrls = {}, urlTypes = { 
     IFRAME: 0, 
     LINK: 1 
    }; 

//INITIALIZE OTHER URLS WITH URL AND INDEX AT WHICH IT WOULD BE LOADED 
    function createInfo(url, type, text) { 
     var o = {}; 
     o.URL = url; 
     o.Type = type; 
     o.Text = text; 
     return o; 
    } 
otherUrls[2] = createInfo("http://http://en.wikipedia.org/wiki/Punjabi_language", urlTypes.IFRAME); 
otherUrls[4] = createInfo("http://http://en.wikipedia.org/wiki/Numerical_digit", urlTypes.LINK, "click here [wikipedia]"); 

function loadImages(arr,loc,other){ 
    var l=arr.length,i=0, url, idx, o; 
    while(arr.length){ 
     url=arr.shift(), 
     idx=(l-arr.length)-1, 
     o=other[idx]; 

     makeImage(url,idx,loc,o); 
    } 
} 

function makeImage(url, idx, loc, other){ 
    var image=new Image(); 
    image.src = url; 
    images[idx]=image; 
    image.onload=function(){ 
      imageLoaded(idx, loc, other); 
     }; 
    image.onerror=function(){ 
      var ix=idx,ot=other,lc=loc; 
      imageError(ix, lc, ot); 
     }; 
} 

function imageLoaded(i,l,o){ 
    var img=$(images[i]); 
    img.hide().css({'display':'block','height':'25px','width':'25px'}).appendTo(l).fadeIn(); 
    loadOtherObjects(o,img); 
} 

function imageError(i,l,o){ 
    // handle 404 using setTimeout set at 10 seconds, adjust as needed 
    timer = setTimeout(function() {$(images[i]).unbind("error load onreadystate");}, 10000); 
    $(images[i]).bind("error load onreadystatechange", function (e) { 
     if (e.type !== "error") { 
      imageLoaded(i,l,o); 
     } 
    }); 
} 

function loadOtherObjects(o,img){ 
    if (o) { 
     console.log(o); 
     console.log(o.Type==urlTypes.LINK); 
     if (o.Type == urlTypes.IFRAME) { 
      var d = $("<div/>").css({'height':'250px','width':'250px'}), f = $("<iframe/>").attr("src", o.URL); 
      f.appendTo(d); 
      d.insertAfter(img); 
     } else if(o.Type == urlTypes.LINK) { 
      var lnk = $("<a/>").attr("href", o.URL).text(o.Text); 
      lnk.insertAfter(img); 
     } 
    } 
} 

$(function(){ 
    loadImages(imgArr, "#container", otherUrls); 
}); 

UWAGA: Proszę zobaczyć this answer do innego pytanie dotyczące ładowania obrazów za pomocą kodu, ponieważ nie wszystkie przeglądarki przeciwpożarowych loaded wydarzenie, jeśli obrazy znajdują się w pamięci podręcznej.

+0

To prawie działa, ale ładuje obrazy w pozornie losowej kolejności (5,3,4,6,1,2 itd., Różne przy każdym ładowaniu). Używam kodu w oryginalnym pytaniu, aby dynamicznie utworzyć moją tablicę, aby nie musieć masowo duplikować kodu z pełną ścieżką do każdego obrazu (wszystkie znajdują się w tym samym miejscu i są 22 całkowity). Masz pojęcie, co powoduje takie zachowanie? –

+0

dobrze, ponieważ jest to spowodowane rozmiarem zdjęć. ponieważ używamy wywołań zwrotnych do obsługi zdarzeń ładowania, gdy tylko zostanie załadowany, zostanie to pokazane. Co możesz zrobić, to wczytać pierwszy obraz, a następnie uruchomić ładowanie kolejnego z funkcji 'onload'' imageLoaded' – TheVillageIdiot

Powiązane problemy