Beispiel für unobstrutive DOM Scripting: Popups
Tim Tepaße
- javascript
Hallo,
so ziemlich alle Bildergallerien haben das Problem, eine Funktion anzubieten, Bilder größer darzustellen, nach den üblichen Gewohnheiten durchaus durch einen Klick auf das Bild selber. Auf eine nette Lösung bin gerade zufällig gestoßen, eine Gallerie von Screenshots einer Mac-Software:
http://kula.jp/software/endo/screenshots/
(JS aktiviert haben, auf den Link klicken, fertig laden lassen, ausprobieren. Ich warte dann so lange)
Kleines Problem: Bei mir zumindest funktioniert es nicht in Opera, dies aber wahrscheinlich nicht aus grundsätzlichen Gründen, sondern wegen irgendeines programmiertechnischen Fehlers. Und das Layout verrutscht im Firefox 1.5. Aber lassen wir das mal beiseite.
Grundsätzlich ist es nämlich ein Paradebeispiel dafür, wie Javascript nach dem derzeitigen Diskussionsstand eine Seite „verbessern“ sollte. Hat man Javascript deaktiviert, merkt man nichts von dem Effekt, ein Klick auf ein Bild lädt den Screenshot direkt als eigene Ressource, so wie man es gewöhnt ist. Guckt man in den Quellcode sind nicht mal hart eingebaute Event-Handler vorhanden. Der ganze Spaß beruht nämlich auf zwei Dingen, der eingebundenen screenshot.js und das es in der (verbesserungswürdigen) Div-Suppe der Seite ein Container-Element mit der ID „screenshots“ gibt.
Das Skript registriert zwei onload-Handler - mit der eigenen, eher primitiven addLoadEvent()-Funktion aus global.js, bei der ich vermute, dass es an ihr liegt, dass Opera rumzickt. Beide Handler kommen nur dann zum Einsatz, wenn die benötigten JS-Funktionalitäten und die Existenz eines Elementes mit der ID „screenshot“ vorhanden sind. Wenn nicht, dann nicht.
Wenn doch, dann wird die bislang reine HTML-Struktur der Seite genutzt und zu etwas größerem umgemodelt. Der erste Handler – preparePlaceholder() – sorgt dafür, dass im DOM-Baum ein zusätzliches, im Normalfall dank display:block; bislang nicht sichtbares Element existiert. Diese mit CSS gestaltete zusätzliche Ebene wird nachher die Anzeigeebene, die, die dafür sorgt, dass die Seite „verdunkelt“ und das Bild darüber angezeigt wird. Der zweite Handler sorgt dafür alle Verweise der konkreten Screenshots mit onclick-Handlern auszustatten, also erst jetzt die Seite JS-fähig dafür zu machen.
Der Rest ist simpel, bei einem Klick wird die Placeholder-Ebene sichtbar gemacht, in ihr das Bild geladen und natürlich ein (geklautes) Symbol für „Mach das wieder weg“ eingefügt. Der größte Teil des Codes dort beschäftigt sich damit, das absolut positierte Bild auch richtig zu positionieren. Und natürlich nehmen die sehr ausführlichen DOM-Methoden Platz weg. Laangweilig.
Die konkrete Umsetzung ist natürlich noch verbesserungsfähig¹, aber das wesentlich Bemerkenswerte finde ich daran: Man hat eine gegebene, kontrollierbare Struktur im HTML - als Seitenautor hat man eh eine Kontrolle darüber. Und nur durch eine überlegte Struktur und durch ein relativ simples Skript kann man haufenweise Elemente mit einem zusätzlichen Verhaltensmuster ausstatten.
..
¹ Verbesserungsfähige Dinge, die mir so spontan auffallen:
• Eine größere Entkoppelung von der darunterliegenden HTML-Struktur, d.h. kein Containerelement mit rigider Struktur darunter, sondern Verweise der Art <a ... class="popup"><img /></a>.
• Eine intuitive GUI dafür. Die derzeitige ist von Apples Dashboard geklaut, das dürfte für Nicht-Mac-Benutzer nicht unbedingt sofort einleuchtend sein. Das Verdunkeln natürlich, aber die konkrete Darstellung des Bildes könnte man verändern, einen Rahmen zur besserne Abgrenzung, den Schließ-Button an die intuitivere rechte obere Seite des Bildes stellen.
• Die konkrete Positionierung des Bildes bzw. des halbtransparenten Layers könnte geschickter mit CSS-Regeln geregelt werden, anstatt dämliche Berechnungen mit konkreten Pixelwerten in JS zu machen. position:fixed, position:absolute schwebt einem da vor. Wobei ich keine Ahnung habe, ob es derzeit eine Möglichkeit gibt, ein Element ohne Kenntnis seiner Größe im Vierport zu zentrieren.
• Die „Barrierefreiheit“ ist für die Mein-Browser-Gehört-Mir-Rufer hier im Forum ja nicht mehr gegeben, weil sie die größeren Bilder z.B. nicht in neuen Tabs öffnen können. Eine nachträglich eingefügte Checkbox „[x] In Popups öffnen“ anhand deren Wert die Funktion showPic() ausgeführt wird oder eben nicht wäre da ein Kompromiss.
• Das Skript nutzt derzeit einen dämlichen Trick um die für die Positionierung benötigten Höhen- und Breitenangaben der vergrößterten Bilder herauszukriegen, diese stehen im Title-Attribut des kleineren Bildes. Sollte man auf diese Angabe nicht verzichten können, hat man ein Problem. Das Title-Attribut sowohl des Bildes als auch des Links ist definitiv der falsche Ort dafür. HTML ist leider rigide darin, beim Vorhandensein von Elementen und Attributen aus anderen Namensräumen invalide zu werden, ansonsten wären eigene Attribute ein passender Ort dafür, z.B. so:
<a href="bild.jpg class="popup" myns:width="600px" myns:height="400px"><img src="bild-klein.jpg" /></a>
Ansonsten geht es natürlich auch bei serverseitig generierter Ausgabe einfach die benötigten Metadaten in der Seite in einem Skript-Bereich unterzubringen:
<script type="text/javascript">
// <![CDATA[
[code lang=javascript]popups = [
{subtitle:"eins", width:"600px", height:"400px"},
{subtitle:"zwei", width:"600px", height:"400px"},
{subtitle:"drei", width:"600px", height:"400px"},
];
// ]]>
</script>[/code]
Wobei dabei das Prinzip, sich sämtliche benötigten Informationen aus der HTML-Struktur zu holen, wieder unterlaufen wird, ja.
• Nicht unbedingt barrierefrei, denkt man an arme Modemnutzer, aber dennoch bequem: Alle Bilder versteckt vorladen.
Tim
Hallo Gunnar,
so ziemlich alle Bildergallerien haben das Problem, eine Funktion anzubieten, Bilder größer darzustellen, nach den üblichen Gewohnheiten durchaus durch einen Klick auf das Bild selber. Auf eine nette Lösung bin gerade zufällig gestoßen ...
Man sollte nie einen längeren Beitrag hier schreiben, ohne sich vorher in #selfhtml abzusprechen und nach Erfahrungen zu fragen:
<molily> hm, dazu nutzt man doch lightbox,. nicht mitbekommen?
<Tim> Lightbox?
<molily> lightbox.js. DER renner in letzter zeit.
<molily> hat innerhalb von wochen tausende bookmarks bei delicious bekommen.
<molily> ging doch alle zeitungen^Wblogs
<Tim> Ich krieg nix mehr mit.
...
<molily> vorteil: lightbox funktioniert ;)
Und da hat er recht. ;)
Tim
Hallo Tim,
so ziemlich alle Bildergallerien ...
^^
ich fasse es nicht: Du jetzt auch schon?
eine Gallerie von Screenshots einer Mac-Software:
^^
Was hast du nur an der Galle?
So long,
Martin
Hallo Tim.
Ein nettes Script, durchaus.
Aber hattest du die hier schon oft angepriesenen Lightbox und Felix' Pendant mitbekommen?
Diese beiden sind in Bezug auf einige deiner Kritikpunkte weitaus raffinierter umgesetzt worden.
Unaufdringliches (ich schätze den deutschen Begriff) JS nimmt auch in meinen eigenen Entwicklungsmethoden immer mehr Raum ein.
Das einzige wirkliche Problem neben der nötigen Unterstützung der genutzten Methoden ist aber noch immer die eindeutige Identifizierung des Wirkungsbereiches dieser Scripte. Hierzu ist nach wie vor eine spezielle Auszeichnung des Markups erforderlich. Wenn rein strukturell bereits eine solche Möglichkeit gegeben ist, besteht dagegen kein Problem.
Alternativ kann natürlich auch die gesamte Identifizierung per JS stattfinden, was aber mitunter recht aufwendig, rechenlastig und ggf. fehlerträchtig ist.
Alles in allem bin ich aber der Meinung, dass unaufdringliches JS ein sehr gutes Konzept darstellt und hoffe, dass sich der Nutzen dieses Konzeptes verbreitet.
Einen schönen Freitag noch.
Gruß, Ashura
Hallo Tim!
so ziemlich alle Bildergallerien haben das Problem, eine Funktion anzubieten, Bilder größer darzustellen, nach den üblichen Gewohnheiten durchaus durch einen Klick auf das Bild selber. Auf eine nette Lösung bin gerade zufällig gestoßen, eine Gallerie von Screenshots einer Mac-Software:
http://kula.jp/software/endo/screenshots/
(JS aktiviert haben, auf den Link klicken, fertig laden lassen, ausprobieren. Ich warte dann so lange)
So nett finde ich die Lösung aber nicht: Wieso muss ich denn zum Ausblenden eines Bildes auf dieses unauffällige Kreuz klicken? Rein intuitiv habe ich natürlich erst einmal auf den roten Button oben links im Screenshot geklickt und leider passierte nichts. Der Trichter-Effekt funktionert leider auch nicht :-(
¹ Verbesserungsfähige Dinge, die mir so spontan auffallen:
[…]
• Eine intuitive GUI dafür. Die derzeitige ist von Apples Dashboard geklaut, das dürfte für Nicht-Mac-Benutzer nicht unbedingt sofort einleuchtend sein. Das Verdunkeln natürlich, aber die konkrete Darstellung des Bildes könnte man verändern, einen Rahmen zur besserne Abgrenzung, den Schließ-Button an die intuitivere rechte obere Seite des Bildes stellen.
Hey, wenn eine GUI intuitiv ist, dann die des Macs! Aber der Schließbutton sollte besser hervorgehoben werden (und vielleicht der rote Button für uns zusätzlich ;-) ). Das mit der rechten oberen Seite ist Geschmackssache, denke ich: Da die Links zu den Screenshots eher links angeordnet sind, hat man nach dem Laden des vergrößerten Bildes immer noch seine Maus an dieser Stelle.
BTW: Interessant zu sehen, wie Dashboard aussieht (hab noch Panther auf dem Mac). Aber von Expose kennt man so ein Look&Feel ja auch schon.
• Die konkrete Positionierung des Bildes bzw. des halbtransparenten Layers könnte geschickter mit CSS-Regeln geregelt werden, anstatt dämliche Berechnungen mit konkreten Pixelwerten in JS zu machen. position:fixed, position:absolute schwebt einem da vor. Wobei ich keine Ahnung habe, ob es derzeit eine Möglichkeit gibt, ein Element ohne Kenntnis seiner Größe im Vierport zu zentrieren.
Schuss ins Blaue: Wie wäre es denn mit text-align: center; vertical-align: center;
(<http://de.selfhtml.org/css/eigenschaften/ausrichtung.htm@title=CSS-Eigenschaften für Ausrichtung und Absatzkontrolle>) oder margin: auto;
(<http://de.selfhtml.org/css/eigenschaften/randabstand.htm@title=Außenrand und Abstand>).
• Die „Barrierefreiheit“ ist für die Mein-Browser-Gehört-Mir-Rufer hier im Forum ja nicht mehr gegeben, weil sie die größeren Bilder z.B. nicht in neuen Tabs öffnen können. Eine nachträglich eingefügte Checkbox „[x] In Popups öffnen“ anhand deren Wert die Funktion showPic() ausgeführt wird oder eben nicht wäre da ein Kompromiss.
Diese Lösung wäre durchaus sinnvoll. Aber das mit dem neuen Tab ist doch auch kein Problem: Kontextmenü → Bildadresse kopieren, dann ein neuer Tab und Einfügen.
Viele Grüße,
Robert
Hallo Robert.
So nett finde ich die Lösung aber nicht: Wieso muss ich denn zum Ausblenden eines Bildes auf dieses unauffällige Kreuz klicken? Rein intuitiv habe ich natürlich erst einmal auf den roten Button oben links im Screenshot geklickt und leider passierte nichts.
Die meiner Meinung nach beste Lösung ist die, die Lightbox anbietet: will man das Bild wieder schließen, klickt man einfach darauf. (Bei einer solch großen Trefferfläche kann man dann auch nicht mehr danebenklicken.)
Einen schönen Samstag noch.
Gruß, Ashura
Moin!
So nett finde ich die Lösung aber nicht: Wieso muss ich denn zum Ausblenden eines Bildes auf dieses unauffällige Kreuz klicken? Rein intuitiv habe ich natürlich erst einmal auf den roten Button oben links im Screenshot geklickt und leider passierte nichts.
Die meiner Meinung nach beste Lösung ist die, die Lightbox anbietet: will man das Bild wieder schließen, klickt man einfach darauf. (Bei einer solch großen Trefferfläche kann man dann auch nicht mehr danebenklicken.)
Da hast du natürlich Recht, wobei es immer noch nicht die Macht der Gewohnheit bei Screenshots von Mac-Software bekämpft ;-)
Einen schönen Samstag noch.
Gleichfalls und viele Grüße,
Robert
Hallo Tim!
Verbesserungsfähige Dinge, die mir so spontan auffallen:
• Die konkrete Positionierung des Bildes bzw. des halbtransparenten Layers könnte geschickter mit CSS-Regeln geregelt werden, anstatt dämliche Berechnungen mit konkreten Pixelwerten in JS zu machen. position:fixed, position:absolute schwebt einem da vor. […]
Das wäre eine gute Idee: Die Seite ist augenscheinlich für Safari optimiert oder Gecko-Browser setzen etwas nicht standardkonform um (wie die verlinkten Screenshots zeigen).
Viele Grüße,
Robert