Rasmus: Zu viele onMouseouts!

Beitrag lesen

Hi Felix,

Vielen, vielen Dank für diese Antwort! Du hast mir in der Tat weiter geholfen. Einerseits war "Event Bubbling" wohl ein Begriff, der mir gefehlt hat. Andererseits hat mir Dein Lösungsansatz auch sehr geholfen.

Weil bei mir die Tabellen dynamisch mit PHP erstellt werden und im Extremfall sogar mit AJAX vom Server geholt werden, habe ich mich jedoch dagegen entschieden, in PHP für jede Tabellzeile eine Variable anzulegen. Stattdessen initiiere ich in Javascript ein globales Array mit allen "bekannten" Zeilen (beim Aufruf der Seite ist dies ein leeres Array). Falls jetzt die Maus auf eine unbekannte Zeile zieht, meldet sich diese Zeile im Array an und kann von da an mit Javascript gefärbt werden, wie Du, Felix, es auch vorgeschlagen hast. Das Ganze geht solange gut, bis eine AJAX-Funktion auf die Idee kommt, Tabellenzeilen wieder zu löschen. Dann müsste die AJAX-Funktion die Zeilen auch im Array wieder abmelden. Aber welch ein Glück, dass ich das Problem nicht habe habe!

Als Dankeschön und für alle Leute, die wie ich tagelang das ganze Netz nach einer Lösung durchforsten, poste ich noch meine Testseite, die ich vorhin programmiert habe:

  
<html>  
<head>  
<title>Tabellen-Highlight-Test</title>  
<script language="JavaScript">  
<!--  
function forcecolor(id, color)  
  {  
  window.document.all[id].style.backgroundColor = color;  
  }  
function highlight(id)  
  {  
  window.setTimeout("forcecolor('"+id+"', '#aaaaaa')", 0);  
  window.setTimeout("forcecolor('"+id+"', '#bbbbbb')", 60);  
  window.setTimeout("forcecolor('"+id+"', '#cccccc')", 120);  
  }  
function darken(id)  
  {  
  window.setTimeout("forcecolor('"+id+"', '#cccccc')", 0);  
  window.setTimeout("forcecolor('"+id+"', '#bbbbbb')", 60);  
  window.setTimeout("forcecolor('"+id+"', '#aaaaaa')", 120);  
  }  
var alltherows = new Array();  
var isrowlightened = new Array();  
function canyouhandlethis(e)  
  {  
  var i;  
  var welchezeile = -1;  
  // -> Zuerst schauen wir, ob das event.target Teil einer Tabellenzeile ist  
  var element = e.target;  
  while ((element != "[object HTMLTableRowElement]") && (element != null))  
    element = element.parentNode;  
  // -> Wenn ja, schauen wir in alltherows nach, ob wir die Zeile schon kennen.  
  if (element == "[object HTMLTableRowElement]")  
    {  
    for (i=0; i < alltherows.length; i++)  
      if (alltherows[i] == element.id)  
        {  
        welchezeile = i;  
        break;  
        }  
    // -> Wenn nein, wird sie zu alltherows hinzugefuegt: alltherows.push();  
    if (welchezeile == -1)  
      {  
      alltherows.push(element.id);  
      // -> Das hilft aber nur, wenn wir auch isrowlightened.push(true) gesetzt wird.  
      isrowlightened.push(true);  
      //    Und jetzt muss das event.target folgerichtig auch sein highlighting bekommen.  
      highlight(element.id);  
      welchezeile = alltherows.length-1;  
      } else {  
      // -> Falls die Zeile schon bekannt ist UND noch nicht highlighted, wird sie  
      //    angeknipst und isrowlightened[i] auf true gesetzt.  
      if (isrowlightened[i] == false)  
        {  
        isrowlightened[i] = true;  
        highlight(element.id);  
        }  
      }  
    }  
  // -> Und nun werden alle ANDEREN Zeilen in alltherows dunkel gemacht, wenn  
  //    das parallele isrowlightened[i] true gesetzt ist. Setze es dafuer auch auf false.  
  for (i=0; i < alltherows.length; i++)  
    if ((i != welchezeile) && (isrowlightened[i] == true))  
      {  
      isrowlightened[i] = false;  
      darken(alltherows[i]);  
      }  
  }  
//-->  
</script>  
</head>  
<body onmousemove="canyouhandlethis(event)" bgcolor="#aaaaaa">  
Hier noch ein ganz normaler Testtext, der nur im Body-Tag hängt.  
<br>  
<br>  
<br>  
<table>  
<tr class="lightrow" id="zeile_1"><td>Hier <i>kann</i> was abgehen. Aber was?</td><td>Das was wohl keiner.</td></tr>  
<tr class="lightrow" id="zeile_2"><td>Hier <i>kann</i> was abgehen. Aber was?</td><td>Das was wohl keiner.</td></tr>  
<tr class="lightrow" id="zeile_3"><td>Hier <i>kann</i> was abgehen. Aber was?</td><td>Das was wohl keiner.</td></tr>  
<tr class="lightrow" id="zeile_4"><td>Hier <i>kann</i> was abgehen. Aber was?</td><td>Das was wohl keiner.</td></tr>  
<tr class="lightrow" id="zeile_5"><td>Hier <i>kann</i> was abgehen. Aber was?</td><td>Das was wohl keiner.</td></tr>  
</table>  
</body>  
</html>  

Dies muss natürlich noch für IE und andere Browser kompatibel gemacht werden (habe es nur mit Firefox getestet).

Ich finde die Lösung recht elegant, weil man nur eine Javascript-Funktion braucht, die alles selbst regelt. Der noch einzufügende PHP-Code zum Erstellen der Tabellen bleibt also minimal. Problematisch könnte sein, dass Tabellen in Tabellen noch nicht berücksichtigt worden sind (nur die niederste Zeile wird beleuchtet) und dass es nicht ad hoc möglich ist, nur bestimmte Klassen von Zeilen zu highlighten; parentNode findet keine Zeilenklassen sondern nur generell Zeilen. Da müsste man auch noch etwas tricksen. Aber das Grundgerüst dürfte klar sein.

Viele Grüße

Rasmus