Dr.Web - Das Online Magazin für Seitenbetreiber

Das Leselineal - Lese- und Navigationshilfe für umfangreiche Online-Dokumente

Werbung

von Horst Klier

Lange Texte sind am Bildschirm schwer zu lesen - das gilt auch in Zeiten von 30-Zoll-Monster-Bildschirmen noch. Ein vorbildlicher Seitenbetreiber versucht es seinen Besuchern so einfach wie möglich zu machen. Unser Leselineal soll neben der reinen Lesbarkeit auch die Navigation durch einen besonderen Kniff unterstützen.

Ich habe bei Kollegen und auch bei mir selbst beobachtet, dass bei langen Texten am Bildschirm und vor allem bei langen Zeilen der Mauszeiger als Hilfsmittel benutzt wird. Teilweise werden Worte der aktuellen Zeile markiert, um dem Auge eine bessere Führung zu geben. Also lag die Idee nahe, einfach per Javascript die aktuelle Zeile farbig zu hinterlegen. Genau das ist das auch die Funktion des Leselineals: ein farbiger Balken hinter dem Text, der sich mit der Maus bewegen lässt.

Screenshot

Da es vorkommen kann, dass sich jemand dadurch gestört fühlt, benötigen wir auch eine Möglichkeit das Lineal abzuschalten. Das sollte dann aber nicht nur für die aktuelle Seite, sondern für alle Seiten gelten. Also merken wir uns das mit einem Cookie. Und wenn wir schon dabei sind, können wir zusätzlich die Möglichkeit anbieten, das Leselineal auf einer Seite zu fixieren und auch das per Cookie zu speichern. Das macht auch wirklich Sinn.

Entwickelt wurde das Leselineal für den Ernährungsratgeber Leben ohne Diät, der komplett online angeboten wird. Nun wird kaum jemand mehrere Stunden am Stück das Buch lesen. Wie merkt er sich aber die Stelle, bis zu der er schon gekommen war? Sicherlich hat er ein Lesezeichen im Browser auf die Website gesetzt, aber wird er das jedes mal ändern, wenn er ein Stück weiter gelesen hat? Das lässt sich mit unserem Leselineal eleganter lösen. Wir fragen einfach beim Laden jeder Seite ab, ob das Leselineal auf einer anderen Seite fixiert ist und bieten an direkt dorthin zu springen. Das Besondere dabei: diese Abfrage kann sogar auf Seiten eingebaut werden, die selbst das Leselineal nicht verwenden.

Ffangen wir an. Um das Leselineal zu erzeugen verwenden wir einfach einen DIV-Container, der mittels Z-Index unter dem eigentlichen Inhalt platziert wird. Dieser sollte höher als eine Textzeile sein, was nur durch einen kleinen Trick wirklich allen Browsern beizubringen ist: wir benutzen ein non-breaking-space mit einer Schriftgröße von 180%. Auf der rechten Seite wollen wir eine kleine Grafik, die das Menü aufklappen soll.

Um den Platz zu schaffen, den diese Grafik benötigt, soll beim eigentlichen Text ein kleiner Rand hinzugefügt werden. Dazu wird dieser ebenfalls in einen DIV-Container gesteckt und diesem auch ein onmousemove-Ereignis zugewiesen, um die Mausbewegung verarbeiten zu können. Da sich Inhalt und Leselineal überlagern, benötigen wir dasselbe Ereignis auch auf dem Leselineal selbst und sogar auf der darin enthaltenen Grafik. Manche Browser sind eben ganz schön zickig, was das Weiterleiten von Ereignissen betrifft. Komplett sieht das dann in etwa so aus:

 <div id="leselineal" style= "text-align:right; height:2em;
border-bottom: 1px solid
#B1DBA4; position:relative;top:0px;left:0px; width:100%; background-color:#EBF6E8; z-index:1; vertical-align:middle;">
<span onmousemove="Mausmove(event)"
style="font-size:180%;"> </span><img
style="vertical-align:middle; margin-top:-4px;"
onmousemove="Mausmove(event)" src="/images/leselineal-menu.gif">
</div>
<div id="content" onmousemove="Mausmove(event)"
style="position:relative;z-index:3; padding-right:16px; padding-bottom:3em;">
...der eigentliche Inhalt...
</div>

Wer genau hinsieht, wird feststellen, dass das Leselineal mit position:relative formatiert ist, um es später verschieben zu können. Außerdem ist beim eigentlichen Inhalt (im Container "content") auch unten ein Rand. Dieser dient dazu, das Lineal abzulegen, wenn es deaktiviert wurde. So ist es wenig störend am unteren Bildschirmrand und doch ist das Menü noch erreichbar um es wieder aktiveren zu können. Das Leselineal selbst hat einen farbigen Hintergrund und der untere Rand ist in einer anderen Farbe hervorgehoben. Wie es im Einzelfall ausgestaltet wird, hängt vom Design ab.

