Wechsel von "display none" nach "display block" zerstört Tabellen-Layout
Enrico
- javascript
Hallo zusammen,
ich erzeuge über PHP folgende Tabelle:
<table>
<thead>
...
</thead>
<tbody id="listeHeute">
...
</tbody>
<tbody id="listeZukuenftig">
...
</tbody>
<tbody id="listeVergangen">
...
</tbody>
</table>
Die Tabelle führt einen eventuell heute anfallenden Auftritt von uns auf sowie zukünftige und vergangene Auftritte:
Ich möchte nun mittels JavaScript in Abhängigkeit vom angeklickten Textlink ("Heute", "Zukünftig" und "Vergangen") die jeweils nicht benötigten tbodies ausblenden lassen:
var kategorien = ["heute", "zukuenftig", "vergangen"];
var w,
x = kategorien.length;
aufrufen (0);
function aufrufen (nr)
{
w = 0;
for (; w < x; w++)
{
document.getElementById("liste" + kategorien[w][0].toUpperCase() + kategorien[w].substring(1)).style.display = "none"
}
document.getElementById("liste" + kategorien[nr][0].toUpperCase() + kategorien[nr].substring(1)).style.display = "block";
}
Das Array "kategorien" wird ebenfalls über PHP erzeugt. Gibt es keinen heutigen Auftritt, so wird "kategorien" keinen Eintrag "heute" enthalten. Sind nur vergangene Auftritte vorhanden, dann wird "kategorien" nur den Eintrag "vergangen" enthalten usw. Deswegen durchlaufe ich das Array auch mit einer Schleife.
Ich verstecke zuerst alle tbodies aus ("display: none") und möchte nur den anzuzeigenden tbody sichtbar machen ("display: block").
Leider wird dabei aber der Tabellenaufbau zerstört:
Was mache ich falsch?
Vielen Dank für eure Hilfe und Gruß Enrico
Tach!
Ich verstecke zuerst alle tbodies aus ("display: none") und möchte nur den anzuzeigenden tbody sichtbar machen ("display: block").
Leider wird dabei aber der Tabellenaufbau zerstört:
Was mache ich falsch?
Schau mal in die Entwicklertools, welcher Wert für display bei einem tbody voreingestellt ist. Diese Voreinstellung bekommst du auch wieder, wenn du den Wert none nur entfernst statt einen unpassenden zu setzen.
dedlfix.
Hi dedlfix,
perfekt! "table-row-group" anstatt "block" und schon klappt es.
Da muss man erst mal darauf kommen 😀
Danke und Gruß Enrico
@@Enrico
perfekt! "table-row-group" anstatt "block" und schon klappt es.
Das war nicht das, was dedlfix dir sagen wollte, sondern ""
.
Und damit hat dedlfix dich leider auf deinem Irrweg ein Stück vorangebracht.
Der Fehler ist, überhaupt CSS-Eigenschaften direkt mit JavaScript zu ändern. Dazu gleich mehr.
LLAP 🖖
@@Enrico
var w, x = kategorien.length;
w
brauchst du an der Stelle nicht, sondern nur in der Funktion aufrufen()
. Die Variable sollte demzufolge in der Funktion lokal deklariert werden.
function aufrufen (nr) { w = 0; for (; w < x; w++)
Seltsame Schreibweise. Üblich ist
function aufrufen(nr)
{
for (var w = 0; w < x; w++)
oder wenn du die Variable vorher deklarieren willst:
function aufrufen(nr)
{
var w;
for (w = 0; w < x; w++)
In modernen Browsern mit dem Schlüsselwort let
statt var
.
document.getElementById("liste" + kategorien[w][0].toUpperCase() + kategorien[w].substring(1))
Kannst du deine IDs statt in CamelCase nicht mit Bindestrich benennen? <tbody id="liste-heute">
usw.? Dann kannst du dir den ganzen umständlichen Kram sparen und hast einfach
document.getElementById("liste-" + kategorien[w])
Ich verstecke zuerst alle tbodies aus ("display: none") und möchte nur den anzuzeigenden tbody sichtbar machen ("display: block").
Warum das denn? Durch die Schleife gehen und abfragen, ob der aktuelle Schleifenindex w
gleich nr
ist. Wenn ja, auf "block"
setzen, andernfalls auf ""
(siehe andere Antwort):
function aufrufen(nr)
{
for (var w = 0; w < x; w++)
{
if (w == nr)
{
document.getElementById("liste-" + kategorien[w]).style.display = "block";
}
else
{
document.getElementById("liste-" + kategorien[w]).style.display = "";
}
}
}
oder kurz
function aufrufen(nr)
{
for (var w = 0; w < x; w++)
{
document.getElementById("liste-" + kategorien[w]).style.display = (w == nr) ? "block" : "";
}
}
Was mache ich falsch?
.style.display = "none"
Ich krame mal wieder den Cheatah raus:
„Was hingegen schwer ist, ist in die Köpfe der Menschen zu bringen, dass Layout-Informationen in den CSS-Code gehören, nicht in den JavaScript-Code. JavaScript ist wunderbar geeignet, die DOM-Objekte auf eine Weise zu verändern, die in CSS genutzt werden kann.“
Nun könnte jemand sagen: Das Anzeigen/Nicht-Anzeigen wäre keine „Layout-Information“. Dann hat das erst recht nichts im style
-Objekt zu suchen.
Zum Nicht-Anzeigen gibt es das HTML-Attribut hidden
. Dieses ist hier zu verwenden:
function aufrufen(nr)
{
for (var w = 0; w < x; w++)
{
if (w == nr)
{
document.getElementById("liste-" + kategorien[w]).removeAttribute("hidden");
}
else
{
document.getElementById("liste-" + kategorien[w]).setAttribute("hidden", "");
}
}
}
Dann wäre das Problem mit dem flaschen Wert für die display
-Eigenschaft gar nicht erst aufgetaucht.
LLAP 🖖
@@Gunnar Bittersmann
Zum Nicht-Anzeigen gibt es das HTML-Attribut
hidden
. Dieses ist hier zu verwenden:function aufrufen(nr) { for (var w = 0; w < x; w++) { if (w == nr) { document.getElementById("liste-" + kategorien[w]).removeAttribute("hidden"); } else { document.getElementById("liste-" + kategorien[w]).setAttribute("hidden", ""); } } }
Es sollte auch so gehen:
function aufrufen(nr)
{
for (var w = 0; w < x; w++)
{
if (w == nr)
{
document.getElementById("liste-" + kategorien[w]).hidden = false;
}
else
{
document.getElementById("liste-" + kategorien[w]).hidden = true;
}
}
}
Was sich dann kurz schreiben lässt:
function aufrufen(nr)
{
for (var w = 0; w < x; w++)
{
document.getElementById("liste-" + kategorien[w]).hidden = (w != nr);
}
}
IIRC haben einige ältere Browser (IE < ?) Probleme mit .hidden
; da funktioniert’s nur mit setAttribute()
/removeAttribute()
.
LLAP 🖖
Hi Gunnar,
ich bin platt! Super Antwort! Und danke, dass Du mich auf den Irrweg hingewiesen hast!
Gruß Enrico