Rahmen nur um ausgefüllte Zellen einer dynamisch erstellten Tabelle
Hi72
- javascript
Hallo zusammen,
ich habe folgendes Problem. Ich möchte in JAVAScript ein Periodensystem erstellen. Grundlage ist eine dynamisch erstellte Tabelle mit 11 Zeilen und 19 Spalten. Mit folgenden Codezeilen werden in einzelne Tabellenzellen die ELementsymbole eingetragen:
for (var i=0;i<109;i++){
tabelle.rows[pse[i*6+3]].cells[pse[i*6+4]].innerHTML='<span style= "border: solid">'+pse[i*6+1]+'</span>';
tabelle.rows[pse[i*6+3]].cells[pse[i*6+4]].onclick=function(){myFunction(this);
}
Das funktioniert auch ganz gut. Allerdings sind die Rahmen um die Elementsymbole gezeichnet und damit unterschiedlich breit: bei "Mg" breiter als bei "I". Gibt es eine Möglichkeit, einen Rahmen um die Tabellenzelle zu zeichnen? Die müssten damit eigentlich gleich breit werden. Vielen Dank für Eure Antworten.
Hey,
Dann nimm den border
hier
<span style= "border: solid">'+pse[i*6+1]+'</span>'
raus und sprich die darüber liegende zelle an.
Kurze Frage... Warum nur 109 Elemente? sind wir nicht bei 118?
Gruß
Jo
Hallo,
versuch mal, den spans eine feste Höhe und Breite zu geben, sowie ein display:inline-block
, und das am Besten im Style-Bereich.
Gruß
Jürgen
Ich mach mal den Gunnar: Mit Spans wäre das nicht bedienbar.
Nimm Buttons, gib ihnen z.B. einen 2px Rand und mach sie per Margin und calc(100% + 1px) ein Pixel größer als die Tabellenzelle, so dass sich ihre Ränder überlappen. Sonst hast Du blöde Ecken im Layout.
Den Klick-Handler legst Du auf die Tabelle und prüfst, ob das event-Target ein Button ist, dann brauchst Du nur eine Registrierung.
for (let i=0; i<109; i++) {
tabelle.rows[pse[i*6+3]].cells[pse[i*6+4]].innerHTML='<button>'+pse[i*6+1]+'</button>';
}
tabelle.addEventListener('click', function(ev) {
if (ev.target.tagName === "BUTTON")
handleClick(this, ev.target.textContent)
};
table {
border-collapse: collapse;
width: auto;
}
td {
width: 2em; height: 2em; padding: 0;
background-color: white;
}
button {
margin: -1px -1px; padding: 0; width: calc(100% + 2px); height: calc(100% + 2px);
border: 2px solid black;
}
Rolf
By the way - deine pse-Tabelle klingt nach verbesserungsfähigem Datendesign. Kannst Du daraus keine Tabelle von Objekten machen, so dass deine for-Schleife so aussieht. Und meine Button-Erzeugung muss ich korrigieren, der Default-Typ ist "submit", ich weiß nicht ob das zu deiner Webseite passt.
for (let i=0; i<109; i++) {
let elementInfo = pse[i];
tabelle.rows[elementInfo.rowIndex]
.cells[elementInfo.colIndex]
.innerHTML='<button type="button">'+elementInfo.symbol+'</button>';
}
tab[i*n+k] - das ist Assembler-Design der 50-er Jahre. Welche Not trieb dich, es so zu machen?
Rolf
Hallo Rolf b,
Und meine Button-Erzeugung muss ich korrigieren, der Default-Typ ist "submit", ich weiß nicht ob das zu deiner Webseite passt.
❓ type="button"
existiert.
Bis demnächst
Matthias
Ja. Schreibte ich doch, sozusagen als Update. Ich konnte es nur nicht mehr in den Ursprungsbeitrag hineineditieren, weil ich mir das mit dem Datendesign-Hinweis selbst verbaut hatte (beantwortete Beiträge editieren darf ich nicht, dazu muss man vermutlich Mod sein).
Rolf
Hallo Rolf,
for (let i=0; i<109; i++) {
wo du hier schon mal let
verwendest: wie reagieren die Browser, die let noch nicht unterstützen? Laut caniuse sind das etwa 20%.
Gruß
Jürgen
Mit Nichtausführen des Scripts. Dann also var...
Rolf
Hallo Hi72,
Wenn es nur um die Rahmen geht, die können auch die Tabellenzellen selbst bekommen.
td:not(:empty) { border: thin solid; }
Bis demnächst
Matthias
:not(:empty) - da war was. Ich hatte mich auf "es gibt kein :has()" fokussiert und diesen Ausnahmeselektor vergessen.
Es geht aber auch ganz ohne explizite Border, wenn man mit Buttons arbeitet und sie so gestyled lässt wie sie vom Browser geschaffen wurden. Nur die Größe muss man etwas tweaken.
table {
border-collapse: collapse;
}
td {
width: 2em; height: 2em; padding: 0;
background-color: white;
}
button {
padding: 0;
width: calc(100% + 1px); height:calc(100% + 1px);
}
Rolf
@@Matthias Apsel
Wenn es nur um die Rahmen geht, die können auch die Tabellenzellen selbst bekommen.
td:not(:empty) { border: thin solid; }
Dazu braucht man auch nicht unbedingt :not
und :empty
, dafür gibt es die Eigenschaft empty-cells
, die allerdings nur im Rahmenmodell mit getrennten Rahmen wirkt. (CodePen)
LLAP 🖖
@@Hi72
tabelle.rows[pse[i*6+3]].cells[pse[i*6+4]].onclick=function(){myFunction(this); }
Das funktioniert auch ganz gut.
Außer dass es nicht funktioniert. Funktioniert im Sinne von: funktioniert bei allen.
Tabellenzellen sind keine interaktiven Elemente, mit Tastatursteuerung kann man sie nicht anwählen.
Wenn du eine JavaScript-Funktion aufrufen willst, musst du in jeder Tabellenzelle jeweils einen <button>
dafür vorsehen.
Das click
-Event registrierst du am besten für die ganze Tabelle und fragst dann ab in Eventhandlerfunktion ab, welches Element das Click-Ereignis ausgelöst hat. (event delegation)
Sieht so aus: CodePen
LLAP 🖖
@@Gunnar Bittersmann
Tabellenzellen sind keine interaktiven Elemente, mit Tastatursteuerung kann man sie nicht anwählen.
Um den Fehler sichtbar zu machen, habe ich u.a. in einem Stylesheet zu stehen:
:root
{
--error-color: red;
--error-outline: 0.5rem solid var(--error-color);
}
[onclick]:not(a):not(button):not(input):not([tabindex]),
[onclick][tabindex^="-"],
[ng-click]:not(a):not(button):not(input):not([tabindex]),
[ng-click][tabindex^="-"]
{
ERROR: click-Event für nicht fokussierbares Element;
outline: var(--error-outline) !important;
}
LLAP 🖖
PS: Welche Sprache muss man angeben, damit der Syntax-Highlighter in CSS-Code keine roten Kästchen malt?
Vielen Dank für die vielen Antworten - mit <button> ... </button> funktioniert alles so wie es soll.