Phil: Bilder Diashow mit Preload und "Bereitsgeladen-Absicherung"

Hallo zusammen,

ich benötige mal wieder Eure Hilfe!

Ich erfinde doch so furchtbar gerne das Rad neu, und da dachte ich mir, dass ich mal schnell 'ne Diashow (Slideshow, wie auch immer ;-)) schreibe.

Tja, die Worte "Ich" "schnell" und "schreibe" passen einfach nicht zusammen, und deshalb sitz ich mal wieder vor meinem Computer und hab wieder mal ein Haarbüschel weniger.

Die Slideshow hat ein Array, in dem sämtliche Bilder der Slideshow als URI hinterlegt sind. Alle 7 Sekunden wird per setTimeout ein neues Bild angezeigt, dass vorher als neues Image Objekt vorgeladen wurde. Gleichzeitig beginnt natürlich wieder per Image Objekt der Preload des nächsten Bildes. Soweit sogut, das ist ja alles keine große Sache, funktionier auch wunderbar.

Folgendes Problem:
Ich möchte nicht, dass die Slideshow zum nächsten Bild springt, bevor dieses komplett im Cache ist. Daher wollte ich, ja, eben so eine Art "Bereits-Geladen-Absicherung" einbauen, über die ich versuche, festzustellen, ob ein bestimmtes Bild geladen wurde, oder eben nicht.
Erster Ansatz war über complete des Image Tags. Musste aber leider bald feststellen, dass ich dass nur mit real existierenden Image Tags nutzen kann, nicht jedoch mit Image Objekten in Javascript.
Es folgten noch andere Versuche. Dann viel mir endlich wieder der altbewährte Trick mittels onload im <img> ein, wo sich jedes Bild praktisch bei einer Methode "Bereit" meldet.

Nun hab ich aber dummerweise neuerdings diesen Tick von wegen valides XHTML schreiben. Da fällt der onload Trick schnell wieder Weg, da onload nur im body und frameset Tag erlaubt ist.

Lange Rede kurzer Sinn, ich wollte mal hören, ob jemand irgendwelche genialen Ideen hat, wie man so eine Überprüfung auf Ladezustand schreiben kann, und trotzdem "sauber" bleibt.

Vielen Dank für jede Idee oder jedes Stichwort!

Gruß

Phil

