XHTMLforum

XHTMLforum (http://xhtmlforum.de/index.php)
-   Javascript & Ajax (http://xhtmlforum.de/forumdisplay.php?f=83)
-   -   EventHandler: Reihenfolge und Abbruch der Verarbeitung (capture,bubble) (http://xhtmlforum.de/showthread.php?t=58758)

SchlechterInformatiker 09.10.2009 16:25

EventHandler: Reihenfolge und Abbruch der Verarbeitung (capture,bubble)
 
Hallo,
ich habe eine Tabelle und möchte, dass ein Tooltip erscheint, wenn sich der Mauszeiger eine gewisse Zeit über einer der Tabellen-Zellen (das <TD>) befindet. Das Tooltip soll verschwinden wenn der Mauszeiger die Tabellen-Zeile (das <TR>) verlässt, nicht aber wenn der Mauszeiger von einer Spalte in eine andere fährt.

Ich habe bereits viel mit den Funktionen "stopPropagation()" und "addEventListener(...)" experimentiert, indem ich den dritten Parameter auf "true" bzw. "false" gestetzt habe, um die EventHandler anzumelden, nachdem ich den Thread http://xhtmlforum.de/45740-events-ve...-berladen.html gelesen habe. Aber ich komme nicht weiter.

Weiß jemand wie ich diese Funktionen richtig kombinieren muss um das gewünschte Ergebnis zu erhalten?

Oder gibt es vielleicht eine Möglichkeit, den "onmouseover" Event der nächsten Spalte auszulösen und abzufangen bevor das "onmouseout" Event der aktuellen Spalte ausgelöst wird? Dann könnte ich mit einer globalen Variable herausfinden, ob die Quelle des nächsten Events wieder eine Spalte derselben Tabelle ist oder ob der Mauszeiger die Tabelle verlassen hat.

Oder bin ich total auf dem Holzweg? Oder ist das was ich möchte gar nicht möglich?

Hier ein Beispiel:

HTML-Code:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
 <body onload="init();">
  <script type="text/javascript">
  var timeout;
  var vorherigeSpalte = "";
  function init()
  {
    document.getElementById("Spalte1").addEventListener("mouseout",spalteVerlassen,false);
    document.getElementById("Spalte2").addEventListener("mouseout",spalteVerlassen,false);
    document.getElementById("Zeile1").addEventListener("mouseout",tabelleVerlassen,false);

    document.getElementById("Spalte1").addEventListener("mouseover",initToolTip,false);
    document.getElementById("Spalte2").addEventListener("mouseover",initToolTip,false);

    document.getElementById("ToolTip").firstChild.nodeValue = "";
  }
  function tabelleVerlassen(e)
  {
    //Hierzu kommt es nicht wegen e.stopPropagation() in der Funktion spalteVerlassen(e)
    //Wenn ich e.stopPropagation jedoch weglasse, verschwindet das Tooltip immer, was wiederum auch nicht erwünscht ist
    window.clearTimeout(timeout);
    document.getElementById("ToolTip").style.visibility = "hidden";       
  }
  function spalteVerlassen(e)
  {
    e.stopPropagation();
  }
  function initToolTip(e)
  {
    document.getElementById("ToolTip").firstChild.nodeValue = "Info zu " + e.target.id;
    if((vorherigeSpalte == "Spalte1" && e.target.id == "Spalte2") || (vorherigeSpalte == "Spalte2" && e.target.id == "Spalte1"))
    {
      //NICHT verstecken!
    }
    else
    {
      document.getElementById("ToolTip").style.visibility = "hidden";
      window.clearTimeout(timeout);
      timeout = window.setTimeout("zeigeToolTipAn()",1000); 
    }
    vorherigeSpalte = e.target.id;
  }
  function zeigeToolTipAn()
  {
    document.getElementById("ToolTip").style.visibility = "visible";
  }
  </script>
  <table cellspacing="0" cellpadding="0">
  <tbody>
    <tr id="Zeile1">
      <td id="Spalte1" style="border-width:1px;border-style:solid;width:100px;height:100px;text-align:center;">
      Spalte1
      </td>
      <td id="Spalte2" style="border-width:1px;border-style:solid;width:100px;height:100px;text-align:center;">
      Spalte2
      </td>
    </tr>
    </tbody>
  </table>
  <div id="ToolTip" style="width:50px;height:40px;left:200px;top:200px;background-color:red;visibility:hidden;">
  </div>
 </body>
</html>


Scheppertreiber 09.10.2009 16:28

Einfach mit einem title="Sprechblase" im HTML ?

SchlechterInformatiker 09.10.2009 16:47

Tut mir leid, aber ich kann dir nicht ganz folgen...

Scheppertreiber 09.10.2009 16:50

Das was Du realisieren will macht der Browser doch automatisch:

HTML-Code:

<td title="Blabla">Text</td>

SchlechterInformatiker 09.10.2009 16:55

Daran hab ich zwar nicht gedacht, aber das tut's für meine Zwecke nicht - denke ich. Da hab ich auf das Tooltip keinen weiteren Einfluss, oder? Also der Text der da in das Tooltip muss, ist lang und enthält einige Formatierungen. Ich würde auch gerne die Hintergrundfarbe des Tooltip bestimmen können und das Tooltip sollte der Maus folgen.

Scheppertreiber 09.10.2009 17:02

Das dürfte etwas tüftelig werden.

Die Box darstellen (zB als "<div>") und formatieren, bei Bedarf mit display ein- und
ausschalten dürfte nicht so das Problem sein.

Die Box so positionieren, daß sie die anderen Inhalte nicht verdeckt ginge auch.

Im Prinzip würde ich sobald die tr den Focus erhält einen timer starten
der nach einer gewissen Zeit seine Cursorposition bestimmt und danach die
Box einschaltet (vermutlich ist deren Inhalt noch abhängig von Spalte oder Reihe).
An ein tr konnte man den Handler anklemmen der die Box abschaltet wenn der
Focus von der Zeile weggeht.

Klemme das alles an die tr !

SchlechterInformatiker 09.10.2009 17:14

Also du meinst, ich solle nur dem TR einen onmouseover-Handler und ein onmouseout-Handler geben und dann selber die entsprechende TD (und somit dessen inhalt) mittels cursor-Position und offsetLeft der TD's bestimmen und dann quasi die Events beim capture abfangen und stopPropagation aufrufen so dass die TDs innen drin nix davon mitbekommen..?!

Scheppertreiber 09.10.2009 17:20

Ich würde es in der Richtung mal probieren.

Erstmal sehen, den Handler dem tr mitzugeben. Vielleicht kannst Du an die
td weitere Handler klemmen die dann den entsprechenden Text setzen.

(Ich weiß nicht ob das so geht, ist nur eine Idee).

SchlechterInformatiker 09.10.2009 17:24

Joa ok... an komplexen, dafür weniger schönen Lösungen mangelt es mir nicht, obwohl dein Ansatz noch nicht dazu gehörte. Ich dachte halt bevor ich mit Kanonen auf Spatzen schieße frage ich lieber mal nach ob ich nicht eine JavaScript Funktion übersehen habe, die mir helfen könne.


Mal sehen welcher der komplexeren Ansätze noch der einfachste ist...

Danke dir!

SchlechterInformatiker 09.10.2009 22:11

Ok, hier die schönste von meinen unschönen Lösungen. Unschön deshalb, weil ich dem gesamten document auch einen Handler verpassen muss.

Hier eine einfache Version der ganzen Sache, ohne besonderen Inhalt und ohne Positionsverschiebung des ToolTips. Positionsverschiebung kann einfach in die Funktion "warte(...)" eingebaut werden damit die Position ständig aktualisiert wird. Und dem ToolTip kann man statt der ID der unter dem Cursor liegenden Spalte kann man auch dessen Inhalt in das Tooltip füllen.

Hier die Firefox-Version:

HTML-Code:

<html>
 <body onload="init()">
  <script type="text/javascript">
  var alteID;
  var timeout;
  function init()
  {
    document.getElementById("Spalte1_id").addEventListener("mouseover",bereiteAnzeigeVor,false);
    document.getElementById("Spalte2_id").addEventListener("mouseover",bereiteAnzeigeVor,false);
    document.getElementById("Spalte3_id").addEventListener("mouseover",bereiteAnzeigeVor,false);
   
    document.getElementById("Spalte1_id").addEventListener("mousemove",warte,false);
    document.getElementById("Spalte2_id").addEventListener("mousemove",warte,false);
    document.getElementById("Spalte3_id").addEventListener("mousemove",warte,false);
     
    document.getElementById("ToolTip").appendChild(document.createTextNode(""));
    document.addEventListener("mouseover",bereiteAnzeigeVor,false);
  }
  function bereiteAnzeigeVor(e)
  {
    window.clearTimeout(timeout);
    if(!alteID)
    {
    alteID = e.target.id;
    }
    else
    {
    if((alteID == "Spalte1_id" && e.target.id == "Spalte2_id") || (alteID == "Spalte2_id" && e.target.id == "Spalte1_id"))
    {
      document.getElementById("ToolTip").firstChild.nodeValue = e.target.id;
      e.stopPropagation();
    }
    else
    {
      document.getElementById("ToolTip").style.visibility = "hidden";       
    }
    alteID = e.target.id;
    }
  }
  function warte(e)
  {
    window.clearTimeout(timeout);
    timeout = window.setTimeout("zeigeToolTipAn()",1000);
  }
  function zeigeToolTipAn()
  {
    document.getElementById("ToolTip").style.visibility = "visible";
    document.getElementById("ToolTip").firstChild.nodeValue = alteID; 
  }
  function beendeAnzeige()
  {
      window.clearTimeout(timeout);
      document.getElementById("ToolTip").style.visibility = "hidden";   
  }
  </script>
  <table cellspacing="0" cellpadding="0" style="border-width:1px;border-style:solid;">
  <tbody>
    <tr>
    <td id="Spalte1_id" style="width:100px;height:50px;text-align:center;border-width:1px;border-style:solid;">
      Inhalt 1
    </td>
    <td id="Spalte2_id" style="width:100px;height:50px;text-align:center;border-width:1px;border-style:solid;">
      Inhalt 2
    </td>
    <td id="Spalte3_id" style="width:100px;height:50px;text-align:center;border-width:1px;border-style:solid;">
      Inhalt 3
    </td>
    </tr>
  </tbody>
  </table>
  <div id="ToolTip" style="width:100px;height:40px;background-color:yellow;visibility:hidden;"/>
 <//body>
</html>

Erläuterung

Wenn man die Maus über Spalte 1 oder Spalte 2 bewegt und 1 Sekunde ruhen lässt, wird das ToolTip angezeigt. Fährt man mit der Maus von Spalte 1 über Soalte 2 oder umgekehrt, verschwindet das ToolTip nicht, der Inhalt wird aber geändert. Anders verhält es sich wenn man mit der Maus von Spalte 2 auf Spalte 3 fährt. Da verschwindet das ToolTip und man muss wieder eine Sekunde warten bis es wieder erscheint mit neuen Informationen. Fährt man irgendwo aus der Tabelle raus, verschwindet das Tooltip immer.

Das Prinzip ist folgendes:
Beim Eintritt des Mauszeigers in einer Spalte merkt sich das Script die ID der jeweiligen Spalte. Bei jeder Bewegung des Mauszeigers startet der Countdown der Sekunde, die zu warten ist, von Neuem. Erst wenn eine Sekunde ohne Mausbewegung vergangen ist, wird das Tooltip angezeigt und bleibt angezeigt.

Der Knackpunkt: Das Verstecken des Tooltip wird nicht durch ein mouseout-Event eingeleitet, sondern durch ein mouseover-Event eines anderen Elements, wie z.B. wenn man mit der Maus in Spalte 3 eintritt oder aus der Tabelle austritt (was dem Eintritt in das globale übergeordnete "document" gleichkommt). Für den Fall dass das globale "document" das ToolTip nicht verstecken soll (wie bei einem Übergang zwischen den Spalten 1 und 2) wird durch e.stopPropagation() verhindert, dass das globale "document" dieses Event empfängt.


Alle Zeitangaben in WEZ +2. Es ist jetzt 11:19 Uhr.

Powered by vBulletin® Version 3.8.11 (Deutsch)
Copyright ©2000 - 2024, vBulletin Solutions, Inc.

© Dirk H. 2003 - 2023