c't 10/99
So sehr sich auch die beiden großen Hersteller von WWW-Browsern mit Features zu übertrumpfen suchen, ein paar Kleinigkeiten fehlen immer noch. Zum Glück gibt es jedoch Möglichkeiten, fehlende Befehle über JavaScript nachzurüsten.
Moderne Browser bringen eigentlich alles mit, was man benötigt, um ihren Vorrat an Befehlen zu ergänzen: Mit JavaScript und VBScript stehen gleich zwei moderne, objektorientierte Skriptsprachen zur Verfügung. Die Programme lassen sich mit jedem Texteditor erstellen und auf der lokalen Festplatte speichern. Um die Skripte einfach per Mausklick zugänglich zu machen, kann man diese Dateien dann in das Favoriten- beziehungsweise Lesezeichen-Menü aufnehmen oder - noch bequemer - auf eine Schaltfläche in der für oft benutzte Adressen vorgesehenen Symbolleiste legen.
Das Wort `eigentlich´ im ersten Satz läßt es schon vermuten: Ganz so einfach funktioniert es denn doch nicht. Aber dieser Artikel wäre hier nicht abgedruckt, wenn die dabei auftauchenden Hindernisse in puncto Sicherheit und Browser-Inkompatibilitäten unüberwindbar wären. Hat man sie erst einmal gemeistert, läßt sich aus einem Browser noch einiges an Komfort beim Surfen herausholen.
Das Thema Browser-Inkompatibilitäten führt zunächst zur Frage nach der Skriptsprache der Wahl. VBScript verbietet sich dabei von selbst, wenn man zu einigermaßen universell einsetzbaren Lösungen kommen will, denn diese Sprache steht nur im Internet Explorer zur Verfügung. Hingegen können JavaScript-Programme sowohl vom IE als auch vom Navigator verarbeitet werden. Microsoft nennt seinen Dialekt zwar JScript, aber im Grunde handelt sich dabei um JavaScript. Sämtliche Beispielskripte in diesem Artikel sind daher in JavaScript geschrieben und wurden mit dem Internet Explorer in den Versionen 4 und 5 sowie mit dem Netscape Communicator 4.x getestet. Wenn es Unterschiede für die verschiedenen Browser zu beachten gibt, weisen wir explizit darauf hin.
Ursprünglich ist JavaScript dazu gedacht, kleine Routinen in HTML-Seiten einzubetten. Damit wird es zum Beispiel möglich, die Benutzereingaben in Formularen zu überprüfen, bevor sie Ihren Weg über das Internet antreten, oder ein Element, das der Benutzer mit dem Mauszeiger berührt, visuell hervorzuheben. Die Befehle eines Skripts beziehen sich dabei immer auf Daten innerhalb der Seite, die auch das Skript enthält. Informationen über vorher besuchte Seiten, den Inhalt eines zweiten Browser-Fensters oder auch nur eines anderen Frame im selben Fenster sind für derartige Skripte aus Sicherheitsgründen tabu, wenn sie nicht vom selben Server stammen.
Das gilt selbst für Skripte in lokal gespeicherten Dateien. Will man also ein Progrämmchen schreiben, das etwa alle Links aus der aktuellen Seite in einer Liste zusammenstellt, so hilft eine auf der Festplatte vorhandene Skript-Datei zunächst nicht viel weiter. Vielmehr muß man den Browser glauben machen, daß das Skript im Kontext der angezeigten Seite läuft. Dafür gibt zwei verschiedene Methoden: Die sogenannten Bookmarklets funktionieren sowohl im Netscape Navigator als auch im Internet Explorer. Der zweite in Frage kommende Mechanismus steht nur im Microsoft-Browser zur Verfügung und bedient sich dessen sogenannter Menu Extensions.
Die Idee hinter den Bookmarklets [1] besteht aus einem Link, der bereits das komplette Skript enthält. Er verweist also nicht auf eine separate Datei, sondern der Browser bekommt es als URL vorgesetzt. Diese `Adresse´ beginnt mit dem Schlüsselwort javascript:, auf das die Skript-Befehle folgen.
Ein solcher Link ist innerhalb von HTML-Seiten nichts Ungewöhnliches. Viele Websites enthalten beispielsweise auf jeder Seite eine Navigationsleiste. Schaut man sich deren Quelltext an, so trifft man recht häufig auf eine Konstruktion wie
[javascript:back(); Zurück]
Klickt der Anwender nun auf den Link `Zurück´, so führt der Browser den JavaScript-Befehl back() aus, der dasselbe bewirkt wie der entsprechende Button in der Symbolleiste des Browsers.
Die Lesezeichen des Navigators beziehungsweise die Favoriten des Internet Explorer enthalten nichts anderes als Links. Hier gespeicherte Einträge nach obigem Muster ergeben also einen Shortcut auf einen JavaScript-Befehl. Wählt man ihn aus dem entsprechenden Menü aus, so arbeitet ihn der Browser genauso ab, als wäre er Bestandteil der gerade angezeigten Seite, und ermöglicht dem Befehl so den Zugriff auf alle ihre Objekte und Eigenschaften. Ein Bookmark mit der URL javascript:alert('Diese Seite kommt von ' + location.hostname); erzeugt beispielsweise eine Meldung, in der der Name des Servers angezeigt wird, von der die aktuelle Seite stammt.
Ein derartiges Bookmarklet kann auch mehrere Befehle enthalten. Selbst komplexe Abfrage- und Schleifenkonstruktionen sowie die Definition von Variablen sind möglich. Die Lesbarkeit leidet jedoch mit zunehmender Länge unter der Tatsache, daß das gesamte Skript auf einer Zeile stehen muß, deren Länge etwa 2000 Zeichen übrigens nicht überschreiten sollte. Falls Sie die im folgenden vorgestellten Beispielskripte also abtippen oder JavaScript-Dateien anderer Herkunft zu Bookmarklets verarbeiten wollen, müssen Sie sämtliche Zeilenumbrüche, Leerzeilen, Einrückungen und Kommentare entfernen und das Kennzeichen javascript: am Anfang ergänzen. Selbstverständlich gibt es die gezeigten Bookmarklets aber auch fertig zum Download auf unserem ftp-Server [5] oder in der c't-Mailbox.
|
Im Netscape Navigator lassen sich Bookmarklets in Unterverzeichnisse des Symbolleisten-Ordners einsortieren. |
Wenn Sie selbst mit Bookmarklets experimentieren und dazu neue Shortcuts erzeugen wollen, ist das bei Netscape und beim Internet Explorer für MacOS recht einfach: Das Lesezeichen-Fenster stellt alle nötigen Befehle bereit. Für den Microsoft-Browser unter Windows müssen Sie hingegen im Ordner Favoriten neue Dateien erzeugen. (Der Ordner ist bei Windows 9x normalerweise ein Unterverzeichnis von C:\Windows, bei Windows NT von C:\WinNT\profiles\.) Am besten kopieren Sie einen bereits bestehenden Eintrag, benennen ihn um und füllen das Feld URL im Eigenschaften-Dialog mit dem Programmcode. Die Rückfrage `Mit dem Protokoll "javascript" ist keine registrierte Anwendung verknüpft. Möchten Sie das Ziel trotzdem beibehalten?´ können Sie getrost bejahen.
Mit den vielleicht auf den ersten Blick seltsam erscheinenden Variablennamen, die wir in den Skripten verwenden, hat es folgende Bewandtnis: Bookmarklets laufen im Kontext der gerade angezeigten Seite. Diese kann natürlich selbst schon JavaScript enthalten, und innerhalb dieser Skripte sind möglicherweise globale Variablen definiert. Um die Wahrscheinlichkeit zu minimieren, daß eine Variable aus unseren Skripten genauso heißt wie eine bereits definierte, tragen alle den Präfix ct. Danach haben wir uns auf zwei Zeichen beschränkt, um die Länge der Skripte möglichst kurz zu halten.
Einen letzten Tip im Zusammenhang mit Bookmarks wollen wir Ihnen nicht vorenthalten: Wenn Sie viele davon in der Link-Leiste Ihres Browsers unterbringen wollen, geht ihr recht schnell der Platz aus. Um den Preis eines weiteren Mausklicks kann man jedoch hinter jedem Button beliebig viele Links verbergen. Dazu muß man für den Internet Explorer im Verzeichnis Favoriten\Links weitere Ordner anlegen beziehungsweise im Fenster `Lesezeichen bearbeiten´ von Netscape Unterordner im Symbolleisten-Ordner erzeugen. Diese Verzeichnisse erscheinen dann in der jeweiligen Leiste als Buttons, ihre Einträge werden in einem Popup-Menü angezeigt. Die neue Version 5 des Internet Explorer hat jedoch einen Bug, der dieses Vorgehen für Bookmarklets unbrauchbar macht: Ruft man hier einen javascript:-Link aus einem solchen Menü auf, so erscheint zuerst ein neues, leeres Explorer-Fenster, und das Skript hat keine Möglichkeit mehr, auf das ursprünglich angezeigte Dokument zuzugreifen.
Die Beschränkung auf eine Zeile setzt den Fähigkeiten von Bookmarklets recht enge Grenzen. Für den Internet Explorer ab Version 4 gibt es aber noch eine weitere Möglichkeit, JavaScript für eigene Befehle einzusetzen. Diesen Mechanismus benutzt Microsoft zum Beispiel in den sogenannten Internet Explorer PowerToys [2]. Sie fügen dem Kontextmenü, das bei einem Rechtsklick in einer Internet-Seite erscheint, neue Befehle hinzu.
|
Eigene Einträge im Kontextmenü des Internet Explorers muß man in der Registry anmelden. |
Um dort eigene Einträge unterzubringen, muß man sie in die Registry eintragen, und zwar unter dem Schlüssel HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt. Für jeden Befehl erzeugt man hier einen neuen Schlüssel. Sein Name erscheint im Kontextmenü des Internet Explorers; um einen Buchstaben in diesem Eintrag unterstrichen darzustellen, stellt man ihm ein `&´ voran. Der Standardwert des Schlüssels bekommt als Inhalt den Namen inklusive komplettem Pfad der Datei, die das Skript enthält. Optional kann man noch einen DWORD-Wert namens `Contexts´ erzeugen, der angibt, in welchem Kontextmenü der Eintrag erscheinen soll: Trägt man hier eine 1 ein, so gehört er zum Standard-Kontextmenü, mit einer 2 kommt er beim Rechtsklick auf ein Bild zum Vorschein, eine 4 steht für Controls, eine 8 für Tabellen und 16 für markierten Text. Soll der Befehl für mehrere Anlässe zur Verfügung stehen, so kann man die dazugehörigen Werte addieren.
Das eigentliche Skript gehört in eine HTML-Datei, die folgendermaßen aufgebaut sein sollte:
Beim Abtippen der hier vorgestellten Skripte müssen Sie also die ersten und die letzten beiden Zeilen hinzufügen; Zeilenumbrüche, Einrückungen und Kommentare können Sie jedoch beibehalten. Auch in diesem Format stehen die Beispielskripte bei heise online [5] zum Download bereit.
Das Schlüsselwort defer vermeidet häßliche Flackereffekte: Es sorgt dafür, daß Ausgaben erst in das Browser-Fenster gelangen, wenn das Skript komplett abgearbeitet ist. Die with-Anweisung samt der geschweiften Klammern ist nicht unbedingt erforderlich. Da aber per Menu Extension aufgerufene Skripte nicht im Kontext der aktuellen Seite laufen, muß man den Bezug explizit programmieren. external.menuArguments stellt diesen Zusammenhang her; der Ausdruck liefert das bei Bookmarklets oder eingebetteten Skripten implizit angenommene window-Objekt.
Weder im Netscape Navigator noch im Internet Explorer gibt es einen Befehl, der alle Links aus einer HTML-Seite extrahiert und in einem separaten Browser Fenster anzeigt, etwa um sie für später zu speichern. Diesem Manko hilft das Skript `Linkliste´ ab.
Die Hauptarbeit findet in Zeile 9 statt: Für jeden Link wertet das Skript zunächst den Ausdruck (ctDL[ctI].text || ctDL[ctI].href) aus, der entweder den Text des Links liefert oder aber - wenn der Text leer ist, etwa weil der Link hinter einem Bild liegt - dessen Ziel-URL. Die Methode link versieht diesen Text anschließend mit den nötigen HTML-Tags, um einen Link daraus zu erzeugen. Das Ergebnis wird um ein abschließendes
ergänzt - dem HTML-Befehl für einen Zeilenumbruch - und in das document-Objekt des neuen Fensters geschrieben.
Der abschließende Aufruf ctDO.close() signalisiert dem Browser, daß die Ausgaben beendet sind und er damit beginnen kann, die Seite zu umbrechen und anzuzeigen. Die Funktion liefert einen Wert zurück, mit dem man überprüfen kann, ob der Aufruf erfolgreich war. Dieser Rückgabewert wird hier nicht benötigt. Normalerweise gibt ein Bookmarklet das Ergebnis der letzten aufgerufenen Funktion als Text im Browser aus. void() dient dazu, dieses Resultat zu schlucken. Dadurch liefert das gesamte Skript keinen Wert, und die angezeigte Seite bleibt unangetastet.
Das base-Tag in Zeile 6 sorgt dafür, daß beim ersten Klick auf einen Link wiederum ein neues Fenster geöffnet wird und alle weiteren Ausgaben in diesem Fenster landen. Wer dieses Verhalten nicht mag, ersetzt ctLL durch _blank, um jede Seite in einem neuen Fenster angezeigt zu bekommen, oder läßt die Zeile komplett weg. Dann verhält sich das Linklisten-Fenster wie ein normaler Browser, und man kann in ihm wie gewohnt navigieren.
Setzt man das Skript `Linkliste´ als Bookmarklet ein, so gibt es ein Problem mit Seiten, die Frames enthalten. Die Links sind dann ja auch in einem solchen Rahmen enthalten, und das Skript weiß nicht, aus welchem Frame es die Links extrahieren soll. Bei Netscape gibt es für solche Fälle den Befehl `Rahmen in neuem Fenster öffnen´ im Kontextmenü. Im Internet Explorer fehlt dieser Befehl, aber man kann ihn recht einfach nachrüsten: Neben dem oben gezeigten vierzeiligen Rahmen braucht die dafür nötige HTM-Datei nur eine einzige echte Programmzeile:
open(location.href);
location.href ist vermutlich der Ausdruck, den Sie auch bei eigenen Experimenten mit Browser-Skripten am häufigsten benutzen werden: Er ergibt die URL der gerade angezeigten Seite.
Man kann diesen Ausdruck aber nicht nur auslesen, sondern ihm auch einen neuen Wert zuweisen und damit im Internet navigieren. Ein Anwendungsbeispiel dafür zeigt das Skript `Suchen´: In der abgedruckten Form sendet es den Text, den der Anwender in der aktuellen Web-Seite markiert hat, als Anfrage an die Suchmaschine AltaVista. Ist nichts markiert, ruft es die AltaVista-Homepage auf. Das Skript eignet sich dadurch hervorragend als Ersatz für ein statisches Bookmark auf diese Suchmaschine.
Die URL zum Suchen setzt das Skript in Zeile 7 zusammen. Sie besteht aus der Adresse des Servers, den Parametern, die dieser als Kennzeichen für eine Suchanfrage erwartet, und schließlich aus dem zu suchenden Text. Die Funktion escape setzt Umlaute und Leerzeichen in die für URLs gebräuchliche Form um. Dadurch kann eine Suchanfrage auch aus mehreren Wörtern bestehen.
Das Listing zeigt die JScript-Version für den Internet Explorer. Wollen Sie das Skript mit dem Netscape Navigator verwenden, müssen Sie die erste Zeile durch
ctSU = document.getSelection();
ersetzen. Durch Anpassungen in den Zeilen 2 und 3 läßt sich das Skript für die Verwendung mit anderen Suchmaschinen anpassen. Für einige populäre deutsche Exemplare finden Sie die Werte, die Sie den Variablen ctUR und ctPA zuweisen müssen, in einer Tabelle auf dieser Seite. Sollte Ihr Lieblingsserver fehlen, können Sie die erforderlichen Werte herausfinden, indem Sie eine Anfrage mit den von Ihnen am häufigsten verwendeten Suchoptionen an ihn richten. Die URL, die Ihr Browser danach im Adreßeingabefeld anzeigt, übernehmen Sie in das Skript und sorgen dafür, daß der zuvor eingegebene Suchbegriff durch escape(ctSU) ersetzt wird.
Die in diesem Artikel vorgestellten Techniken bieten breiten Raum für eigene Experimente. So läßt sich das Skript `Suchen´ beispielsweise durch Einfügen der Zeile
ctSU = prompt('Suchbegriff: ');
dahingehend ändern, daß es nach einem Suchbegriff fragt, wenn kein Text markiert ist. Oder Sie lassen das Skript auf einen Server wie http://dict.leo.org/ los, der Übersetzungen liefert. Oder, oder ... (hos)
[1] Bookmarklets, http://www.bookmarklets.com/
[2] Internet Explorer 4.0 PowerToys, http://www.microsoft.com/Windows/ie/ie40/powertoys/main.htm
[3] Microsoft Scripting Technologies, http://msdn.microsoft.com/scripting/
[4] JavaScript Developer Central, http://developer.netscape.com/tech/javascript/index.html
[5] c't ftp-Service, http://www.heise.de/ct/ftp/99/10/114/
1 ctDL = document.links; // Die aktuelle Seite 2 ctWI = open('','','width=400,height=300,scrollbars,resizable,menubar'); 3 // Ein neues Fenster... 4 ctDO = ctWI.document; // ... und dessen Dokument 5 6 ctDO.writeln(' '); 7 for(ctI=0; ctI'); 10 } 11 void(ctDO.close());
Das Skript `Linkliste´ erzeugt ein separates Browser-Fenster mit allen Links der aktuellen Web-Seite.
1 ctSU = document.selection.createRange().text; // Der markierte Text 2 ctUR = 'http://www.altavista.de/'; // URL der Suchmaschine 3 ctPA = 'cgi-bin/query?pg=q&what=web&q='; // Suchparameter 4 5 if(ctSU) // Textauswahl an Suchmaschine übergeben 6 { 7 location.href = ctUR + ctPA + escape(ctSU); 8 } 9 else // Nichts ausgewählt 10 { 11 location.href = ctUR; 12 }
Um das Skript `Suchen´ für andere Suchmaschinen zu verwenden, bedarf es nur kleiner Änderungen. Einige Beispiele zeigt die Tabelle.
| Parameter für Suchmaschinen | ||
| Suchmaschine | ctUR = | ctPA = |
| AltaVista | 'http://www.altavista.de/' | 'cgi-bin/query?pg=q&what=web&q=' |
| Aladin | 'http://www.aladin.de/' | 'cgi-bin/select.cgi?maxHits=10&searchText=' |
| Crawler.de | 'http://www.crawler.de/' | 'cgi-bin/suche.C?Maschine=CrawlerNeu&Menue=35&query=' |
| Excite | 'http://www.excite.de/' | 'search.gw?look=excite_de&c=web&search=' |
| Fireball | 'http://www.fireball.de/' | 'query-fireball.fcg?pg=express&what=german_web&fmt=d&q=' |
| Infoseek | 'http://www.infoseek.de/' | 'seek/s.cgi?col=WW&sv=IS&qt=' |
| Intersearch | 'http://www.intersearch.de/' | 'cgi-bin/search?icon=deutsch.gif&t=STANDARD&q=' |
| Lycos | 'http://www.lycos.de/' | 'cgi-bin/pursuit?matchmode=and&mtemp=main.sites&query=' |
| Web.de | 'http://suche.web.de/' | 'search/?ref=hp&smode=int&su=' |
| Yahoo | 'http://search.yahoo.de/' | 'search/de?p=' |
Version zum Drucken | Per E-Mail versenden | Heft bestellen
Das aktuelle Heft ist jetzt im Handel erhältlich.
Ältere Artikel können Sie über unser Zeitschriften-Archiv bestellen.