Tim Tepaße: Beispiel für unobstrutive DOM Scripting: Popups

Beitrag lesen

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

--
Sie lasen einen Beitrag aus der neuen Reihe „Tim rezensiert Webtechnik, die ihm gerade so unterkommt“