--
ie:{ fl:( br:> va:} ls:< fo:) rl:( n4:{ ss:) de:] js:| ch:? sh:( mo:) zu:)
  1. Hallo Phil,

    Lange Rede kurzer Sinn, ich wollte mal hören, ob jemand irgendwelche genialen Ideen hat, wie man so eine Überprüfung auf Ladezustand schreiben kann, und trotzdem "sauber" bleibt.

    Vielen Dank für jede Idee oder jedes Stichwort!

    Den Eventhandler kannst du auch im Script-Bereich selbst aufrufen.

    Beispiel:

    window.onload = deineCompletePruefFunktion;

    Ähnlich geht es vielleicht auch so:

    bilder[0) = new Image();
    bilder[0].src = "deinBild.jpg";
    bilder[0].onload = deineFolgeAktion;

    Habe ich noch nie so gemacht, werde das aber nächste woche mal ausprobieren, weil ich letzte Woche vor einem ähnlichen Problem stand, dessen Lösung ich erst einmal vertagt habe.

    Gruß Gernot

    1. Hallo nochmal,

      das folgende Skript sollte eigentlich funktionieren, denn wenn man ein nicht existetes Bild laden will, wird brav "nicht geladen" gemeldet.

      Dennoch habe ich Zweifel, denn auf der Seite, an der ich letzte Woche gebastelt habe, scheint das noch nicht so ganz zu funktionieren:

      <script type="text/javascript" language="JavaScript">
      <!--

      var pics = new Array('er.gif', 'sie.gif', 'es.gif');
      var bilder = new Array();
      for (i=0; i<pics.length ; i++ ) {
       bilder[i]= new Image();
       bilder[i].src = pics[i];
      }

      function melden () {
        for (i=0; i<bilder.length ; i++ ) {
          if(bilder[i].complete) {
            alert(bilder[i].src +" geladen!");
          } else {
            alert(bilder[i].src +" nicht geladen!");
            bilder[i].src = pics[i];
            return false;
          }
        }
      }

      window.onload = melden;

      //-->
      </script>

      Gruß Gernot

      1. Hi Gernot,

        dein Ansatz sieht ungefähr genauso aus wie meiner, nur bin ich nicht auf window.onload gekommen. Wie gesagt, bei mir "scheint" es daran zu scheitern, dass die complete Eigenschaft wohl nicht mit Image Objekten arbeitet, sondern nur mit real existierenden Tags. Zumindest sah das für mich so aus.

        Ich habe das Problem letzte Nacht noch gelößt, hatte bereits bei meinem Posting so ein Gefühl... Ich habe einfach beide Ansätze kombiniert.

        Jedes Bild der Slideshow wird in einem 1 x 1px großem unsichtbarem Div geladen. Wichtig ist natürlich overflow:hidden. Jedesmal, wenn die Routine zum wechseln der Bilder aufgerufen wird, fragt sie vorher eine Prüfroutine, ob denn dieses Bild geladen ist (Wo complete dann sehr gut arbeitet, scheinbar wirklich, weil ich jetzt "echte" Bilder habe, und nicht Image Objekte). Ist das Bild geladen, wird ordentlich ausgetauscht, und wieder ein Timeout gesetzt. Wenn nicht, ruft sich die Routine einige Millisekunden selbst wieder auf und versucht wieder das Bild zu wechseln.

        Einziger wirklicher Nachteil dabei ist, dass die onload Funktion des Bodys unbrauchbar wird, weil er ewig lädt (bis alle Bilder geladen sind). Aber damit kann ich glaub ich leben.

        Letzten Endes war es eigentlich so einfach, dass es mir peinlich ist, das ganze als Frage gepostet zu haben ;-)

        Falls es jemanden interessiert, hier der Quelltext des ganzen, in noch sehr unreiner Form ;-)

        <?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE  html PUBLIC "-//W3C//DTD XHTML 1.1//EN"  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

        <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <meta http-equiv="Content-Script-Type" content="text/javascript" /> <meta http-equiv="Content-Style-Type" content="text/css" />

        <titleDiashow</title>

        <script type="text/javascript">

        var ImgArr = new Array("NAME","ID", "VIEWED");  ImgArr["NAME"] = new Array("Blick auf Granada","H&auml;user in Granada","Iglesia de Santa Ana ","Eingang zu einem versteckten Garten","Versteckter Innenhof in Granada","Sternenhimmel","Licht und Schatten","Blick von der Alhambra auf den Stadtteil Albaicin ","Die Alhambra Grande","Die G&auml;rten des Generalife von aussen","Die G&auml;rten des Generalife ","Besuch in den G&auml;rten","In den G&auml;rten","In den G&auml;erten","Sabine in den G&auml;rten des Generalife","H&uuml;bscher Brunnen mit interessanter Form","Es war einmal ....","Weitere kleine G&auml;rten auf dem Weg durch die Medina","","","Sabine in der Medina","Ich in der Medina","Blick auf die Alcazaba","Tiefe Ruinen in der Alcazaba","Eingangsraum in den Nasridischen Pal&auml;sten","Kleiner Brunnen im Myrtenhof","Sch&ouml;ne Blumenornamente ","Schriftornamente ","Fantastisch verzierte B&ouml;gen in den Nasridischen Pal&auml;sten","Kuppel in der Sala de los Abencerrajes.","Endlich, der ber&uuml;hmte L&ouml;wenhof","Der L&ouml;wenbrunnen","Detail des L&ouml;wenhofs","Sch&ouml;ner Brunnen in den Nasridischen Pal&auml;sten","Der Brunnen aus der N&auml;he","Alabasterbrunnen","Der Ladies Tower","Garten Alhambra","Garten Alhambra","Kleiner Rosengarten");  ImgArr["ID"] = new Array("77","78","79","80","81","82","83","84","85","86","87","88","89","90","91","92","93","94","95","96","97","98","99","100","101","102","103","104","201","202","203","204","205","206","207","208","209","210","211","212");  ImgArr["VIEWED"] = new Array("14","25","17","12","8","2","5","6","11","2","2","3","2","2","2","0","1","1","1","0","2","5","1","1","2","1","1","2","0","0","3","1","2","1","2","1","2","2","8","1");  var ImgCount = 40;  var Img = 0;

        function customSize() {   //if(document.getElementById('SlideImg').height > screen.height - 300) {    document.getElementById('SlideImg').height = screen.height - 300;   //}  }

        function startSlideshow() {   window.setTimeout("nextImage()",7000);  }

        function isLoaded() {   var ImageId = "Img" + Img;   if(document.getElementById(ImageId).complete == true) {    return true;   }   else {    return false;   }  }

        function nextImage() {   if(Img == ImgCount - 1) { Img = -1; }   Img++;   if(isLoaded()) {    ImageId = "Img" + Img;    document.getElementById('SlideImg').src = document.getElementById(ImageId).src;    document.getElementById('SlideImg').alt = document.getElementById(ImageId).alt;    document.getElementById('ImgNum').innerHTML = (Img+1).toString();    document.getElementById('ImgNameBig').innerHTML = document.getElementById(ImageId).alt;    document.getElementById('ImgNameSmall').innerHTML = document.getElementById(ImageId).alt;    document.getElementById('ImgViewed').innerHTML = ImgArr["VIEWED"][Img];    window.setTimeout("nextImage()",7000);   }   else {    Img--;    window.setTimeout("nextImage()", 50);   }  } </script>

        </head> <body onload=""> <div style="margin-top: 30px; text-align: center; width: 100%;">  <h1 id="ImgNameBig">Blick auf Granada</h1>  <img id="SlideImg" src="/deliverImage.html?id=77" alt="Blick auf Granada" /><br  />  <script type="text/javascript">   customSize();   startSlideshow();  </script>

        <span id="ImgNum">1</span>/40 | <span id="ImgNameSmall">Blick auf Granada</span> | <span id="ImgViewed">14</span> mal angeschaut<br />  <div id="PreImgContainer" style="width: 1px; height: 1px; visibility: hidden; overflow: hidden;">    <img id="Img0" src="/deliverImage.html?id=77" alt="Blick auf Granada" />

        <img id="Img1" src="/deliverImage.html?id=78" alt="H&auml;user in Granada" />    <img id="Img2" src="/deliverImage.html?id=79" alt="Iglesia de Santa Ana " />    <img id="Img3" src="/deliverImage.html?id=80" alt="Eingang zu einem versteckten Garten" />    <img id="Img4" src="/deliverImage.html?id=81" alt="Versteckter Innenhof in Granada" />    <img id="Img5" src="/deliverImage.html?id=82" alt="Sternenhimmel" />    <img id="Img6" src="/deliverImage.html?id=83" alt="Licht und Schatten" />    <img id="Img7" src="/deliverImage.html?id=84" alt="Blick von der Alhambra auf den Stadtteil Albaicin " />    <img id="Img8" src="/deliverImage.html?id=85" alt="Die Alhambra Grande" />    <img id="Img9" src="/deliverImage.html?id=86" alt="Die G&auml;rten des Generalife von aussen" />

        <img id="Img10" src="/deliverImage.html?id=87" alt="Die G&auml;rten des Generalife " />    <img id="Img11" src="/deliverImage.html?id=88" alt="Besuch in den G&auml;rten" />    <img id="Img12" src="/deliverImage.html?id=89" alt="In den G&auml;rten" />    <img id="Img13" src="/deliverImage.html?id=90" alt="In den G&auml;erten" />    <img id="Img14" src="/deliverImage.html?id=91" alt="Sabine in den G&auml;rten des Generalife" />    <img id="Img15" src="/deliverImage.html?id=92" alt="H&uuml;bscher Brunnen mit interessanter Form" />    <img id="Img16" src="/deliverImage.html?id=93" alt="Es war einmal ...." />    <img id="Img17" src="/deliverImage.html?id=94" alt="Weitere kleine G&auml;rten auf dem Weg durch die Medina" />    <img id="Img18" src="/deliverImage.html?id=95" alt="" />

        <img id="Img19" src="/deliverImage.html?id=96" alt="" />    <img id="Img20" src="/deliverImage.html?id=97" alt="Sabine in der Medina" />    <img id="Img21" src="/deliverImage.html?id=98" alt="Ich in der Medina" />    <img id="Img22" src="/deliverImage.html?id=99" alt="Blick auf die Alcazaba" />    <img id="Img23" src="/deliverImage.html?id=100" alt="Tiefe Ruinen in der Alcazaba" />    <img id="Img24" src="/deliverImage.html?id=101" alt="Eingangsraum in den Nasridischen Pal&auml;sten" />    <img id="Img25" src="/deliverImage.html?id=102" alt="Kleiner Brunnen im Myrtenhof" />    <img id="Img26" src="/deliverImage.html?id=103" alt="Sch&ouml;ne Blumenornamente " />    <img id="Img27" src="/deliverImage.html?id=104" alt="Schriftornamente " />

        <img id="Img28" src="/deliverImage.html?id=201" alt="Fantastisch verzierte B&ouml;gen in den Nasridischen Pal&auml;sten" />    <img id="Img29" src="/deliverImage.html?id=202" alt="Kuppel in der Sala de los Abencerrajes." />    <img id="Img30" src="/deliverImage.html?id=203" alt="Endlich, der ber&uuml;hmte L&ouml;wenhof" />    <img id="Img31" src="/deliverImage.html?id=204" alt="Der L&ouml;wenbrunnen" />    <img id="Img32" src="/deliverImage.html?id=205" alt="Detail des L&ouml;wenhofs" />    <img id="Img33" src="/deliverImage.html?id=206" alt="Sch&ouml;ner Brunnen in den Nasridischen Pal&auml;sten" />    <img id="Img34" src="/deliverImage.html?id=207" alt="Der Brunnen aus der N&auml;he" />    <img id="Img35" src="/deliverImage.html?id=208" alt="Alabasterbrunnen" />    <img id="Img36" src="/deliverImage.html?id=209" alt="Der Ladies Tower" />

        <img id="Img37" src="/deliverImage.html?id=210" alt="Garten Alhambra" />    <img id="Img38" src="/deliverImage.html?id=211" alt="Garten Alhambra" />    <img id="Img39" src="/deliverImage.html?id=212" alt="Kleiner Rosengarten" />   </div> </div> </body> </html>

        Etwas umfangreich, aber dafür der komplette Parsetree dabei :)

        Vielen Dank an dich Gernot, werde deinen Ansatz jetzt auch nochmal ausprobieren!

        Gruß

        Phil

        --
        ie:{ fl:( br:> va:} ls:< fo:) rl:( n4:{ ss:) de:] js:| ch:? sh:( mo:) zu:)