Hans: Mysteriöser Fehler beim Bildertausch

Hallo!

Ich bin der Verzweiflung nah! Ich habe eine Bildergallerie gebaut, bei welcher ein Bild groß und die kleineren darunter in klein dargestellt werden. Beim Klick auf ein kleines Bild soll das Großbild gegen dieses getauscht werden.

Dies klappt auch alles einwandfrei. Zufällig sitze ich jetzt aber wieder an meinem alten Notebook, wo noch der IE6 drauf läuft. Hier tritt jetzt ein total mysterioeser Fehler auf:

Nach Klick auf ein kleines Bild wird nur ab und zu das jew. Bild in Groß angezeigt. Meistens verschwindet das aktuelle Bild und dafür bleibt die Stelle einfach leer. Klicke ich mit der rechten Maustaste auf die Eigenschaften sehe ich, dass der neue Pfad eingetragen ist. Wähle ich dort "Bild anzeigen" so wird das Bild auch immer angezeigt. Allerdings werden dann die Größenangaben nicht korrigiert und das Bild ist verzerrt.

Nun wird es noch mysterioeser: Füge ich direkt nach "img.src = newsrc;" ein "alert('test');" ein, so werden die Bilder zu 100% einwandfrei getauscht und dargestellt. Nehme ich es wieder raus ist der Fehler wieder da... Ich kann nach einem Tag allmöglicher Tests absolut nicht erkennen woran das liegen könnte. An anderen Stellen tausche ich auch Bilder und dort klappt es auch mit meinem IE6 hier immer.

---
Glaubt ihr mein IE spinnt einfach nur (der Quelltext lässt sich auch immer nur nach Löschen der Temporären Dateien anzeigen..) oder habe ich vielleicht irgend nen Fehler gemacht, so dass ich in einen Bug vom IE6 reinrassele?

Hier der Code in Kurzform:
// bilder ist ein Array mit Informationen zu den Bildern (Src, Groesse, Alt...)
function picChanged(thumbsrc){
  for(i=0 ; i<bilder.length ; i++){
    if(thumbsrc.indexOf(bilder[i][2])>=0){
      showPic(i); // Tauscht das Bild, übergibt nur die Bildnummer
      break;
    }
  }
}
function showPic(i){
  haupt  = document.getElementById('hauptbild'); // div
  haupt_a = haupt.getElementsByTagName('a')[0];
  haupt_img = haupt.getElementsByTagName('img')[0];
  // ...
  haupt_img.width  = sizex;
  haupt_img.height = sizey;
  haupt_img.alt    = xl.alt  = altl;
  haupt_img.src = xl.src = src;
  // alert('test'); - Wird hier alert ausgeführt klappt der Tausch..
}

