javascript - Hur kan jag låta en tabells kropp scrolla men hålla dess huvud fast på plats?
Jag skriver en sida där jag behöver att en HTML-tabell håller en viss storlek. Jag behöver att rubrikerna högst upp i tabellen alltid ska vara där, men jag behöver också att tabellens kropp kan scrollas oavsett hur många rader som läggs till i tabellen. Tänk en mini-version av Excel. Detta verkar vara en enkel uppgift men nästan varje lösning jag har hittat på nätet har någon nackdel. Hur kan jag lösa detta?
Svar #1
Jag var tvungen att hitta samma svar. Det bästa exemplet jag hittade är https://www.cssplay.co.uk/menu/cssplay-sticky-snap-table.html - jag tyckte att exempel #2 fungerade bra för mig. Du kommer att behöva sätta höjden på den inre tabellen med JavaScript, resten är CSS.
Svar #2
Jag tyckte att DataTables var ganska flexibel. Medan dess standardversion är baserad på jquery, finns det också ett AngularJs-plugin.
Svar #3
Jag såg Sean Haddys utmärkta lösning på en liknande fråga och tog mig friheten att göra några ändringar:
- Använd klasser istället för ID, så att ett jQuery-skript kan återanvändas för flera tabeller på en sida
- Lade till stöd för semantiska HTML-tabellelement som caption, thead, tfoot och tbody
- Gjorde rullningslisten valfri så att den inte visas för tabeller som är "kortare" än den rullbara höjden
- Justerade rullningsdivens bredd för att få skrollfältet upp till bordets högra kant
Gjorde konceptet tillgängligt genom
- använder aria-hidden="true" på injicerad statisk tabellrubrik
- och lämna originaltråden på plats, bara dold med jQuery och ställ
aria-hidden="false"
Sean gjorde det tunga jobbet, dock. Tack också till Matt Burland för att ha påpekat behovet av att stödja tfoot.
Se själv på http://jsfiddle.net/jhfrench/eNP2N/
Svar #4
Det du behöver är:
ha en tabellkropp med begränsad höjd eftersom rullning endast sker när innehållet är större än rullningsfönstret. Men
tbodykan inte ges storlek, och du måste visa det som enblockför att göra det:tbody { overflow-y: auto; display: block; max-height: 10em; /Till exempel }
Synkronisera kolumnbredderna för tabellhuvudet och tabellkroppen igen eftersom att göra den senare till ett
blockgjorde den till ett orelaterat element. Det enda sättet att göra detta är att simulera synkronisering genom att tvinga samma kolumnbredder på båda.
Men eftersom tbody självt nu är ett block, kan det inte längre bete sig som en table. Eftersom du fortfarande behöver ett table-beteende för att visa dina kolumner korrekt, är lösningen att be varje rad att visas som individuella table:
thead {
display: table;
width: 100%; // Fill the containing table
}
tbody tr {
display: table;
width: 100%; // Fill the containing table
}
(Observera att med denna teknik kommer du inte längre att kunna sträcka dig över rader).
När det är gjort kan du tvinga kolumnbredder att ha samma bredd i både thead och tbody. Du kan notera det:
- individuellt för varje kolumn (genom specifika CSS-klasser eller inline-styling), vilket är ganska besvärligt att göra för varje tabbelfall ;
- jämt för alla kolumner (genom
th, td { width: 20%; }om du till exempel har 5 kolumner), vilket är mer praktiskt (ingen behov av att sätta bredd för varje tabellinstans) men kan inte fungera för vilket antal kolumner som helst - enhetligt för valfritt antal kolumner, genom en
fixedtabellayout (dvs. samma bredd för alla).
Jag föredrar det sista alternativet, som kräver att man lägger till:
thead {
table-layout: fixed; // Same layout for all cells
}
tbody tr {
table-layout: fixed; // Same layout for all cells
}
th, td {
width: auto; // Same width for all cells, if table has fixed layout
}
Se en demo här, forkad från svaret på den här frågan.
Svar #5
Har du försökt använda thead och tbody, och sätta en fast höjd på tbody med overflow:scroll?
Vilka är dina målbläddrare?
REDIGERA: Det fungerade bra (nästan) i Firefox - tillägget av den vertikala rullningslisten orsakade behovet av en horisontell rullningslist också - usch. IE satte bara höjden på varje td till det jag hade specificerat för tbody:s höjd. Här är det bästa jag kunde komma på:
<html>
<head>
<title>Blah</title>
<style type="text/css">
table { width:300px; }
tbody { height:10em; overflow:scroll;}
td { height:auto; }
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>One</th><th>Two</th>
</td>
</tr>
</thead>
<tbody>
<tr><td>Data</td><td>Data</td></tr>
<tr><td>Data</td><td>Data</td></tr>
<tr><td>Data</td><td>Data</td></tr>
<tr><td>Data</td><td>Data</td></tr>
<tr><td>Data</td><td>Data</td></tr>
<tr><td>Data</td><td>Data</td></tr>
<tr><td>Data</td><td>Data</td></tr>
<tr><td>Data</td><td>Data</td></tr>
<tr><td>Data</td><td>Data</td></tr>
<tr><td>Data</td><td>Data</td></tr>
<tr><td>Data</td><td>Data</td></tr>
<tr><td>Data</td><td>Data</td></tr>
<tr><td>Data</td><td>Data</td></tr>
<tr><td>Data</td><td>Data</td></tr>
<tr><td>Data</td><td>Data</td></tr>
</tbody>
</table>
</body>
</html>