Für die Bewegung selbst ist nun das Ereignis mausmove zuständig. Dort wird die Mausposition abgefragt und der Leselineal an die entsprechende Position bewegt. Das ganze ist leider nicht ganz so trivial, weil die Mausposition relativ zum Fenster geliefert wird. Also muss man auch noch die Position des Objektes selbst sowie eventuell benutzte Scrollbalken mit einbeziehen. Etwa so:

      function Mausmove (Ereignis) {
if (fixed==0) {
pagey = scrollY();
y=pagey+Ereignis.clientY-findPosY(document.
getElementById('content'));
y=y+(document.getElementById('leselineal').offsetHeight
/ 2)
document.getElementById('leselineal').style.top
= y+'px';
  };
};

Wobei scrollY eine Funktion ist, welche die Position des vertikalen Scrollbalkens browserübergreifend liefert und findPosY liefert die Y-Position des angegebenen Objektes. Hilfsfunktionen wie diese beiden hier aufzuführen, würde den Rahmen sprengen. Sie können Sie im beigefügten Quelltext in ganzer Pracht bewundern. Damit das Leselineal auch hübsch zentriert dargestellt wird, addieren wir auch noch die halbe Höhe des Elements selbst. Die ganze Bewegung ist in eine Abfrage gefasst, die einfach eine globale Variable abfragt. So ist es uns später einfach möglich das Leselineal zu fixieren.

Im Grunde sind wir mit der Grundfunktion schon fertig und können uns dem Menü zuwenden. Dieses besteht aus einem vorgefertigten DIV-Container, der einfach an passender Stelle eingeblendet wird. Darin enthalten sind simple Links, die dann entsprechende Funktionen auslösen. Da sich die Menüpunkte je nach Zustand des Lineals auch ändern können, sind diese mit Ids versehen, um sie bei Bedarf leicht ein und ausblenden zu können.

      <div onmouseout="MenuAusblenden(event)" style="padding:2px;border:
1px solid
#B1DBA4;width:16em;position:absolute;top:0px;left:0px;
visibility:hidden; display:block; z-index:4; background-color:#EBF6E8;">
<div id="jumplineal"
style="display:none;line-height:180%;"><span
style="display:block;padding:4px; padding-left:8px;">Das Leselineal
ist auf der Seite<br>
"<span class="highlighted">Aus Cookie holen</span>"
fixiert.</span>
<a class="llm" href="javascript:JumpLineal(null);">Zum Leselineal
springen</a>
</div>
<a id="fixlineal" class="llm" href="javascript:FixLineal('Ein guter
Seitentitel');">Leselineal fixieren</a>
<a id="freelineal" style="display:none;" class="llm"
href="javascript:FreeLineal();">Leselineal lösen</a>
<a id="aktlineal" style="display:none;" class="llm"
href="javascript:AktLineal();">Leselineal aktivieren</a>
<hr size="1" color="#B1DBA4">
<a class="llm" href="javascript:UeberLineal();">über das
Leselineal</a>
<a id="deaktlineal" class="llm"
href="javascript:DeaktLineal();">Leselineal deaktivieren</a>
</div>

Was auffällt, ist der Text am Anfang des Menüs. Dieser wird immer dann eingeblendet, wenn das Menü auf einer anderen Seite fixiert wurde. Damit der Benutzer auch weiß, auf welcher Seite das ist, geben wir den Titel und nicht nur die URL an. Dieser Titel sollte möglichst aussagekräftig sein, weshalb wir diesen explizit für das Leselineal angeben und nicht einfach den Seitentitel auslesen. Er wird dann später beim Fixieren in einem Cookie mitgeführt.

Wo wir gerade dabei sind, machen wir das Cookie doch komplett. Wir speichern den Seitentitel, die URL der Seite und die Y-Position, an der das Lineal fixiert wurde. Und falls das Lineal deaktiviert wurde, merken wir uns das auch, dass war ja schließlich ursprünglich überhaupt der Grund für das Menü und den Cookie. Speichern, auslesen und löschen machen drei kleine Hilfsroutinen, die man im kompletten Quelltext leicht findet.

