Calocybe: target="_blank" for HTML Strict pages

Beitrag lesen

(In reply to http://forum.de.selfhtml.org/archiv/2002/6/15222/ and any other threads about this topic.)

Moin Leuts!

Leider war ich etwas zu langsam, um diesen Beitrag noch im gerade entschwundenen Thread zu bringen. Aber naja.

Ich halte zwar die Notwendigkeit des Oeffnens neuer Fenster bei Verwendung von HTML Strict nach wie vor fuer Nonsens, moechte aber mal diesen Kompromissvorschlag bringen, der neue Fenster mit JS oeffnet -- doch der Reihe nach:

Considerations

Wie wir in einer der vergangenen Diskussionen eroertert haben, ist target="_blank" kein logik-strukturierendes Attribut und gehoert daher nicht in die Strict-Variante von HTML. Jedoch wird bei der Verwendung oftmals eine logische Bedeutung impliziert, naemlich die, dass der Link zu einer anderen Website fuehrt, also extern ist.

Zur Kennzeichnung fuer diesen logischen Zusammenhang bietet HTML durchaus ein Mittel: das REL-Attribut des A-Elements. Lediglich ein standardisierter Wert fuer die externe Relation ist noch nicht verfuegbar; anbieten wuerde sich etwa rel="extern" oder rel="offsite".

Die Umsetzung in ein konkretes Verhalten bei fensterbasierten grafischen Browsern faellt imho in dieselbe Kategorie wie das realisieren einer browserbasierten Anwendung, oder anders formuliert, das Oeffnen eines neuen Fensters stellt bereits eine ganz kleine web-basierte Applikation dar (und daher ist fuer mich der Wunsch nach Verwendung von HTML Strict in diesem Zusammenhang nicht nachvollziehbar, denn Stricts einziger Zweck ist die Beschreibung einer Textstruktur). Ueber Web-Applikationen auf Basis von HTML habe ich noch mal eine gesonderte Meinung zu bieten, wie der regelmaessige Forumsbesucher weiss, aber das soll mal hier nicht interessieren. Wichtig ist die Feststellung, dass fuer die Realisierung von Web-Applikationen JavaScript zustaendig ist, nicht HTML oder CSS.

Das soll insgesamt heissen, in einer Welt der sauberen Trennung von Textstruktur, Design und Automation/Programmierung kennzeichnet rel="offsite" im A-Element einen externen Link, waehrend mit JS dafuer gesorgt wird, dass sich solche Links in einem neuen Fenster oeffnen. Dieses Ergebnis ist auch fuer mich ueberraschend, da ich ja eigentlich Gegner von solchem JS-Firlefanz bin, aber target="_blank" ist ja imho auch in den seltensten Faellen sinnvoll. Somit bekommt man eine bescheuerte Loesung fuer ein bescheuertes Problem, die sich aufgrund der Logik aber aufdraengt. (<-- Das mit der Logik, also die obige Ueberlegung, steht natuerlich zur Diskussion!)

Implementation

Wish list:
    * Die Implementierung soll natuerlich so geschehen, dass Besucher
      mit nicht-JavaScript-begabten Browsern keinerlei
      Einschraenkungen haben.
    * Die neu geoeffneten Fenster sollen genauso aussehen, wie wenn
      sie von target="blank" erzeugt worden waeren, insbesondere
      sollen nicht saemtliche Toolbars fehlen oder die Fenster nicht
      mehr resizable sein, wie man es von den nervigen JS-Popups kennt.
    * Ausserdem muss derselbe Link bei mehrmaliger Betaetigung immer
      wieder neue Fenster hervorbringen, keinesfalls bestehende
      wiederverwenden.
    * Und die Fenstergroesse soll die sein, die der Browser auch fuer
      ein _blank-Fenster waehlen wuerde.
    * Schliesslich sollte idealerweise der bestehende HTML-Code nicht
      veraendert werden muessen (nachdem REL="offsite" drinsteht).

Letzteres ist kein Problem. Die gaengige Praxis, Event-Handler mitten im HTML-Code als OnXXX-Attribut hinzuschreiben, ist ja sowieso nur ein Shortcut fuer das richtige Setzen von Event-Handlern in JavaScript. Dort geschieht das durch Zuweisen einer Funktion an die onXXX-Eigenschaft eines Objektes. Wir koennen die Aufgabe also ausschliesslich in JS abwickeln.

Das Simulieren eines _blank-Fensters sollte meinem beklagenswerten Wissensstand nach durch Aufruf von window.open() mit der URL als einzigem Argument zu bewerkstelligen sein.

Es ist zu beruecksichtigen, dass REL mehrere, durch Space separierte, Relationships enthalten kann.

Beispielcode (see this in action at http://selfworld.calocybe.dyndns.org/ftmp/offsite-links.html (sorry, lame connection these days)):

/*  (C) Copyright 2002 by Calocybe Creations
     *  This code is in the public domain, that is to read, you are free
     *  to use it without any restriction.
     */

/* this is the event handler */
    function OnOffsiteLinkClick() {
        window.open(this.href);
        return false;     /* cancel the default click action */
    }

/*  AttrListContains(list, value);
     *  Checks if the space-separated list of values 'list' contains 'value'.
     *  This is useful for implementing a selection  equivalent to the CSS2 selector E[list~="value"] .
     *  Works case-insensitively.
     */
    function AttrListContains(list, value) {
        var i, split;

if (typeof(list) == "undefined" || list == null) return 0;
        if (!(list = list.toString()).length) return 0;

split = list.split(" ");
        for (i=0; i < split.length; i++)
            if (split[i].toLowerCase() == value.toLowerCase()) return 1;

return 0;
    }

function AssignLinkClickHandler() {
        var i, l, anchors;

if (!(window.document.getElementsByTagName && String.prototype.split && window.open))
            /* sorry, your user agent sucks! */
            return;

anchors = window.document.getElementsByTagName("a");

for (i=0; i < anchors.length; i++) {
            l = anchors[i];
            if (
              l.getAttribute("href") &&                             /* is a link, not merely an anchor */
              AttrListContains(l.getAttribute("rel"), "offsite")    /* refers to an extern location */
            )
                l.onclick = OnOffsiteLinkClick;
        }
    }

Getestet mit Mozilla 1.0.0. Testberichte fuer andere Browser sind willkommen.

Advantages

Will man diese Methode fuer andere Zwecke als Offsite-Links einsetzen, kann man den Code leicht abaendern, um auf andere RELationships oder auch andere Attribute (insbesondere CLASS) zu reagieren.

Auf diese Weise kann man sogar den Benutzer mittels einer Checkbox waehlen lassen, ob er Offsite-Links in einem neuen Fenster haben moechte oder nicht, bei Bedarf also die OnClick-Handler setzen oder wieder entfernen. Implementing this is left as an exercise for the reader.

Know issues

Funktioniert in dieser Form nur bei Mausklick, nicht bei Linkaktivierung durch Tastatur. Ich vermute jedoch, wer mit der Tastatur navigiert, betrachtet das eher als Feature.

Funktioniert nur mit Browsern, die getElementsByTagName(), String.split() und window.open() verstehen (also die moderneren).

Falls bereits spezielle OnClick-Handler fuer manche Links gesetzt sind, werden diese mit diesem Code deaktiviert (bezieht sich nur auf solche mit REL="offsite"). Naja, ganz abgesehen von der Praxisrelevanz dieser Ueberlegung wird es dem geneigten Seitenautor nicht schwer fallen, den Code so abzuaendern, dass in solchen Faellen der alten Handler von dem neuen aus aufgerufen wird oder fuer solche Links der neuen Handler gar nicht erst installiert wird.

[Your comments go here.]

So long

--
Vergeben und vergessen heißt, gemachte kostbare Erfahrungen zum Fenster hinauswerfen.
    -- Arthur Schopenhauer