Matthias Apsel: Prüfen, ob Bild geladen wurde

Om nah hoo pez nyeetz, alle!

Ich habe für ein Projekt eine umfangreiche Navigation erstellt, deren <a>-Elemente nur eine Hintergrundgrafik (alle dieselbe als Sprite) enthalten. Das ist natürlich ggf. nicht barrierefrei. Deshalb habe ich zunächst eine Textvariante der Navigation, die für Leute, die mit JS und Grafiken unterwegs sind, folgendermaßen auf die Grafikvariante umgestellt wird:

<img src="..." alt="..."  onload="document.getElementById('nav').className = 'nutzbar';">

Dies funktioniert auch, allerdings gefällt mir das nicht so richtig und der Validator meckert (zu recht) über "onload".

Gibt es andere Ansätze?

  • Geschichten über document.getElementById scheitern, weil das Element ja unabhängig davon existiert, ob die Grafik auch tatsächlich geladen wurde
  • document.Bildname.complete arbeitet nicht ordentlich [[ref:self812;javascript/objekte/images.htm#complete@title=selfhtml], dort "Beachten Sie"]
  • riesige JQuery-Geschichten möchte ich nicht verwenden

Matthias

--
1/z ist kein Blatt Papier. http://www.billiger-im-urlaub.de/kreis_sw.gif
  1. Hi,

    Gibt es andere Ansätze?

    a) Die Basisvariante anbieten, die für alles und jeden funktioniert.
    b) Mittels erweiterter Techniken optimierte Varianten für spezielle Fälle anbieten.

    Die erweiterten Techniken können z.B. CSS sein (::before bietet sich an), oder eine Kombination aus JavaScript (schreibt eine HTML-Klasse in ein zentrales Element) und CSS (reagiert per Selektor darauf).

    Wieso Du wissen willst, ob irgendwelche Bilder geladen wurden, ist mir nicht klar. Ein solches Wissen sollte nicht nötig sein, zumal eine Reaktion darauf nur stark verspätet möglich ist.

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:| br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. Om nah hoo pez nyeetz, Cheatah!

      Hi,

      Gibt es andere Ansätze?

      a) Die Basisvariante anbieten, die für alles und jeden funktioniert. b) Mittels erweiterter Techniken optimierte Varianten für spezielle Fälle anbieten.

      Das hab ich ja gemacht. (allerdings ist b) nicht valide)

      a) alle kriegen eine Textvariante b) Nutzer mit aktivierten JS und aktivierten Grafiken bekommen die Grafikvariante

      Wieso Du wissen willst, ob irgendwelche Bilder geladen wurden, ist mir nicht klar. Ein solches Wissen sollte nicht nötig sein, zumal eine Reaktion darauf nur stark verspätet möglich ist.

      Ich prüfe anhand des Bildes, ob das Laden von Bildern im Browser aktiviert ist. (Das könnte eine 1x1 Pixel-Grafik sein oder auch eine, die sowieso benötigt wird.)

      Mir ist dabei klar, dass sein könnte:

      • nur die Grafik, die ich prüfe wird geladen, die notwendige nicht (Pech)
      • nur die Grafik, die ich prüfe wird nicht geladen, die notwendige schon (sieht unschön aus)
      • Leute, die JS deaktiviert haben, kommen nur in den Genuss der Textvariante, obwohl die Navigation ansich ohne JS auskäme
      • Leute haben nur das Anzeigen von Hintergrundgrafiken deaktiviert

      Ich bin der Meinung/Hoffnung, dass ich auf diese (leider nicht valide) Weise, (fast) jedem eine zugängliche Navigation zur Verfügung stelle.

      Matthias

      --
      1/z ist kein Blatt Papier. http://www.billiger-im-urlaub.de/kreis_sw.gif
  2. <img src="..." alt="..." onload="document.getElementById('nav').className = 'nutzbar';">

    Erst einmal hat das im HTML nichts zu suchen, das kannst du mit reinem JavaScript machen. Am besten lädst du gleich die Hintergrundgrafik.

    var navBg = new Image();
    navBG.onload = function () {
      ...
    };
    navBg.src = 'nav-bg.png';

    Dies funktioniert auch, allerdings gefällt mir das nicht so richtig und der Validator meckert (zu recht) über "onload".

    onload existiert seit Netscape 2 beim img-Element. Dass HTML 4 es nicht erlaubt, ist ein Fehler. HTML5 erlaubt es.

    Mathias

    1. Hallo molily,

      var navBg = new Image();
      navBG.onload = function () {

      wird denn das Bild nur geladen, wenn der Browser das automatische Bilderladen eingeschaltet hat, oder lädt navBg.src=... das Bild immer?

      Gruß, Jürgen

      1. Om nah hoo pez nyeetz, JürgenB!

        Hallo molily,

        var navBg = new Image(); navBG.onload = function () {

        wird denn das Bild nur geladen, wenn der Browser das automatische Bilderladen eingeschaltet hat, oder lädt navBg.src=... das Bild immer?

        im FF5 ersteres

        Matthias

        --
        1/z ist kein Blatt Papier. http://www.billiger-im-urlaub.de/kreis_sw.gif
        1. Om nah hoo pez nyeetz, Matthias Apsel!

          var navBg = new Image(); navBG.onload = function () {

          wird denn das Bild nur geladen, wenn der Browser das automatische Bilderladen eingeschaltet hat, oder lädt navBg.src=... das Bild immer?

          Safari spielt nicht mit.

          Matthias

          --
          1/z ist kein Blatt Papier. http://www.billiger-im-urlaub.de/kreis_sw.gif
          1. Hallo Matthias,

            Safari spielt nicht mit.

            also sollte man besser das Bild im html anfordern und dann per JS (body.onload, img.onload, ...) die Maße abfragen.

            Gruß, Jürgen

            1. Om nah hoo pez nyeetz, JürgenB!

              Safari spielt nicht mit.

              also sollte man besser das Bild im html anfordern

              Hintergrundbild

              und dann per JS (body.onload, img.onload, ...) die Maße abfragen.

              navBg.onload = function ()
              {
                 if (navBg.height > 0) {navigation.className = "grafisch";}
              };
              

              mit diesem doppelt gemoppelten gibt sich auch der Safari zufrieden. Hängt das möglicherweise auch mit der unterschiedlichen Interpretation von Bildname.complete zusammen?

              Matthias

              --
              1/z ist kein Blatt Papier. http://www.billiger-im-urlaub.de/kreis_sw.gif
              1. Hallo Matthias,

                das verstehe wer will: onload feuert, aber Höhe ist 0.

                Was machen denn die IEs?

                Gruß, Jürgen

                1. Om nah hoo pez nyeetz, JürgenB!

                  das verstehe wer will: onload feuert, aber Höhe ist 0.

                  Was machen denn die IEs?

                  die machens richtig, bis hinunter zum 6er.

                  Matthias

                  --
                  1/z ist kein Blatt Papier. http://www.billiger-im-urlaub.de/kreis_sw.gif
      2. Hallo,

        wird denn das Bild nur geladen, wenn der Browser das automatische Bilderladen eingeschaltet hat, oder lädt navBg.src=... das Bild immer?

        Nunja, wenn man nach (Accessible) Image Replacement sucht, dürfte man auch Varianten finden, die funktionieren, wenn es sich um grafische Browser handelt, die dennoch die Bilder nicht laden (können). Das war zumindest ein damals (vor vielen Jahren) diskutiertes Feature. Das Verstecken von Text mit Off-left oder text-overflow: -9999px wird dem natürlich nicht gerecht.

        Mathias

  3. Hi,

    Das ist natürlich ggf. nicht barrierefrei.

    Das ist auch ein SEO-Killer.

    <img src="..." alt="..."  onload="document.getElementById('nav').className = 'nutzbar';">

    Warum dann inline?
    var img = new Image();
    img.src = "test.png";
    img.onload = // blende span mit text in a aus, und füge css-class für a mit Hintergrundbild hinzu.

    Ich teste persönlich lieber nach einem/mehreren timeouts, ob höhe/breite verfügbar ist...

    Gruesse, Joachim

    --
    Am Ende wird alles gut.
    1. Om nah hoo pez nyeetz, Joachim!

      Das ist natürlich ggf. nicht barrierefrei. Das ist auch ein SEO-Killer.

      nicht unbedingt, weil Link-Texte ja existieren

      <img src="..." alt="..."  onload="document.getElementById('nav').className = 'nutzbar';"> Warum dann inline?

      Zum schnellen Testen. Wobei molilys Gedanke natürlich um Längen besser ist, am konkreten Hintergrund zu prüfen.

      img.onload = // blende span mit text in a aus, und füge css-class für a mit Hintergrundbild hinzu.

      Halte ich nicht für gut, //schiebe Text mit CSS aus dem sichtbaren Bereich

      Ich teste persönlich lieber nach einem/mehreren timeouts, ob höhe/breite verfügbar ist...

      hab ich noch nicht gemacht, scheint mir aber für Hintergründe nicht praktikabel.

      Matthias

      --
      1/z ist kein Blatt Papier. http://www.billiger-im-urlaub.de/kreis_sw.gif
      1. Hi,

        Ich teste persönlich lieber nach einem/mehreren timeouts, ob höhe/breite verfügbar ist...

        hab ich noch nicht gemacht, scheint mir aber für Hintergründe nicht praktikabel.

        wenn Du mit new Image ein Image-Object erzeugst und dessen Eigenschaften anschliessend prüfst, ist es doch völlig egal, wofür Du dessen Source später auch noch verwenden möchtest.

        Gruesse, Joachim

        --
        Am Ende wird alles gut.