Das Menü soll eingeblendet werden, wenn der Mauszeiger über das Grafiksymbol bewegt wird. Also einfach ein onmouseover auf die Grafik und fertig. Das wäre schön, aber Firefox bemerkt nicht, dass wir die ganze Zeit schon das Lineal bewegen. Das heißt, er erkennt das onmouseover nur an der ursprünglichen Position des Leselineals. Aber halb so schlimm, denn wenn sich das Leselineal mit dem Mauszeiger bewegt, befindet sich das Symbol auf dem Lineal sowieso immer auf gleicher Höhe. Wir müssen also nur noch den X-Wert in unserer Mausmove-Funktion zusätzlich abfragen. Also blenden wir unser Menü wie folgt ein:

      x=pagex+Ereignis.clientX-findPosX(document.
getElementById('content'));
x=x-document.getElementById('leselineal').offsetWidth;
if (x>=-16) {
  document.getElementById('linealmenu').style.visibility =
'visible';
  document.getElementById('linealmenu').style.top =
findPosY(document.getElementById('leselineal'))+'px';
  document.getElementById('linealmenu').style.left =
(findPosX(document.getElementById('leselineal'))+
document.getElementById('leselineal').offsetWidth-16)+'px';
};

Zum Ausblenden reicht eigentlich das onmouseout-Ereignis im Menü-Container. Aber auch hier zicken wieder die Browser. Firefox löst onmouseout auch aus, wenn innerhalb des Menüs ein Link verlassen wird. Deshalb fragen wir beim Ereignis sicherheitshalber nochmal die Koordinaten der Maus ab, ob diese auch wirklich außerhalb des Menü-Bereiches sind. Dummerweise ist es damit aber wiederum beim IE möglich nach oben zu entwischen. Um dem zu entgehen wird in der Hauptroutine nicht nur die X-Position abgefragt, sondern zusätzlich auch die Y-Koordinate mit einbezogen. Das läuft dann in allen Browsern sehr stabil. Im Quelltext können Sie die notwendigen Abfragen leicht sehen.

Nun zu den einzelnen Funktionen des Linealmenüs. Belassen wir es bei einer kurzen Beschreibung, die Funktionen sind allesamt übersichtlich und im Quelltext kommentiert. Jede Funktion ändert auch das Menü durch ein- und ausblenden von Menüpunkten und blendet das Menü selbst ebenfalls aus. Darauf gehen wir aber an dieser Stelle nicht explizit ein.

FixLineal
Das Lineal wird an der aktuellen Position fixiert. Dazu wird die globale Variable fixed als Flag gesetzt und zusätzlich wird die aktuelle Position zusammen mit Seitentitel und URL als Cookie abgelegt.

FreeLineal
Das ist die genaue Umkehrfunktion zum Fixieren. Die globale Variable wird wieder auf 0 gesetzt. Zusätzlich werden alle Cookies gelöscht.

DeaktLineal
Das Lineal wird deaktivert. Dazu wird es an einer Y-Position unterhalb des content-Containers fixiert. Ein Cookie sorgt dafür, das die Deaktivierung erhalten bleibt.

AktLineal
Das Deaktivierungs-Cookie wird gelöscht und die Fixierung wieder freigegeben.

UeberLineal
Ein Fenster mit einer kurzen Beschreibung des Leselineals wird eingeblendet. Wenn ich hier Fenster sage, dann meine ich schlicht einen vordefinierten DIV-Container namens ueberlineal, der zentriert über der Seite angezeigt wird ("über" meint hier nicht in Y-, sondern in Z-Richtung). Damit dieser auch nicht übersehen wird, platzieren wir über der Seite aber unter dem Container noch ein, auf Seitengröße erweitertes, schwarzes DIV. Bei diesem schalten wir die Transparenz auf 30% und haben dadurch den eigentlichen Seiteninhalt gegenüber unserem Hinweis-Fenster abgedunkelt. Weil es so schön ist, machen wir doch noch ein kleines zweites DIV, das genauso groß wie das Hinweis-Fenster ist, aber um ein paar Pixel nach unten und rechts verschoben dargestellt wird. Dies auch in schwarz und mit einer Transparenz von 10% ausgestattet erzeugt einen kaum merklichen Schatten. Die Routine zum Anzeigen packen wir gleich in eine kleine Hilfsfunktion namens ShowLinealWindow, der wir nur noch den Namen des anzuzeigenden DIV-Containers übergeben. Diese Routine brauchen wir später nämlich nochmal. Die UeberLineal-Funktion besteht also lediglich aus dem Aufruf dieser Routine.
Der ueberlineal-Container enthält neben schlichtem Hinweistext nur zwei kleine Schließbuttons, die schlicht und einfach die 3 Container wieder ausblenden.

