sph: ist der verwendete code valide?

hallo community!

ich habe ein mehr oder minder kleines anliegen an die javascript-experten unter euch :)

ich habe ein tutorial zum bewerkstelligen von javascript-tooltips gefunden, ich konnte mein vorhaben auch recht brauchbar auf der gewünschten seite realisieren - allerdings möchte ich gerne auf nummer sicher gehen und gerne wissen ob ich das script auch wirklich so ohne weiteres verwenden kann, oder ob es damit nur zu problemen kommt, wegen zu vieler fehler, falscher verwendung oder ähnlichem.

da ich selbst nicht den blassesten schimmer von javascript habe kann ich nicht im geringsten beurteilen was ich da eigentlich verwende(über das pro- und kontra diesbezüglich darf sich jeder selbst seine gedanken machen und für sich behalten)...

nun, hier die entsprechenden codezeilen:

########
<script>
<!--
wmtt = null;

document.onmousemove = updateWMTT;

function updateWMTT(e) {
 x = (document.all) ? window.event.x + document.body.scrollLeft : e.pageX;
 y = (document.all) ? window.event.y + document.body.scrollTop  : e.pageY;
 if (wmtt != null) {
  wmtt.style.left = (x + 20) + "px";
  wmtt.style.top  = (y + 20) + "px";
 }
}

function showWMTT(id) {
 wmtt = document.getElementById(id);
 wmtt.style.display = "block"
}

function hideWMTT() {
 wmtt.style.display = "none";
}
//-->
</script>
########

... und zum aktivieren:

########
<a href="..." onmouseover="showWMTT('1')" onmouseout="hideWMTT()">...</a>
########

falls sich jemand das ganze gern "live" ansehen möchte:
http://blog.plastick.org/pages/klick.html

... soll mal ne linksammlung werden, ich denke die beispiellinks erklären warum ich das so verwenden möchte.

Nun - kann ich das so belassen? Oder sind da einige ganz und garnicht so hübsche javascript-schnitzer drin, die man ausbügeln sollte? Scheint mit IE v6.irgendwas und FF v1.5.irgendwas zu funktionieren - vielleicht ist ja auch der ein- oder andere OPERA-nutzer unter euch, der mir berichten kann wie/ob die tooltips in diesem browser funktionieren?

viele fragen, ich hoffe jemand hier kann mir antworten geben, danke fürs lesen!

viele grüße,

