Saya ingin dapat "tweak" sebuah tabel HTML's presentasi untuk menambahkan satu fitur: ketika bergulir melalui halaman sehingga tabel pada layar tapi header baris off-layar, saya ingin header untuk tetap terlihat di bagian atas dari area tampilan.
Ini akan secara konseptual seperti "freeze panes" fitur di Excel. Namun, sebuah halaman HTML yang dapat berisi beberapa tabel dalam dan aku hanya ingin hal itu terjadi untuk meja yang sedang di-lihat, hanya ketika sedang di-view.
Catatan: saya've melihat salah satu solusi dimana tabel data dibuat digulir sedangkan header tidak gulir. Yang's bukan solusi I'm cari.
I've membuat bukti-of-konsep solusi menggunakan jQuery.
I've sekarang punya kode ini di Mercurial bitbucket repositori. File utama tables.html
.
I'm menyadari satu masalah dengan ini: jika tabel berisi jangkar, dan jika anda membuka URL dengan yang ditentukan jangkar di browser, ketika beban halaman, baris dengan anchor mungkin akan dikaburkan oleh kepala mengambang.
Update 2017-12-11: saya melihat ini doesn't bekerja dengan saat ini Firefox (57) dan Krom (63). Tidak yakin kapan dan mengapa ini berhenti bekerja, atau bagaimana untuk memperbaikinya. Tapi sekarang, saya pikir jawaban yang diterima oleh Hendy Irawan lebih unggul.
Craig, saya halus kode anda sedikit (di antara beberapa hal lain itu's sekarang menggunakan position:fixed) dan dibungkus itu sebagai sebuah plugin jQuery.
Coba di sini:
Dan mendapatkan kode sumber di sini: https://github.com/jmosbech/StickyTableHeaders
Check out jQuery.floatThead (demo yang tersedia) yang sangat keren, dapat bekerja dengan DataTables juga, dan bahkan dapat bekerja di dalam sebuah overflow: auto
wadah.
Jika anda're menargetkan modern css3 compliant browser (Browser yang mendukung: https://caniuse.com/#feat=css-sticky) anda dapat menggunakan posisi:lengket
, yang doesn't membutuhkan JS dan tidak't menghancurkan tata letak meja miss menyelaraskan th dan td dari kolom yang sama. Juga tidak memerlukan kolom tetap lebar untuk bekerja dengan baik.
Contoh untuk satu baris header:
thead th
{
position: sticky;
top: 0px;
}
Untuk theads dengan 1 atau 2 baris, anda dapat menggunakan sesuatu seperti ini:
thead > :last-child th
{
position: sticky;
top: 30px; /* This is for all the the "th" elements in the second row, (in this casa is the last child element into the thead) */
}
thead > :first-child th
{
position: sticky;
top: 0px; /* This is for all the the "th" elements in the first child row */
}
Anda mungkin perlu untuk bermain sedikit dengan top properti last child mengubah jumlah pixel untuk menyesuaikan tinggi baris pertama (+ margin + perbatasan + padding, jika ada), sehingga baris kedua tongkat hanya turun di bawah yang pertama.
Juga kedua solusi ini bekerja bahkan jika anda memiliki lebih dari satu tabel dalam halaman yang sama: th
elemen dari masing-masing mulai menjadi lengket ketika posisi teratas adalah salah satu yang ditunjukkan dalam css definisi dan hilang begitu saja ketika semua meja gulungan bawah. Jadi jika ada tabel lagi semua pekerjaan yang indah dengan cara yang sama.
Mengapa menggunakan last-child sebelum dan anak setelah di css?
Karena aturan css yang diberikan oleh browser dalam urutan yang sama seperti anda menuliskannya ke dalam file css dan karena ini, jika anda hanya memiliki 1 baris ke thead elemen baris pertama adalah bersamaan baris terakhir dan pertama-anak aturan perlu menimpa terakhir-anak satu. Jika tidak, anda akan memiliki offset baris 30 px dari margin atas yang saya kira anda don't ingin.
Masalah yang diketahui dari posisi: sticky adalah bahwa hal itu doesn't bekerja pada elemen thead atau baris tabel: anda harus menargetkan th elemen. Hopping masalah ini akan diselesaikan di masa depan versi browser.
I've mengalami masalah ini baru-baru ini. Sayangnya, saya harus melakukan 2 tabel, satu untuk header dan satu untuk tubuh. It's mungkin bukan pendekatan yang terbaik yang pernah tapi here goes:
<html>
<head>
<title>oh hai</title>
</head>
<body>
<table id="tableHeader">
<tr>
<th style="width:100px; background-color:#CCCCCC">col header</th>
<th style="width:100px; background-color:#CCCCCC">col header</th>
</tr>
</table>
<div style="height:50px; overflow:auto; width:250px">
<table>
<tr>
<td style="height:50px; width:100px; background-color:#DDDDDD">data1</td>
<td style="height:50px; width:100px; background-color:#DDDDDD">data1</td>
</tr>
<tr>
<td style="height:50px; width:100px; background-color:#DDDDDD">data2</td>
<td style="height:50px; width:100px; background-color:#DDDDDD">data2</td>
</tr>
</table>
</div>
</body>
</html>
Ini bekerja untuk saya, it's mungkin bukan cara yang elegan tetapi tidak bekerja. I'll menyelidiki begitu melihat apakah saya bisa melakukan sesuatu yang lebih baik, tetapi hal ini memungkinkan untuk beberapa tabel.
Pergi baca di meluap kepatutan untuk melihat apakah itu sesuai dengan kebutuhan anda
Alternatif-alternatif yang mungkin
js-mengambang-table-header
js-mengambang-table-header (Google Code)
Di Drupal
Saya memiliki Drupal 6 situs. Saya ada di admin "modul" di halaman, dan melihat tabel memiliki fitur yang tepat!
Melihat kode, tampaknya akan dilaksanakan oleh sebuah file yang bernama tableheader.js
. Itu berlaku fitur pada semua tabel dengan kelas lengket-enabled
.
Untuk situs Drupal, saya'd seperti untuk dapat membuat penggunaan yang tableheader.js
modul sebagai-adalah untuk konten pengguna. tableheader.js
doesn't tampaknya akan hadir pada pengguna laman konten di Drupal. Aku diposting forum pesan untuk bertanya bagaimana untuk memodifikasi tema Drupal sehingga's tersedia. Menurut sebuah respon, tableheader.js
dapat ditambahkan ke tema Drupal menggunakan drupal_add_js()
dalam tema's template.php
sebagai berikut:
drupal_add_js('misc/tableheader.js', 'core');
Ini adalah benar-benar hal yang sulit untuk memiliki header lengket di meja anda. Aku punya kebutuhan yang sama tetapi dengan asp:GridView dan kemudian saya menemukan itu benar-benar berpikir untuk memiliki sticky header pada gridview. Ada banyak solusi yang tersedia dan butuh 3 hari mencoba semua solusi, tetapi tidak satupun dari mereka bisa memuaskan.
Masalah utama yang saya hadapi dengan solusi ini adalah masalah keselarasan. Ketika anda mencoba untuk membuat header mengambang, entah bagaimana keselarasan header sel-sel dan sel-sel tubuh yang keluar jalur.
Dengan beberapa solusi, saya juga punya masalah mendapatkan header tumpang tindih untuk pertama beberapa baris dari tubuh, yang menyebabkan tubuh mendapatkan baris yang tersembunyi di belakang kepala mengambang.
Jadi sekarang saya harus melaksanakan, saya sendiri logika untuk mencapai hal ini, meskipun saya juga tidak menganggap ini sebagai solusi sempurna tapi ini juga bisa membantu untuk seseorang,
Di bawah ini adalah tabel contoh.
<div class="table-holder">
<table id="MyTable" cellpadding="4" cellspacing="0" border="1px" class="customerTable">
<thead>
<tr><th>ID</th><th>First Name</th><th>Last Name</th><th>DOB</th><th>Place</th></tr>
</thead>
<tbody>
<tr><td>1</td><td>Customer1</td><td>LastName</td><td>1-1-1</td><td>SUN</td></tr>
<tr><td>2</td><td>Customer2</td><td>LastName</td><td>2-2-2</td><td>Earth</td></tr>
<tr><td>3</td><td>Customer3</td><td>LastName</td><td>3-3-3</td><td>Mars</td></tr>
<tr><td>4</td><td>Customer4</td><td>LastName</td><td>4-4-4</td><td>Venus</td></tr>
<tr><td>5</td><td>Customer5</td><td>LastName</td><td>5-5-5</td><td>Saturn</td></tr>
<tr><td>6</td><td>Customer6</td><td>LastName</td><td>6-6-6</td><td>Jupitor</td></tr>
<tr><td>7</td><td>Customer7</td><td>LastName</td><td>7-7-7</td><td>Mercury</td></tr>
<tr><td>8</td><td>Customer8</td><td>LastName</td><td>8-8-8</td><td>Moon</td></tr>
<tr><td>9</td><td>Customer9</td><td>LastName</td><td>9-9-9</td><td>Uranus</td></tr>
<tr><td>10</td><td>Customer10</td><td>LastName</td><td>10-10-10</td><td>Neptune</td></tr>
</tbody>
</table>
</div>
Catatan: tabel ini dibungkus ke dalam sebuah DIV dengan atribut class sama dengan 'meja-holder'.
Di bawah ini adalah script JQuery yang saya tambahkan di halaman html header.
<script src="../Scripts/jquery-1.7.2.min.js" type="text/javascript"></script>
<script src="../Scripts/jquery-ui.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
//create var for table holder
var originalTableHolder = $(".table-holder");
// set the table holder's with
originalTableHolder.width($('table', originalTableHolder).width() + 17);
// Create a clone of table holder DIV
var clonedtableHolder = originalTableHolder.clone();
// Calculate height of all header rows.
var headerHeight = 0;
$('thead', originalTableHolder).each(function (index, element) {
headerHeight = headerHeight + $(element).height();
});
// Set the position of cloned table so that cloned table overlapped the original
clonedtableHolder.css('position', 'relative');
clonedtableHolder.css('top', headerHeight + 'px');
// Set the height of cloned header equal to header height only so that body is not visible of cloned header
clonedtableHolder.height(headerHeight);
clonedtableHolder.css('overflow', 'hidden');
// reset the ID attribute of each element in cloned table
$('*', clonedtableHolder).each(function (index, element) {
if ($(element).attr('id')) {
$(element).attr('id', $(element).attr('id') + '_Cloned');
}
});
originalTableHolder.css('border-bottom', '1px solid #aaa');
// Place the cloned table holder before original one
originalTableHolder.before(clonedtableHolder);
});
</script>
dan akhirnya di bawah ini adalah CSS class untuk sedikit mewarnai tujuan.
.table-holder
{
height:200px;
overflow:auto;
border-width:0px;
}
.customerTable thead
{
background: #4b6c9e;
color:White;
}
Jadi seluruh ide dari logika ini adalah untuk menempatkan meja ke meja dudukan div dan membuat clone dari yang pemegang pada sisi klien saat halaman dimuat. Sekarang menyembunyikan tubuh dari tabel di dalam clone pemegang dan posisi yang tersisa header bagian atas header asli.
Solusi yang sama juga bekerja untuk asp:gridview, anda perlu menambahkan dua langkah lagi untuk mencapai hal ini di gridview,
jika (hal ini.HeaderRow != null) { ini.HeaderRow.TableSection = TableRowSection.TableHeader; }
<div class="meja-holder"></div>
.Note: jika anda memiliki header yang dapat diklik kontrol maka anda mungkin perlu menambahkan beberapa script jQuery untuk melewati peristiwa-peristiwa yang diangkat dalam kloning header header asli. Kode ini sudah tersedia di jQuery lengket-header plugin buat oleh [jmosbech][1]
Jika anda menggunakan layar penuh meja anda mungkin tertarik dalam pengaturan th untuk menampilkan:fixed; top:0; atau mencoba sangat mirip pendekatan melalui css.
Update
Hanya cepat membangun solusi yang bekerja dengan iframe (html4.0). Contoh ini TIDAK sesuai standar, namun anda akan dengan mudah dapat memperbaikinya:
outer.html
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Outer</title>
<body>
<iframe src="test.html" width="200" height="100"></iframe>
</body>
</html>
test.html
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Floating</title>
<style type="text/css">
.content{
position:relative;
}
thead{
background-color:red;
position:fixed;
top:0;
}
</style>
<body>
<div class="content">
<table>
<thead>
<tr class="top"><td>Title</td></tr>
</head>
<tbody>
<tr><td>a</td></tr>
<tr><td>b</td></tr>
<tr><td>c</td></tr>
<tr><td>d</td></tr>
<tr><td>e</td></tr>
<tr><td>e</td></tr>
<tr><td>e</td></tr>
<tr><td>e</td></tr>
<tr><td>e</td></tr>
<tr><td>e</td></tr>
</tbody>
</table>
</div>
</body>
</html>
Menggunakan display: tetap
pada thead
bagian harus bekerja, tapi itu hanya bekerja pada saat meja di pandang, anda akan memerlukan bantuan dari JavaScript. Dan itu akan menjadi rumit karena akan perlu untuk mengetahui bergulir tempat dan lokasi elemen relatif terhadap viewport, yang merupakan salah satu daerah utama dari browser ketidakcocokan.
Lihatlah populer framework JavaScript (jQuery, MooTools, YUI, dll.) untuk melihat jika mereka dapat melakukan apa yang anda inginkan atau membuat lebih mudah untuk melakukan apa yang anda inginkan.
It's frustasi bahwa apa yang bekerja di browser doesn't bekerja pada orang lain. Berikut ini bekerja di Firefox, tapi tidak di Chrome atau IE:
<table width="80%">
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
</tr>
</thead>
<tbody style="height:50px; overflow:auto">
<tr>
<td>Cell A1</td>
<td>Cell B1</td>
<td>Cell C1</td>
</tr>
<tr>
<td>Cell A2</td>
<td>Cell B2</td>
<td>Cell C2</td>
</tr>
<tr>
<td>Cell A3</td>
<td>Cell B3</td>
<td>Cell C3</td>
</tr>
</tbody>
</table>
Bahwa bukti dari konsep yang anda buat adalah besar! Namun saya juga menemukan plugin jQuery ini yang tampaknya bekerja dengan sangat baik. Semoga membantu!