Jetzt fehlt eigentlich nur noch ein zweites Info-Fenster. Nämlich wenn der Anwender das Lineal auf einer anderen Seite als der aktuellen fixiert hat, soll direkt nach dem Laden ein entsprechender Hinweis "Sie haben das Leselineal auf der Seite xyz fixiert. Wollen Sie jetzt zu der Seite springen?" erscheinen. Das funktioniert im Prinzip wie beim "ueberlineal", es gibt lediglich ein paar mehr Buttons für den Anwender. Das sind:

  • Ja: hier wird zu der Seite mit dem Leselineal gesprungen
  • Jetzt nicht: Deaktivert das Leselineal für die aktuelle Seite, das heißt, es wird deaktiviert, aber kein Deaktivierungs-Cookie gesetzt
  • Fixierung löschen: ruft die bereits bekannte Funktion FreeLineal auf
  • Leselineal deaktivieren: Deaktivert das Leselineal

Dass war's, zumindest bis auf eine Kleinigkeit. Im Moment brauchen wir eine Menge vorgefertigter DIV-Container und sogar spezielle Styles für die Menülinks. Das ist schon ein wenig aufwändig in jede Seite richtig einzubinden. Gibt es dafür nicht auch ein JavaScript?

Natürlich gibt es das. Wir können alle benötigten DIVs und Styles auch zur Laufzeit erzeugen. Das geht dann sogar mit ein wenig Intelligenz. Wenn im aktuellen Dokument ein Bereich mit der ID "content" definiert ist, dann wird das Leselineal aktiviert. Falls nicht, wird lediglich die Prüfung der Cookies durchgeführt und eventuell der Hinweis angezeigt, um auf die Seite springen zu können, auf der das Lineal fixiert wurde. Die Funktion zum erzeugen der DIVs ist im Quelltext als GenLeselinealDivs und die Funktion für die Styles als GenLeselinealStyles zu finden. Das Mausereignis für den content-Container wird in AddMousemoveToContent zugewiesen. Wichtig wäre hier nur der Hinweis, dass man beim Erzeugen eines DIV immer erst den kompletten Inhalt in einer String-Variable sammeln muss, bevor man ihn mit innerHTML zuweist. Firefox würde bei halbfertigem Code nämlich immer automatisch geöffnete Tags wieder schließen. Und beim Erzeugen der Styles benötigt man zwei verschiedene Routinen, da IE und Firefox hier einen komplett anderen Befehl besitzen und sich auch bei der Behandlung der Angaben leicht unterscheiden.

Das ganze Script lagern wir dann in eine eigene JS-Datei aus. Auf einer Seite, die das Leselineal benutzt, wird lediglich das Script im HTML-Header eingebunden:

      <script src="leselineal.js"></script>
Und zur Aktivierung wird im Body ein onload definiert:
<body onload="LeselinealInit('Titel der aktuellen Seite')">
Zu guter Letzt muss noch der eigentlich Text-Inhalt in einen Container
mit Namen "content" gefasst werden:
<div id="content"
style="position:relative; z-index:3; padding-right:16px; padding-bottom:3em;">
...
</div>

Letzteres spart man sich einfach auf Seiten, bei denen das Leselineal selbst nicht erscheinen soll.

Der komplette Quelltext ist gut kommentiert. Wer das Leselineal in Aktion sehen möchte, der ist herzlich eingeladen auf leben-ohne-diaet zu schmökern. (tm)

Quellcode mit Grafik zum Download (ZIP-Archiv)

Erstveröffentlichung 13.11.2006

Verwandte Artikel

Bookmarken! Diese Icons verlinken auf Bookmark Dienste bei denen Nutzer neue Inhalte finden und mit anderen teilen können.
  • MisterWong
  • del.icio.us
  • TwitThis
  • Hype
  • StumbleUpon
  • Facebook
  • Google Bookmarks
  • Linkarena
abstimmenabstimmenabstimmenabstimmenabstimmen (No Ratings Yet)

1 Kommentar zu “Das Leselineal - Lese- und Navigationshilfe für umfangreiche Online-Dokumente”

  1. 1
    Nils
    6.12.2008 19:57

    Hallo,
    ich bin kürzlich auf dieses Leselineal gestoßen und muss sagen: ich bin begeistert!
    Gibt es das ganze inzwischen als Plugin für Opera, um damit im ganzen Internet zu surfen?
    So eine geniale, einfache Idee!

    Großes Lob,
    Nils

    Antwort

Meine Meinung

Bitte beachten Sie: Werbung und Spam sind unerwünscht und können eine Rechnung zur Folge haben. Woher kommen die Bilder neben den Kommentaren?