---
So ich hoffe durch die Vereinfachung hab ich nichts wichtiges gelöscht. Aber viel mehr findet eigentlich nicht statt... Ich hoffe einer von euch kennt zufällig eine Lösung. Ich bin am Ende ;)

  1. Lieber Hans,

    Du arbeitest mit globalen Variablen:

    function showPic(i){
      haupt  = document.getElementById('hauptbild'); // div
      haupt_a = haupt.getElementsByTagName('a')[0];
      haupt_img = haupt.getElementsByTagName('img')[0];

    Das solltest Du aber nicht! Benutze "var haupt = ..." um eine lokale Variable zu erzeugen.

    Wenn Du schon dabei bist, Dein Script zu verbessern, da frage ich doch gleich: Was tun Besucher ohne Javascript? Was bekommen die zu sehen?

    Du schreibst auch etwas über Abmessungen, und dass diese nach dem Bilderwechsel nicht korrigiert würden. Wie wäre es denn, wenn das umgebende Element des "großen Bildes" einfach eine Mindestgröße hat, innerhalb derer es ein Bild per CSS zentriert anzeigt? Dann braucht es keine Korrekturen an den Abmessungen mittels Javascript!

    Du könntest auch das Vollbild jeweils per Javascript vorausladen lassen und während dieses Ladevorgangs eine Animation zeigen (wie in etwa bei der lightbox).

    Schön fände ich, wenn das Script als extern eingebundene JavaScript-Datei sich selbständig initialisiert (also die "kleinen Bilder" mit dem Bildertausch versieht, die sonst einfach nur auf das Vollbild verweisen) und damit "unobtrusive" ist.

    Magst Du einen Link zu Deiner bisherigen Version posten, damit man sich das genauer anschauen kann?

    Liebe Grüße aus Ellwangen,

    Felix Riesterer.

    --
    ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
    1. Hallo Felix,

      vielen Dank für die Antwort!

      Das mit den globalen Variablen wird abgestellt. Nicht genau aufgepasst.

      Wenn Du schon dabei bist, Dein Script zu verbessern, da frage ich doch gleich: Was tun Besucher ohne Javascript? Was bekommen die zu sehen?

      Die Benutzbarkeit ohne Javscript ist mir sehr wichtig. Aber dies würde mich gleich zu einer anderen Frage führen:

      Ich habe vor den Linktausch mit einem Link wie dem folgenden durchzuführen:
      <a href="{SELF}?bild={bildnr}" onclick="return picChanged({thumb});"><img...></a>

      Die Funktion picChanged gibt entweder true oder false zurück. Ist Javascript aktiviert und klappt der Bildtausch (Test auf img.complete) so gibt die Funktion false zurück. Dadurch wird das Gehen zu {SELF}?bild=... unterbunden. Ist Javascript deaktiviert so wird einfach nur dem Link gefolgt, welcher die gleiche Seite mit dem anderen Bild in groß neu lädt.

      Mit den getesteten Browsern funktioniert das einwandfrei. Könnte es damit sonst noch Probleme geben? (Nach einem kurzen Blick auf lightbox wird es dort ähnlich gemacht?! Aber ein sehr schöner Link, Danke! :))

      Du schreibst auch etwas über Abmessungen, und dass diese nach dem Bilderwechsel nicht korrigiert würden. Wie wäre es denn, wenn das umgebende Element des "großen Bildes" einfach eine Mindestgröße hat, innerhalb derer es ein Bild per CSS zentriert anzeigt? Dann braucht es keine Korrekturen an den Abmessungen mittels Javascript!

      Die Abmessungen würden sich also durch die Bildmaße selbst anpassen? Damit hatte ich ein paar Probleme, außerdem passten sich die Maße immer erst an wenn das Bild voll geladen war. Das war mir etwas zu spät.

      Du könntest auch das Vollbild jeweils per Javascript vorausladen lassen und während dieses Ladevorgangs eine Animation zeigen (wie in etwa bei der lightbox).

      Ich lasse die Bilder onLoad vorausladen. Dabei bin ich mir aber nie sicher, ob das so richtig klappt... Die Funktion:
      function...{
        if(document.Vorladen) return true;
        document.Vorladen = new Array();
        var tbilder = document.getElementsByName('thumblink');
        if(document.images){
          for(var i = 0; i < tbilder.length; i++){
       src = tbilder[i].firstChild.src.replace('_thumb','');
       document.Vorladen[i] = new Image();
              document.Vorladen[i].src = src;
          }
        }
      }

      Schön fände ich, wenn das Script als extern eingebundene JavaScript-Datei sich selbständig initialisiert (also die "kleinen Bilder" mit dem Bildertausch versieht, die sonst einfach nur auf das Vollbild verweisen) und damit "unobtrusive" ist.

      Meinen Ansatz hatte ich ja oben beschrieben. Ich wüsste gerne was von beidem die beste Lösung ist. Auf den Seiten habe ich auch noch eine Bestellbox mit Selects, die Ihre Inhalte anpassen. Bei der mache ich es so, dass sie beim Laden initialisiert wird und biete sonst eine einfache Bestellmöglichkeit ohne Javascript.

      Magst Du einen Link zu Deiner bisherigen Version posten, damit man sich das genauer anschauen kann?

      Jau das kann ich tun! Ich habe es bisher aber noch nicht online und muss in Kürze zu einem Termin. Ich werde es heute abend mal online stellen und den Link dann posten.

      Grüße
      Hans

  2. Hallo,

    zu

    Ich lasse die Bilder onLoad vorausladen. Dabei bin ich mir aber nie sicher, ob das so richtig klappt... Die Funktion:
    function...{
      if(document.Vorladen) return true;
      document.Vorladen = new Array();
      var tbilder = document.getElementsByName('thumblink');
      if(document.images){
        for(var i = 0; i < tbilder.length; i++){
     src = tbilder[i].firstChild.src.replace('_thumb','');
     document.Vorladen[i] = new Image();
            document.Vorladen[i].src = src;
        }
      }
    }
    <<<<<

    Vorladen soll also eine Kind von document sein.
    Javascript-Variablen sind Instanzen der Scriptmaschine und nicht des
    HTML-DOM.

    -------------------------------------------

    zu

    function showPic(i){
      haupt  = document.getElementById('hauptbild'); // div
      haupt_a = haupt.getElementsByTagName('a')[0];
      haupt_img = haupt.getElementsByTagName('img')[0];
      // ...
      haupt_img.width  = sizex;
      haupt_img.height = sizey;
      haupt_img.alt    = xl.alt  = altl;
      haupt_img.src = xl.src = src;
      // alert('test'); - Wird hier alert ausgeführt klappt der Tausch..
    }

    <<<<<<

    Wo ist i in shwoPic() ?

    ---------------------

    Tipp: Wie wärs mit je einem Zeigerfeld aller DIV der kleinen bzw. grossen Bilder ? Der IE kommt ohne getElemementsXXXX-Funktionen aus
    und kann Zeiger direkt verwenden (inklusive ID-Attribut-Werte).
    Zeigerfelder direkt füllen per appendChild() nach createElement().
    Naturlich sind anstelle DIV mit IMG auch IMG ohne Container dynamisch
    verwendbar.

    Gruss Tom.

    1. hi,

      jetzt hör' doch bitte langsam mal auf, deinen weitgehend unfundierten Blödsinn hier abzusondern.

      if(document.Vorladen) return true;

      Vorladen soll also eine Kind von document sein.

      Wenn er sich Vorladen als Eigenschaft von document definiert hat, dann ist Vorladen eine Eigenschaft von document.

      Javascript-Variablen sind Instanzen der Scriptmaschine

      Soll heissen?

      Globale Variablen sind Eigenschaften von window.
      Solltest du das gemeint haben, drückst du dich - zum wiederholten Male - mehr als ungeschickt aus.

      und nicht des HTML-DOM.

      Auch mit diesem Begriff wirfst du äusserst gerne um dich - könntest du den mal erklären, bzw. ein Wort dafür verwenden, welches allgemein geläufig ist?

      gruß,
      wahsaga

      --
      /voodoo.css:
      #GeorgeWBush { position:absolute; bottom:-6ft; }
      1. Hallo,
        Prototyping eines vordefinierten Objektes bedingt nicht, dass der Browser auch reagiert. Objekteigenschaften etc. in der Erbfolge machen nur Sinn, wenn der Brwoser zu Aktionen angeregt wird. Ansonsten sind Scriptvariablen nutzbar, die selbstverständlich nicht im HTML-DOM hinterlegt sind - wie Array als Javascript-Aktion "Feld".

        Wenn document.Vorladen kodiert wurde, muss es also entweder ein
        Prototyping von window sei - mit dem Ziel der Browseraktion, oder
        eine angehangene Script-Variable.

        Prototyping benutzt durchhangeln von Zeigerabhängigkeiten. Die Refenrenz auf eine globale Variable nicht. Protoyping kann also, wenn nicht zwingen notwendig, Laufzeiten verbrauchen.

        HTML-DOM ist das HTML-Document-Object-Model z.B. nach Standard oder nach z.B. Microsoft-Modellierung. HTML-DOM deshalb, weil HTML-Elemente des Dokumentes intern über Zeiger also Referenzen in der "Erbfolge" abgebildet werden müssen. Genaus das enspricht auch der Nutzung per JavaScript, also auch Prototyping.

        Als Pendant gibt es noch z.B. XML-DOM.

        Ajax nutzt intensiv HTML-DOM (inklusive Notprogrammierungen wegen z.B. Microsoftabweichungen vom Standard).

        Typisches Beispiel für HTML-DOM ist der inline-Style also das STYLE-Attribut eines HTML-Tag. Der Style ist auch Pendant zum scriptfreien CSS (ohne Javascript).

        Im HTML-DOM werden auch Style des Objektes genannt, wobei in Script nutzbare Styles überwiegen können.

        Wie Objekte sind also auch Style vordefiniert, da sie ja eine Aktion des Browsers auslösen sollen.

        HTML-DOM-Beschreibungen bieten Browser-Hersteller an bzw. berufen sich auf Standards. Die HTML-Beschreibung von Microsoft steht unter
        http://msdn2.microsoft.com/en-us/library/ms533050.aspx.

        Tom

        1. Lieber twseiten_de,

          es tut mir ja fast leid, aber Dein Geschreibsel liest sich wie eine Google-Übersetzung...

          Liebe Grüße aus Ellwangen,

          Felix Riesterer.

          --
          ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
        2. hi,

          Wenn document.Vorladen kodiert wurde, muss es also entweder ein
          Prototyping von window sei

          Wie kommst du denn darauf?

          oder eine angehangene Script-Variable.

          Das schrieb ich doch.

          Prototyping benutzt durchhangeln von Zeigerabhängigkeiten. Die Refenrenz auf eine globale Variable nicht. Protoyping kann also, wenn nicht zwingen notwendig, Laufzeiten verbrauchen.

          Prototyping ist an der fraglichen Stelle gar nicht im Spiel.

          Typisches Beispiel für HTML-DOM ist der inline-Style also das STYLE-Attribut eines HTML-Tag. Der Style ist auch Pendant zum scriptfreien CSS (ohne Javascript).

          Blödsinniger hätt' ich's auch nicht formulieren können.

          Im HTML-DOM werden auch Style des Objektes genannt, wobei in Script nutzbare Styles überwiegen können.

          Wie Objekte sind also auch Style vordefiniert, da sie ja eine Aktion des Browsers auslösen sollen.

          Auch beides wieder ziemlich sinnfreie Aussagen.

          gruß,
          wahsaga

          --
          /voodoo.css:
          #GeorgeWBush { position:absolute; bottom:-6ft; }