sph

  1. HI,

    ich habs mir mit Firefox 1.5.0.3 angeschaut und funktioniert. Nur der Kalender bricht bei mir aus seinem Rahmen aus.(habe 1240x1028)

    Ich poste aber hier nur, weil ich auch mein Script von jemandem validiert haben möchte =].

    Vllt kannst du das ja? Oder wenn sich jemand dein Script anschaut, könnte er/sie sich mein kleines Script auch eben anschauen.

    Ich hoffe es ist selbsterklärend.

    function Scroll () {
     var bodyHalf  = (document.body.scrollWidth)/3 ;
     var winWidthA = window.innerWidth = 735 ;
     var winWidthB = window.innerWidth ;
     var diffWidth = if (winWidthB = <735) {735 - winWidthB;}
     if (winWidthB == winWidthA) {
      window.scrollTo(bodyHalf, 0); }
     else (winWidthB = <735) {
      window.scrollTo((diffWidth+bodyHalf), 0);}

    bye

    1. ich habs mir mit Firefox 1.5.0.3 angeschaut und funktioniert. Nur der Kalender bricht bei mir aus seinem Rahmen aus.(habe 1240x1028)

      ähm - ernsthaft? kannst du mir vielleicht nen screenshot davon schicken?

      weil... ich benutze gerade den selben browser bei der selben auflösung und muss sagen: der kalender passt schon so... o.0

      hast zu zufälligerweiße die schrift SEHR SEHR GROß skaliert? :)

      kann mir vielleicht, obwohl offtopic, jemand verraten wie ich die seitengestaltung auch für größere schriftstile sicherstellen kann?

      1. Hi,

        hier der Screenshot:
        http://img79.imageshack.us/my.php?image=bildschirmfoto4et.png

        bye

        1. Hi,

          hier der Screenshot:
          http://img79.imageshack.us/my.php?image=bildschirmfoto4et.png

          bye

          oh, vielen dank!

          tja, da muss ich wohl noch dran arbeiten...

          viele grüße, bye!

  2. Tach

    <script>

    fehlendes Typ-attribut
    Das ist das Einzige was mir jetzt erstmal auffällt.

    So long and thanks for all the fish,
    Oku

    1. Tach

      <script>
      fehlendes Typ-attribut
      Das ist das Einzige was mir jetzt erstmal auffällt.

      So long and thanks for all the fish,
      Oku

      danke!
      genau sowas meinte ich - hab das erstmal korrigiert. falls du noch mehr entdeckst könntest du mir bescheidsagen, ja?

      viele grüße,

      sph

  3. Hallo,

    document.onmousemove = updateWMTT;

    Du überwachst damit dokumentweit andauernd das Mousemove-Ereignis und bei jeder Mausbewegung wird die Position berechnet. Das ist im Grunde unnötig. Du könntest die Überwachung dann starten und stoppen, wenn sie benötigt wird, nämlich bei einem Mouseover bzw. Mouseout bei den fraglichen Elementen. Du könntest die Überwachung zudem auf diese Elemente eingrenzen.

    function updateWMTT(e) {
    x = (document.all) ? window.event.x + document.body.scrollLeft : e.pageX;
    y = (document.all) ? window.event.y + document.body.scrollTop  : e.pageY;

    Diese Objektabfrage ist wenig sinnig. Grundregel: Prüfe die Existenz derjenigen Objekte, die du auch zu nutzen gedenkst. »Browsererkennungen« über document.all sind unpassend. Du kannst hier sowieso einfach http://de.selfhtml.org/javascript/objekte/event.htm#client_x_y@ŧitle=clientX/Y verwenden, wenn mich nichts täuscht.

    function showWMTT(id) {
    wmtt = document.getElementById(id);
    wmtt.style.display = "block"
    }

    function hideWMTT() {
    wmtt.style.display = "none";
    }

    <a href="..." onmouseover="showWMTT('1')" onmouseout="hideWMTT()">...</a>

    Auf diese Weise hast du ewig viel JavaScript-Code in deinem Dokument stehen. Zeitgemäßes JavaScript schreiben bedeutet, Inhalt, Präsentation und JavaScript-Interaktivität voneinander zu trennen (siehe Schichtenmodell und Verhaltensschicht). Dein jetziger Code ist überladen und umständlich zu ändern.

    Deshalb verzichtet man mittlerweile zunehmend auf Inline-Event-Attribute und registriert alle Handler automatisch per JavaScript (das nennt sich dann unobtrusive JavaScript oder DOM Scripting). Im HTML notiert man eine einfache Liste, die beim Laden des Dokuments durchlaufen wird. Dabei werden die Mouseover- und Mouseout-Handler registriert.

    Genauer gesagt muss man gar nicht bei jedem Element einzeln Event-Handler registrieren. Mouseover-, Mouseout- und Mousemove-Ereignisse steigen auf (Bubbling). Man braucht also einfach ein Container-Element, bei dem alle Ereignisse vorbeilaufen, dort greift man sie ab und verarbeitet sie.

    Das HTML kann entsprechend vereinfacht werden, es wird kein JavaScript-Code darin mehr untergebracht. Ich habe mal als Beispiel eine Definitionsliste gewählt:

    <dl class="linkliste">  
    <dt><a href="http://www.example.org/">aaaaaa</a></dt>  
    <dd>aaaaaa</dd>  
    <dt><a href="http://www.example.org/">bbbbbb</a></dt>  
    <dd>bbbbbb</dd>  
    <dt><a href="http://www.example.org/">cccccc</a></dt>  
    <dd>cccccc</dd>  
    <dt><a href="http://www.example.org/">dddddd</a></dt>  
    <dd>dddddd</dd>  
    <dt><a href="http://www.example.org/">eeeeee</a></dt>  
    <dd>eeeeee</dd>  
    </dl>  
    
    

    Das Script im Dokumentkopf könnte zeitgemäß etwa so aussehen:

    <style type="text/css">  
    [code lang=css].linkliste dd.hidden { position:absolute; left: -9000px; top:0; width: 0; overflow: hidden; }  
    .linkliste dd.visible { padding:0.5em; width: 15em; overflow: auto; border:1px solid black; background-color:#eee; }
    

    </style>
    <script type="text/javascript">

      
    /* Wenn JavaScript aktiviert ist, verstecke alle dd-Elemente standardmäßig mit der [link:http://www.access-matters.com/testcases/tc5-2-9.html@title=Off-Left-Methode]. Die ist besser als ein einfaches display:none, weil Screenreader-Benutzer den versteckten Text dann trotzdem lesen können. */  
    document.write("<style type='text/css'>" +  
    ".linkliste dd { margin:0; padding:0; position:absolute; left: -9000px; top:0; width: 0; overflow: hidden; }" +  
    "</style>");  
      
    /* Führe beim Laden der Seite die Methode tooltip.init() aus. */  
    window.onload = function () {  
     tooltip.init();  
    };  
      
    /* Erzeuge ein allgemeines Objekt, das lediglich als Container-Objekt für ein paar Variablen und Funktionen dient. So kann man zusammenhängenden JavaScript-Code übersichtlicher strukturieren, denn alle Tooltip-bezogenen Funktionen sind Methoden des Objektes tooltip. */  
    var tooltip = new Object();  
    tooltip.current_dt = null;  
    tooltip.current_dd = null;  
      
    /* Initialisierungsmethode */  
    tooltip.init = function () {  
     /* Suche alle dl-Elemente im Dokumente */  
     var dl_elements = document.getElementsByTagName("dl");  
     /* Durchlaufe die gefundene Elementliste */  
     for (var i = 0, dl_element, j = 0, dt_element; i < dl_elements.length; i++) {  
      dl_element = dl_elements[i];  
      /* Hat das dl-Element die Klasse linkliste? Wenn nicht, dann fahre mit dem nächsten Schleifendurchlauf fort. */  
      if (dl_element.className != "linkliste") {  
       continue;  
      }  
      /* Registriere alle Event-Handler zentral beim dl-Element. Bei jeglichen ...-Ereignissen, die bei dl-Element passieren oder vorbeikommen (beim Aufsteigen/Bubbling), führe ... aus */  
      dl_element.onmousemove = tooltip.update;  
      dl_element.onmouseover = tooltip.show;  
      dl_element.onmouseout = tooltip.hide;  
     }  
    };  
      
    /* Beim Mouseover über irgendein Element innerhalb des dl-Elements wird diese Methode aufgerufen. */  
    tooltip.show = function (e) {  
     /* Blende die letzte Linkbeschreibung aus, sofern bereits eine angezeigt wurde. */  
     if (tooltip.current_dd) {  
      tooltip.hide();  
     }  
     /* Zugriff auf das Event-Objekt, siehe [link:http://de.selfhtml.org/javascript/objekte/event.htm#allgemeines@title=SELFHTML] */  
     e = e || window.event;  
     /* Zugriff auf das Zielelement des Ereignisses (entweder das dl-Element selbst oder eines der dt-Elemente oder eines der Elemente darin, z.B. a) */  
     var target = e.target || e.srcElement;  
     /* Wir möchten vom Zielelement zum dt-Element, also steigen wir im DOM-Knotenbaum auf, bis wir dieses finden. */  
     var node = target;  
     while (node.nodeName != "DT" && node != null) {  
      node = node.parentNode;  
     }  
     /* Lege eine Referenz auf den gefundenen dt-Elementknoten an */  
     tooltip.current_dt = node;  
     /* Eigentlich wollen wir zum dd-Element, also müssen wir ausgehend vom dt-Element das zugehörige dd-Element finden. Es muss aber pro dt-Element nur einmal gesucht werden, auch wenn es mehrmals mit der Maus überfahren wird. Also wird eine Referenz auf den Knoten als Eigenschaft corresponding_dd an den dt-Elementknoten gehängt, die später dann direkt genutzt wird. */  
     if (tooltip.current_dt.corresponding_dd) {  
      /* Falls eine solche Referenz bereits angelegt wurde, dann benutze diesen dd-Elementknoten. */  
      tooltip.current_dd = tooltip.current_dt.corresponding_dd;  
     } else {  
      /* Das zugehörige dd-Element muss erst gesucht werden. Durchlaufe alle dem dt-Element nachfolgenden Knoten, bis ein dd-Elementknoten gefunden wird. */  
      while (node.nodeName != "DD" && node != null) {  
       node = node.nextSibling;  
      }  
      /* Lege Referenzen auf den den gefundenen Elementknoten an */  
      tooltip.current_dd = tooltip.current_dt.corresponding_dd = node;  
     }  
     /* Zeige das dd-Element mit der Beschreibung */  
     tooltip.current_dd.className = "visible";  
     //tooltip.update(e);  
    };  
      
    /* Positioniere das gegenwärtige dd-Element (bei dem das letzte Mouseover-Ereignis passierte) entsprechend der Mausposition */  
    tooltip.update = function (e) {  
     e = e || window.event;  
     tooltip.x = e.clientX;  
     tooltip.y = e.clientY;  
     /* Über tooltip.current_dd kann hier einfach auf den dd-Elementknoten zugegriffen werden. */  
     tooltip.current_dd.style.left = (tooltip.x + 20) + "px";  
     tooltip.current_dd.style.top = (tooltip.y + 20) + "px";  
    };  
      
    /* Verstecke das letzte gezeigte dd-Element */  
    tooltip.hide = function () {  
     tooltip.current_dd.className = "hidden";  
     tooltip.current_dd.style.left = "-9000px";  
    };
    

    </script>
    [/code]

    Der JavaScript-Code ist vergleichsweise komplizierter, diese Art des Event-Handlings und dieser Programmierstil macht es einem aber auf lange Sicht viel einfacher. Vor allem sind die Inhalte auch ohne JavaScript zugänglich und der HTML-Code hat eine ordentliche Struktur.

    (Tastatur-Zugänglichkeit ist noch nicht gegeben, sprich, die Beschreibungen werden nicht eingeblendet, wenn ein Link mit der Tastatur angesprungen wird. Da schlägt die Nutzung des Bubblings fehl, weil Focus-Ereignisse nicht aufsteigen.)

    Mathias

    1. grundgütiger!

      was hast du da aus diesen paar zeilen code gemacht??  :D

      du kannst mir unwissendem natürlich viel erzählen (ein bisschen skeptikt ist nie verkehrt ;)  ), aber schonmal eins ganz klar vorweg: DANKE!

      du hast dir tatsächlich die zeit genommen ein auge auf mein vorhaben zu werfen, das allein ist schonmal großartig!

      und jetzt bleibt mir wohl nichts anderes übrig als diesen code durchzuarbeiten und dann einzubauen - vielen dank für die zahlreichen kommentare! das ist richtig klasse, das hilft mir hoffentlich dabei mich da zurechtzufinden :)

      weil ich das jetzt eben (wegen zeitmangel) nur überflogen habe - betrifft die script-änderung denn auch das link-handling? sprich, muss ich anders verlinken als bisher? (ich schiele da zu <dd> und <dt>...)

      und: beeinflusst diese funktion gar die css-gestaltung der tooltip-box?

      nochmals vielen dank für deine bemühungen :)

      viele grüße,

      sph

      1. Hallo,

        weil ich das jetzt eben (wegen zeitmangel) nur überflogen habe - betrifft die script-änderung denn auch das link-handling? sprich, muss ich anders verlinken als bisher? (ich schiele da zu <dd> und <dt>...)

        Die Linkliste muss nach dem Schema einer Definitionsliste aufgebaut sein:

        <dl class="linkliste">  
        <dt><a href="http://www.example.org/">Link</a></dt>  
        <dd>Beschreibung</dd>  
        <!-- ... weitere dt- und dd-Paare ... -->  
        </dl>
        

        In dt und dd kannst du beliebige Elemente unterbringen. Das Script macht im Grunde nur »zeige das zugehörige dd-Element, wenn die Maus über ein dt-Element kommt«. Im dt-Element muss also nicht unbedingt ein Link sein.

        und: beeinflusst diese funktion gar die css-gestaltung der tooltip-box?

        Die Gestaltung der Tooltip-Box kannst du wie üblich im Stylesheet vornehmen. In meinem Beispiel hatte ich nur einfache Formatieurngen gewählt. In der Formatierungsregel

        .linkliste dd.visible { padding:0.5em; width: 15em; overflow: auto; border:1px solid black; background-color:#eee; }

        kannst du das Aussehen der Box anpassen.

        Mathias

        1. du bist mir wirklich eine enorme hilfe, danke für deine bemühungen!

          gut, da ich das jetzt eingebaut habe hab ich das mit dem css schon entdeckt, und die funktion der definitionsliste hab ich auch rausgefunden - aber vielen dank nochmal!

          greets,

          sph

        2. hallo!

          jetzt muss ich mich doch noch einmal hilfesuchend an dich wenden, denn: mit dem von dir vorgeschlagenen script gibt es ein kleines problem.

          wie kann man die position des tooltips "fixieren"? ich habe da nämlich ein paar seltsame verhaltensweisen bei nicht-maximierter fenstergröße entdeckt - scrollt man nach unten, wird das tooltip-fenster stark verschoben, teils ausserhalb des bildschirms, angezeigt.

          kann man die position des fenster irgendwie an den mauszeiger binden?

          grüße,

          sph

          1. Hallo,

            Achso, da habe ich vergessen, den Scrolling-Offset zu addieren, da war der ursprüngliche Code doch nicht so falsch.

            Aktualisiertes Script

            Mathias

            1. spät, aber doch noch:

              DANKE!

              ja, das war der "fehler" den ich gemeint habe. großartig, funktioniert nun bestens!

              danke für deine bemühungen!

              grüße,

              sph

    2. so, nun habe ich das so übernommen - recht viel mehr hab ich davon allerdings immer noch nicht verstanden,das ist alles sehr verwirrend!

      das ergebnis ist das selbe, funktioniert einwandfrei, meine fragen haben sich erübrigt. und dieser code sollte mich also vor problemen bewahren?
      das fänd ich natürlich spitze! :)

      vielen dank nochmal!

      bye,

      sph