Peter Z.: Bei Click oder mouseover auf kleinem Bild Vergrößerung anzeigen.

Hallo, auf der Suche nach Lösungsvorschlägen zu dem o.g. Problem bin ich immer auf Lösungen gestoßen, wo das große Bild in CSS zunächst über width-Angaben verkleinert wurde und dann bei Hover die Normalgröße angezeigt wurde. Da wird aber doch sofort das große Bild geladen? Wie kann ich zunächst eine kleine Kopie des Bildes anzeigen und dann beim Überfahren an der selben Stelle das Originalbild anzeigen. Kann man eventuell wenn die Seite mit den kleinen Bildern aufgebaut ist im Hintergrund schon die Originalbilder laden? Gruß Peter

  1. Hallo Peter,

    Kann man eventuell wenn die Seite mit den kleinen Bildern aufgebaut ist im Hintergrund schon die Originalbilder laden?

    Klar, das geht. Beispiele gibt's im Netz oder zb. hier im Forum

    Die Umsetzung kann in vielfacher Hinsicht geschehen, grundsätzlich bleibt das Prinzip aber gleich: Die "großen" Bild unsichtbar oder nahezu unsichtbar mit einbinden, dann sind sie im Browser-Cache und stehen zur Verfügung.

    Gruss
    Henry

    1. Hallo Henry, ich habe jetzt aus Beispielen ohne Javascript etwas zusammengebaut, das fast funktioniert. Was ich nicht geschafft habe, ist das große Bild im Fenster horizontal und vertikal auszurichten. Hat jemand eine Idee, wo ich ändern muss, dass die Ausrichtung klapp? Hier der Quelltext:

      <!DOCTYPE html>
      <html>
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0;" />
      
      <style>
      
      .bilder_zoom{position: relative;  z-index: 0;
      }
      
      .bilder_zoom:hover{background-color: transparent;z-index: 50;
      }
      
      .bilder_zoom span{position: absolute; float: left;visibility: hidden;color: black;
      text-decoration: none;}
      
      .bilder_zoom span img{border-width: 0;padding: 2px;}
      
      .bilder_zoom:hover span{visibility: visible; position: fixed; display: block;
      position: absolute;top: 50%;left: 50%;margin-left: -400px;margin-top: -300px;}
      
      </style>
      
      </head>
      
      <body>
      
      <div>
      
      <a class="bilder_zoom">
      <img style="width: 100px; height: 67px;" src="img/bild_klein.jpg" alt="Muster-klein" />
      
      <span><img src="img/bild_gross.jpg" style="width: 800px; height: 600px;" alt="Muster-groß" /></span>
      </a>
      
      </div>
      
      </body>
      </html>
      
      
      1. Hallo Peter,

        Was ich nicht geschafft habe, ist das große Bild im Fenster horizontal und vertikal auszurichten. Hat jemand eine Idee, wo ich ändern muss, dass die Ausrichtung klapp?

        hmmm, dachte zuerst, klar kein Thema. Doch dann musste ich erstaunt feststellen, dass trotz HTML5 und CSS3, diese Art der Zentrierung (oder ich finde es nicht) noch nicht zufriedenstellend gelöst wurde, denn nach wie vor ist das eine der häufigsten, wenn nicht sogar die Häufigste, Frage in den Foren. Es scheint, als trickst da jeder bisher noch sein eigenes Süppchen.

        Gut, dann köchel ich mal ein wenig mit: Beispiel *bitte RUN dort klicken

        Daran gibt's sicher einiges zu kritisieren und das ist auch gut so, schließlich ist das ein Forum hier und so hoffe ich, dass ein geneigter Kritiker einen geeigneten Gegenentwurf zeigt. Habe es auch mit Flex, mit table-cell, etc. probiert. Irgendwie war immer ein Haken dabei. Leider, war selbst Selfhtml in diesem Punkt nicht wirklich hilfreich.

        Gruss
        Henry

        1. @@Henry

          Gut, dann köchel ich mal ein wenig mit: Beispiel *bitte RUN dort klicken

          Daran gibt's sicher einiges zu kritisieren

          Ja:

          <a class="bilder_zoom">

          Wozu soll das a-Element gut sein?

          <img onclick="parentNode.nextSibling.className='showbig';" >

          Wie ich schon sagte: img-Elemente sind nicht interaktiv. Niemals nicht-interaktive Elemente als Target für click-Events vorsehen.

          Habe es auch mit Flex, mit table-cell, etc. probiert. Irgendwie war immer ein Haken dabei.

          Wo hakt’s?

          LLAP 🖖

          --
          “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
          1. Hallo Gunnar,

            Wozu soll das a-Element gut sein?

            Weiß nicht ob das später später einen Grund hat, habe das am Beispiel von Peter angepasst und daher so viel als möglich belassen wie es ist.

            Habe es auch mit Flex, mit table-cell, etc. probiert. Irgendwie war immer ein Haken dabei.

            Wo hakt’s?

            na toll... 😉 danke.

            Der Grund ist einerseits das Beispiel in selfhtml, dass so nicht funktioniert. Und dann, was überraschend ist, dein Beispiel funktioniert, zumindest bei mir IE11, nur wenn ich tatsächlich wie du "vh" für die Höhe nehme, "Prozent" geht nicht.

            screenshot

            Gruss
            Henry

            1. @@Henry

              na toll... 😉 danke.

              Geht übrigens auch anders: mit display: grid statt flex.

              nur wenn ich tatsächlich wie du "vh" für die Höhe nehme, "Prozent" geht nicht.

              Doch, geht auch. Bei Prozenten ist immer die Frage: wovon? Bei vh sind’s Prozent der Viewporthöhe; bei % der Höhe des umgebenden Box. Fürs body-Element wäre dies das html-Element (und nicht etwa der Viewport). Damit das html-Element den Viewport füllt, müsste dessen Höhe auch auf 100% gesetzt werden.

              LLAP 🖖

              --
              “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
              1. Hallo Gunnar,

                Geht übrigens auch anders: mit display: grid statt flex.

                Ja, nur schade, dass bei den tollen Neuerungen das Konsortium nicht diesem, extrem häufig gestellten Wunsch, simple gelöst hat durch z.b.: element{position:vh} bzw. v oder h

                Doch, geht auch. Bei Prozenten ist immer die Frage: wovon? Bei vh sind’s Prozent der Viewporthöhe; bei % der Höhe des umgebenden Box. Fürs body-Element wäre dies das html-Element (und nicht etwa der Viewport). Damit das html-Element den Viewport füllt, müsste dessen Höhe auch auf 100% gesetzt werden.

                ach klar, Wald vor Bäumen... Danke.

                Gruss
                Henry

          2. Nachtrag, (*zum editieren schon zu spät 😉)

            das ist noch eines was bei unser beider Beispiel leider nicht funktioniert:

            Die automatische Skalierung des Bildes. Normalerweise ja ziemlich einfach mit:

            max-width: 100%;
            height: auto;
            

            Nur in Kombi hier funktioniert das leider nicht. Hättest du da auch einen Vorschlag?

        2. Hallo Henry, in Deinem Beispiel habe ich einen Effekt gefunden, den ich mir nicht erklären kann. Wenn man "<table onclick=...." in eine neue Zeile stellt, hat der Klick auf das Bild keine Wirkung. Siehe https://www.w3schools.com/code/tryit.asp?filename=FI4ODFCW5CD9

          1. @@Peter Z.

            Wenn man "<table onclick=...."

            Ich sag’s gern immer wieder: Merke: Niemals nicht-interaktive Elemente als Target für click-Events vorsehen. Für sowas sind buttons zu verwenden. Oder in diesem Fall Links.

            LLAP 🖖

            --
            “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
          2. Hallo Peter,

            Hallo Henry, in Deinem Beispiel habe ich einen Effekt gefunden, den ich mir nicht erklären kann. Wenn man "<table onclick=...." in eine neue Zeile stellt, hat der Klick auf das Bild keine Wirkung. Siehe https://www.w3schools.com/code/tryit.asp?filename=FI4ODFCW5CD9

            Ja, das ist klar.

            
            </a><table
            

            Hier funktioniert nextSibling, weil kein Leerzeichen/Absatz dazwischen ist. Manche Browser (weiß nicht ob alle) interpretieren dann die Leerstelle als nächstes.

            Deshalb funktioniert das

            </a>
            <table
            

            nicht.

            Gruss
            Henry

            1. @@Henry

              Manche Browser (weiß nicht ob alle) interpretieren dann die Leerstelle als nächstes.

              Ein Textknoten ist ein Textknoten ist ein Textknoten. Das sollte in allen Browsern so sein.

              LLAP 🖖

              --
              “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
              1. Hallo Gunnar,

                Manche Browser (weiß nicht ob alle) interpretieren dann die Leerstelle als nächstes.

                Ein Textknoten ist ein Textknoten ist ein Textknoten. Das sollte in allen Browsern so sein.

                ähm... was willst du jetzt damit sagen?

                Gruss
                Henry

                1. @@Henry

                  Manche Browser (weiß nicht ob alle) interpretieren dann die Leerstelle als nächstes.

                  Ein Textknoten ist ein Textknoten ist ein Textknoten. Das sollte in allen Browsern so sein.

                  ähm... was willst du jetzt damit sagen?

                  Dass Text im Markup einen Textknoten im DOM erzeugt, auch wenn der nur aus Whitespace besteht.

                  div
                  ├ #text
                  ├ a
                  ├ table
                  └ #text

                  ist ein anderes DOM als

                  div
                  ├ #text
                  ├ a
                  ├ #text
                  ├ table
                  └ #text

                  Und dass das nicht im Ermessen des Browsers liegt, das so zu handhaben.

                  LLAP 🖖

                  --
                  “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
            2. Hallo Henry

              Hier funktioniert nextSibling, weil kein Leerzeichen/Absatz dazwischen ist. Manche Browser (weiß nicht ob alle) interpretieren dann die Leerstelle als nächstes.

              Wenn du einen Browser findest der den Whitespace nicht interpretiert, solltest du den Bug melden.

              Die von der Schnittstelle Node vererbte Eigenschaft nextSibling gibt allgemein den Knoten zurück, der den selben Elternknoten hat wie der Knoten über den die Eigenschaft referenziert wird und der diesem in Richtung des Baums nachfolgt, oder den Wert null, wenn das Kontextobjekt der letzte Kindknoten seines Vorfahren ist.

              Beachte, dass es hier allgemein um Knoten geht und nicht speziell um Elemente, die eine besondere Form von Knoten darstellen, welche durch die Schnittstelle Element repräsentiert wird. Da es sich bei Elementen um Knoten handelt, erben sie neben den Eigenschaften und Methoden von Element auch jene von der Schnittstelle Node. Wie eben die genannte Eigenschaft nextSibling.

              Node → Element

              Außer Elementen gibt es jedoch noch einige andere Knotentypen, wie beispielsweise Textknoten, welche durch die Schnittstelle Text repräsentiert werden. Diese Knoten erben auf dem Umweg über die Schnittstelle CharacterData ebenfalls die Eigenschaften und Methoden von Node.

              Node → CharacterData → Text

              Das heißt, die auf Node definierten Eigenschaften und Methoden wie nextSibling stellen sozusagen die Grundausstattung für alle Knoten innerhalb des Document Object Models dar, unabhängig von ihrem genauen Typ. Spezifischere Schnittstellen wie Element oder Text erweitern dann diese Grundfunktionalität um weitere Eigenschaften und Methoden.

              Das oben gesagte kann übrigens leicht nachgeprüft werden, da zumindest die gennanten, abstrakt definierten Schnittstellen des Document Object Models im Browser als globale Objekte direkt referenziert werden können, so wie in dem folgenden Beispiel.

              console.info(document.body instanceof Element && document.body instanceof Node); // true
              

              Auch kann man sich vergewissern, dass es sich bei nextSibling tatsächlich um eine von Node vererbte Eigenschaft handelt, auch wenn sie wie in deinem Beispiel über ein Element referenziert wird.

              console.info(Node.prototype.hasOwnProperty('nextSibling')); // true
              

              Diese Eigenschaft ist als Getter implementiert, dessen Kontextvariable this mit dem Objekt initialisiert wird, über das die Eigenschaft angesprochen wurde. Es handelt sich also tatsächlich um keine eigene Eigenschaft der einzelnen durch Objekte repräsentierten Knoten des Baums.

              console.info(document.body.hasOwnProperty('nextSibling')); // false
              

              Jedenfalls, weil es sich um eine auf der Schnittstelle Node angesiedelte Eigenschaft handelt, sind aus Sicht von nextSibling alle Objekte einfach nur Knoten. Das heißt, wenn wie hier im Quelltext auf das Kontextobjekt Whitespace folgt, dann wird dieser zu einem Textknoten geparst, und da es sich dabei um einen Knoten handelt, wird dieser von der Eigenschaft nextSibling referenziert.

              Das ist aber natürlich nicht das, was eigentlich gewünscht ist, denn eigentlich soll ja das nächste Geschwisterelement referenziert werden und kein Textknoten. Dementsprechend ist nextSibling hier von vorneherein die falsche Wahl gewesen.

              Besser wäre es gewesen, die Eigenschaft nextElementSibling zu verwenden, die sowohl von der Schnittstelle Element als auch von der Schnittstelle CharacterData implementiert wird, und somit auf Element- und Textknoten angesprochen werden kann. Diese Eigenschaft referenziert nicht allgemein den nächsten Geschwisterknoten, sondern das nächste Geschwisterelement.

              Es gibt auch für andere Eigenschaften der Schnittstelle Node Entsprechungen, bei denen nicht allgemein Knoten, sondern ausschließlich Elemente referenziert werden. Zum Beispiel gibt es neben previousSibling auch die Eigenschaft previousElementSibling, welche das vorangehende Geschwisterelement enthält, für den Fall, dass ein solches vorhanden ist.

              Darüber hinaus können statt der von Node vererbten Eigenschaften firstChild und lastChild die Eigenschaften firstElementChild und lastElementChild angesprochen werden, die im Gegensatz zu den erstgenannten Eigenschaften ausschließlich Elemente referenzieren.

              Die von Node vererbte Eigenschaft childNodes gibt eine NodeList mit Kindknoten zurück, also auch mit Textknoten. Die unter anderem von Elementen implementierte Eigenschaft children hingegen gibt eine HTMLCollection zurück, die nur Elementknoten enthält.

              Wenn man also schon Elemente über Eigenschaften referenzieren möchte, und nicht auf Methoden wie beispielsweise querySelector zurückgreifen will, was meist die bessere Wahl ist, dann ist es hilfreich zu wissen, welchem Zweck die jeweiligen Eigenschaften dienen.

              Viele Grüße,

              Orlok

              1. Hallo Orlok,

                Wenn du einen Browser findest der den Whitespace nicht interpretiert, solltest du den Bug melden.

                Ich kann mich noch erinnern, dass dies früher je nach Browser unterschiedlich war, dürfte aber dann wohl mittlerweile behoben sein.

                Besser wäre es gewesen, die Eigenschaft nextElementSibling zu verwenden, die sowohl von der Schnittstelle Element als auch von der Schnittstelle CharacterData implementiert wird, und somit auf Element- und Textknoten angesprochen werden kann. Diese Eigenschaft referenziert nicht allgemein den nächsten Geschwisterknoten, sondern das nächste Geschwisterelement.

                Absolut richtig 😉 "nextElementSibling" wäre weitaus sinnvoller, wenn man es denn überhaupt so nutzen möchte.

                Gruss
                Henry

  2. @@Peter Z.

    Bei Click oder mouseover auf kleinem Bild Vergrößerung anzeigen.

    Das funktioniert aber nur mit Maus; nicht mit Tastatur; img-Elemente sind nicht anclickbar.

    … wo das große Bild in CSS zunächst über width-Angaben verkleinert wurde und dann bei Hover die Normalgröße angezeigt wurde. Da wird aber doch sofort das große Bild geladen?

    Ja.

    Kann man eventuell wenn die Seite mit den kleinen Bildern aufgebaut ist im Hintergrund schon die Originalbilder laden?

    Ja.

    Kann so aussehen:

    <ul id="myGallery">
    	<li>
    		<a href="https://upload.wikimedia.org/wikipedia/commons/5/5b/Mandel_zoom_03_seehorse.jpg">
    			<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/5b/Mandel_zoom_03_seehorse.jpg/320px-Mandel_zoom_03_seehorse.jpg" alt="Mandel zoom 03 seehorse"/>
    		</a>
    	</li>
    	<li>
    		<a href="https://upload.wikimedia.org/wikipedia/commons/8/82/Mandel_zoom_05_tail_part.jpg">
    			<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/82/Mandel_zoom_05_tail_part.jpg/320px-Mandel_zoom_05_tail_part.jpg" alt="Mandel zoom 05 tail part"/>
    		</a>
    	</li>
    	<li>
    		<a href="https://upload.wikimedia.org/wikipedia/commons/b/b3/Mandel_zoom_07_satellite.jpg">
    			<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b3/Mandel_zoom_07_satellite.jpg/320px-Mandel_zoom_07_satellite.jpg" alt="Mandel zoom 07 satellite"/>
    		</a>
    	</li>
    	<li>
    		<a href="https://upload.wikimedia.org/wikipedia/commons/a/a4/Mandel_zoom_11_satellite_double_spiral.jpg">
    			<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Mandel_zoom_11_satellite_double_spiral.jpg/320px-Mandel_zoom_11_satellite_double_spiral.jpg" alt="Mandel zoom 11 satellite double spiral"/>
    		</a>
    	</li>
    </ul>
    <footer>Images created by Wolfgang Beyer with the program Ultra Fractal 3.</footer>
    
    <script>
    	const myGalleryLinks = document.querySelectorAll('#myGallery a');
    	
    	for (let i = 0; i < myGalleryLinks.length; i++)
    	{
    		fetch(myGalleryLinks[i].href);
    	}
    </script>
    

    a-Elemente sind per Tastatur (Tab-Taste) erreichbar; du kannst click-Events dafür registrieren und mittels Event.preventDefault() das Aufrufen einer neuen Seite unterbinden und stattdessen bspw. ein Lightbox-Script laufen lassen.

    Ohne JavaScript würde jetzt auch das große Bild geladen und dargestellt werden.

    LLAP 🖖

    --
    “When UX doesn’t consider all users, shouldn’t it be known as ‘Some User Experience’ or... SUX? #a11y” —Billy Gregory
  3. Hallo Peter Z.,

    Wie kann ich zunächst eine kleine Kopie des Bildes anzeigen und dann beim Überfahren an der selben Stelle das Originalbild anzeigen.

    Bedenke, dass dadurch eine große Unruhe auf der Seite entsteht. Suchst du vielleicht so etwas wie lightbox?

    Bis demnächst
    Matthias

    --
    Rosen sind rot.
    1. Liebe Spezialisten, leider sehe ich nun vor lauter Bämuen den Wald nicht mehr! Kann mir jemand schreiben, wo ich ein möglichst einfaches - und funktionierendes - Beispiel finde. Wie Henry schreibt, funktioniert ja das Beispiel in Selfhtml auch nicht. Wäre schön, wenn man dies dann korrigeren könnte. Danke Peter

      1. Hallo Peter,

        Kann mir jemand schreiben, wo ich ein möglichst einfaches - und funktionierendes - Beispiel finde.

        Wenn's ums zentrieren geht: Das hatte Gunnar schon gemacht (achte auf normale Wörter hier, die zum Link gemacht werden, geht manchmal unter), also siehe Beispiel Gunnar.

        Wenn's ums Ganze geht:
        Da hatte Matthias dir diese jquery-Lösung vorgeschlagen.

        Gruss
        Henry