Заголовок таблицы должен оставаться фиксированным в верхней части, когда пользователь прокручивает его вне поля зрения с помощью jQuery
Я пытаюсь создать таблицу HTML, в которой заголовок будет находиться в верхней части страницы, когда И ТОЛЬКО, когда пользователь прокручивает его вне поля зрения. Например, таблица может быть на 500 пикселей вниз от страницы, как я могу ее сделать так, чтобы, если пользователь прокручивает заголовок вне поля зрения (браузер так или иначе обнаруживает, что он больше не выглядит в окне), он останется в верхней части? Кто-нибудь может дать мне решение Javascript?
<table>
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
</tr>
</thead>
<tbody>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
</tbody>
</table>
Итак, в приведенном выше примере я хочу, чтобы <thead>
прокручивался со страницей, если он вышел из вида.
ВАЖНО: я НЕ ищет решение, в котором <tbody>
будет иметь полосу прокрутки (переполнение: авто).
Ответы
Ответ 1
Вы сделали бы что-то вроде этого, нажав на обработчик события scroll
на window
и используя другой table
с фиксированной позицией, чтобы отобразить заголовок в верхней части страницы.
HTML:
<table id="header-fixed"></table>
CSS
#header-fixed {
position: fixed;
top: 0px; display:none;
background-color:white;
}
JavaScript:
var tableOffset = $("#table-1").offset().top;
var $header = $("#table-1 > thead").clone();
var $fixedHeader = $("#header-fixed").append($header);
$(window).bind("scroll", function() {
var offset = $(this).scrollTop();
if (offset >= tableOffset && $fixedHeader.is(":hidden")) {
$fixedHeader.show();
}
else if (offset < tableOffset) {
$fixedHeader.hide();
}
});
Это покажет заголовок таблицы, когда пользователь прокручивается достаточно далеко, чтобы скрыть исходную таблицу. Он снова скроется, когда пользователь снова прокрутит страницу.
Рабочий пример: http://jsfiddle.net/andrewwhitaker/fj8wM/
Ответ 2
Ну, я пытался получить тот же эффект, не прибегая к столбцам фиксированного размера или имеющим фиксированную высоту для всей таблицы.
Решение, с которым я столкнулся, - это взломать. Он состоит из дублирования всей таблицы, а затем скрывает все, кроме заголовка, и делает фиксированную позицию.
HTML
<div id="table-container">
<table id="maintable">
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
</tr>
</thead>
<tbody>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>some really long line here instead</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
</tbody>
</table>
<div id="bottom_anchor"></div>
</div>
CSS
body { height: 1000px; }
thead{
background-color:white;
}
Javascript
function moveScroll(){
var scroll = $(window).scrollTop();
var anchor_top = $("#maintable").offset().top;
var anchor_bottom = $("#bottom_anchor").offset().top;
if (scroll>anchor_top && scroll<anchor_bottom) {
clone_table = $("#clone");
if(clone_table.length == 0){
clone_table = $("#maintable").clone();
clone_table.attr('id', 'clone');
clone_table.css({position:'fixed',
'pointer-events': 'none',
top:0});
clone_table.width($("#maintable").width());
$("#table-container").append(clone_table);
$("#clone").css({visibility:'hidden'});
$("#clone thead").css({'visibility':'visible','pointer-events':'auto'});
}
} else {
$("#clone").remove();
}
}
$(window).scroll(moveScroll);
Смотрите здесь: http://jsfiddle.net/QHQGF/7/
Изменить: обновил код, чтобы thead мог получать события указателя (так что кнопки и ссылки в заголовке все еще работают). Это устраняет проблему, о которой сообщают luhfluh и Joe M.
Новый jsfiddle здесь: http://jsfiddle.net/cjKEx/
Ответ 3
Чистый CSS (без поддержки IE11):
table th {
position: -webkit-sticky; // this is for all Safari (Desktop & iOS), not for Chrome
position: sticky;
top: 0;
z-index: 5;
background: #fff;
}
Ответ 4
Мне удалось исправить проблему с изменением ширины столбцов. Я начал с решения Andrew выше (спасибо большое!), А затем добавил один маленький цикл, чтобы установить ширину клонированных td:
$("#header-fixed td").each(function(index){
var index2 = index;
$(this).width(function(index2){
return $("#table-1 td").eq(index).width();
});
});
Это решает проблему без необходимости клонировать всю таблицу и скрывать тело. Я новичок в JavaScript и jQuery (и для), поэтому любые комментарии оценены.
Ответ 5
Я написал плагин, который делает это. Я работаю над этим около года, и я думаю, что он отлично справляется со всеми угловыми делами:
- прокрутка в контейнере с переполнением
- прокрутка в окне
- забота о том, что происходит при изменении размера окна
- сохранение ваших событий в заголовке
- главное, это не заставляет вас менять таблицу css, чтобы заставить ее работать.
Вот несколько демо/документов:
http://mkoryak.github.io/floatThead/
Ответ 6
На сегодняшний день это лучшее решение, которое я нашел для фиксированного заголовка таблицы.
ОБНОВЛЕНИЕ 5/11: Исправлена ошибка горизонтальной прокрутки, как указано Керри Джонсоном
Codepen: https://codepen.io/josephting/pen/demELL
;(function($) {
$.fn.fixMe = function() {
return this.each(function() {
var $this = $(this),
$t_fixed;
function init() {
$this.wrap('<div class="container" />');
$t_fixed = $this.clone();
$t_fixed.find("tbody").remove().end().addClass("fixed").insertBefore($this);
resizeFixed();
}
function resizeFixed() {
$t_fixed.width($this.outerWidth());
$t_fixed.find("th").each(function(index) {
$(this).css("width",$this.find("th").eq(index).outerWidth()+"px");
});
}
function scrollFixed() {
var offsetY = $(this).scrollTop(),
offsetX = $(this).scrollLeft(),
tableOffsetTop = $this.offset().top,
tableOffsetBottom = tableOffsetTop + $this.height() - $this.find("thead").height(),
tableOffsetLeft = $this.offset().left;
if(offsetY < tableOffsetTop || offsetY > tableOffsetBottom)
$t_fixed.hide();
else if(offsetY >= tableOffsetTop && offsetY <= tableOffsetBottom && $t_fixed.is(":hidden"))
$t_fixed.show();
$t_fixed.css("left", tableOffsetLeft - offsetX + "px");
}
$(window).resize(resizeFixed);
$(window).scroll(scrollFixed);
init();
});
};
})(jQuery);
$(document).ready(function(){
$("table").fixMe();
$(".up").click(function() {
$('html, body').animate({
scrollTop: 0
}, 2000);
});
});
body{
font:1.2em normal Arial,sans-serif;
color:#34495E;
}
h1{
text-align:center;
text-transform:uppercase;
letter-spacing:-2px;
font-size:2.5em;
margin:20px 0;
}
.container{
width:90%;
margin:auto;
}
table{
border-collapse:collapse;
width:100%;
}
.blue{
border:2px solid #1ABC9C;
}
.blue thead{
background:#1ABC9C;
}
.purple{
border:2px solid #9B59B6;
}
.purple thead{
background:#9B59B6;
}
thead{
color:white;
}
th,td{
text-align:center;
padding:5px 0;
}
tbody tr:nth-child(even){
background:#ECF0F1;
}
tbody tr:hover{
background:#BDC3C7;
color:#FFFFFF;
}
.fixed{
top:0;
position:fixed;
width:auto;
display:none;
border:none;
}
.scrollMore{
margin-top:600px;
}
.up{
cursor:pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>↓ SCROLL ↓</h1>
<table class="blue">
<thead>
<tr>
<th>Colonne 1</th>
<th>Colonne 2</th>
<th>Colonne 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Non</td>
<td>MaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMaisMais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
</tbody>
</table>
<h1 class="scrollMore">↓ SCROLL MORE ↓</h1>
<table class="purple">
<thead>
<tr>
<th>Colonne 1</th>
<th>Colonne 2</th>
<th>Colonne 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
<tr>
<td>Non</td>
<td>Mais</td>
<td>Allo !</td>
</tr>
</tbody>
</table>
<h1 class="up scrollMore">↑ UP ↑</h1>
Ответ 7
Лучшим решением является использование этого плагина jquery:
https://github.com/jmosbech/StickyTableHeaders
Этот плагин отлично поработал для нас, и мы пробовали много других решений. Мы протестировали его в IE, Chrome и Firefox.
Ответ 8
Я нашел простую библиотеку jQuery под названием Sticky Table Headers. Две строки кода, и он сделал именно то, что я хотел. Вышеупомянутые решения не управляют шириной столбцов, поэтому, если у вас есть ячейки таблицы, занимающие много места, результирующий размер постоянного заголовка не будет соответствовать вашей ширине таблицы.
http://plugins.jquery.com/StickyTableHeaders/
Информация об использовании здесь:
https://github.com/jmosbech/StickyTableHeaders
Ответ 9
Здесь уже есть много действительно хороших решений. Но одно из самых простых CSS-решений, которые я использую в этих ситуациях, заключается в следующем:
table {
/* Not required only for visualizing */
border-collapse: collapse;
width: 100%;
}
table thead tr th {
/* Important */
background-color: red;
position: sticky;
z-index: 100;
top: 0;
}
td {
/* Not required only for visualizing */
padding: 1em;
}
<table>
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
</tr>
</thead>
<tbody>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
</tbody>
</table>
Ответ 10
Хорошо, просмотрев все доступные решения, я написал плагин, который может заморозить любую строку (не только th) в верхней части страницы или контейнера. Это очень просто и очень быстро. Не стесняйтесь использовать его.
http://maslianok.github.io/stickyRows/
Ответ 11
У меня тоже были те же проблемы с форматированием рамки, которые не отображаются с использованием кода энтрофии, но несколько небольших исправлений, и теперь таблица расширяема и отображает все правила стилизации CSS, которые вы можете добавить.
в css добавить:
#maintable{width: 100%}
то вот новый javascript:
function moveScroll(){
var scroll = $(window).scrollTop();
var anchor_top = $("#maintable").offset().top;
var anchor_bottom = $("#bottom_anchor").offset().top;
if (scroll > anchor_top && scroll < anchor_bottom) {
clone_table = $("#clone");
if(clone_table.length === 0) {
clone_table = $("#maintable").clone();
clone_table.attr({id: "clone"})
.css({
position: "fixed",
"pointer-events": "none",
top:0
})
.width($("#maintable").width());
$("#table-container").append(clone_table);
// dont hide the whole table or you lose border style &
// actively match the inline width to the #maintable width if the
// container holding the table (window, iframe, div) changes width
$("#clone").width($("#maintable").width());
// only the clone thead remains visible
$("#clone thead").css({
visibility:"visible"
});
// clone tbody is hidden
$("#clone tbody").css({
visibility:"hidden"
});
// add support for a tfoot element
// and hide its cloned version too
var footEl = $("#clone tfoot");
if(footEl.length){
footEl.css({
visibility:"hidden"
});
}
}
}
else {
$("#clone").remove();
}
}
$(window).scroll(moveScroll);
Ответ 12
Вот решение, основанное на принятом ответе. Он исправляет: ширину столбцов, стиль таблицы соответствия и когда прокручивается таблица в контейнере div.
Использование
Убедитесь, что в вашей таблице есть тег <thead>
, потому что будет исправлено только содержимое thead.
$("#header-fixed").fixHeader();
Javasript
//Custom JQuery Plugin
(function ($) {
$.fn.fixHeader = function () {
return this.each(function () {
var $table = $(this);
var $sp = $table.scrollParent();
var tableOffset = $table.position().top;
var $tableFixed = $("<table />")
.prop('class', $table.prop('class'))
.css({ position: "fixed", "table-layout": "fixed", display: "none", "margin-top": "0px" });
$table.before($tableFixed);
$tableFixed.append($table.find("thead").clone());
$sp.bind("scroll", function () {
var offset = $(this).scrollTop();
if (offset > tableOffset && $tableFixed.is(":hidden")) {
$tableFixed.show();
var p = $table.position();
var offset = $sp.offset();
//Set the left and width to match the source table and the top to match the scroll parent
$tableFixed.css({ left: p.left + "px", top: (offset ? offset.top : 0) + "px", }).width($table.width());
//Set the width of each column to match the source table
$.each($table.find('th, td'), function (i, th) {
$($tableFixed.find('th, td')[i]).width($(th).width());
});
}
else if (offset <= tableOffset && !$tableFixed.is(":hidden")) {
$tableFixed.hide();
}
});
});
};
})(jQuery);
Ответ 13
Это поможет вам иметь фиксированный заголовок, который также можно прокручивать по горизонтали с данными.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Shubh</title>
<script type="text/javascript">
var lastSeen = [ 0, 0 ];
function checkScroll(div1, div2) {
if (!div1 || !div2)
return;
var control = null;
if (div1.scrollLeft != lastSeen[0])
control = div1;
else if (div2.scrollLeft != lastSeen[1])
control = div2;
if (control == null)
return;
else
div1.scrollLeft = div2.scrollLeft = control.scrollLeft;
lastSeen[0] = div1.scrollLeft;
lastSeen[1] = div2.scrollLeft;
}
window
.setInterval(
"checkScroll(document.getElementById('innertablediv'), document.getElementById('headertable'))",
1);
</script>
<style type="text/css">
#full {
width: 400px;
height: 300px;
}
#innertablediv {
height: 200px;
overflow: auto;
}
#headertable {
overflow: hidden;
}
</style>
</head>
<body>
<div id="full">
<div id="headertable">
<table border="1" bgcolor="grey" width="150px" id="headertable">
<tr>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td> </td>
</tr>
</table>
</div>
<div id="innertablediv">
<table border="1" id="innertableid">
<tr>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
</tr>
<tr>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
</tr>
<tr>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
</tr>
<tr>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
</tr>
<tr>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
</tr>
<tr>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
</tr>
<tr>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
</tr>
<tr>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
</tr>
<tr>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
<td>shubh, ansh</td>
</tr>
</table>
</div>
</div>
</body>
</html>
Ответ 14
function fix_table_header_position(){
var width_list = [];
$("th").each(function(){
width_list.push($(this).width());
});
$("tr:first").css("position", "absolute");
$("tr:first").css("z-index", "1000");
$("th, td").each(function(index){
$(this).width(width_list[index]);
});
$("tr:first").after("<tr height=" + $("tr:first").height() + "></tr>");}
Это мое решение
Ответ 15
В этом решении фиксированный заголовок создается динамически,
контент и стиль клонируются от THEAD
все, что вам нужно, это две строки, например:
var $myfixedHeader = $("#Ttodo").FixedHeader(); //create fixed header
$(window).scroll($myfixedHeader.moveScroll); //bind function to scroll event
Мой плагин jquery FixedHeader и
getStyleObject, представленный ниже, вы можете поместить в файл .js
// JAVASCRIPT
/*
* getStyleObject Plugin for jQuery JavaScript Library
* From: http://upshots.org/?p=112
Basic usage:
$.fn.copyCSS = function(source){
var styles = $(source).getStyleObject();
this.css(styles);
}
*/
(function($){
$.fn.getStyleObject = function(){
var dom = this.get(0);
var style;
var returns = {};
if(window.getComputedStyle){
var camelize = function(a,b){
return b.toUpperCase();
};
style = window.getComputedStyle(dom, null);
for(var i = 0, l = style.length; i < l; i++){
var prop = style[i];
var camel = prop.replace(/\-([a-z])/g, camelize);
var val = style.getPropertyValue(prop);
returns[camel] = val;
};
return returns;
};
if(style = dom.currentStyle){
for(var prop in style){
returns[prop] = style[prop];
};
return returns;
};
return this.css();
}
})(jQuery);
//Floating Header of long table PiotrC
(function ( $ ) {
var tableTop,tableBottom,ClnH;
$.fn.FixedHeader = function(){
tableTop=this.offset().top,
tableBottom=this.outerHeight()+tableTop;
//Add Fixed header
this.after('<table id="fixH"></table>');
//Clone Header
ClnH=$("#fixH").html(this.find("thead").clone());
//set style
ClnH.css({'position':'fixed', 'top':'0', 'zIndex':'60', 'display':'none',
'border-collapse': this.css('border-collapse'),
'border-spacing': this.css('border-spacing'),
'margin-left': this.css('margin-left'),
'width': this.css('width')
});
//rewrite style cell of header
$.each(this.find("thead>tr>th"), function(ind,val){
$(ClnH.find('tr>th')[ind]).css($(val).getStyleObject());
});
return ClnH;}
$.fn.moveScroll=function(){
var offset = $(window).scrollTop();
if (offset > tableTop && offset<tableBottom){
if(ClnH.is(":hidden"))ClnH.show();
$("#fixH").css('margin-left',"-"+$(window).scrollLeft()+"px");
}
else if (offset < tableTop || offset>tableBottom){
if(!ClnH.is(':hidden'))ClnH.hide();
}
};
})( jQuery );
var $myfixedHeader = $("#repTb").FixedHeader();
$(window).scroll($myfixedHeader.moveScroll);
/* CSS - important only NOT transparent background */
#repTB{border-collapse: separate;border-spacing: 0;}
#repTb thead,#fixH thead{background: #e0e0e0 linear-gradient(#d8d8d8 0%, #e0e0e0 25%, #e0e0e0 75%, #d8d8d8 100%) repeat scroll 0 0;border:1px solid #CCCCCC;}
#repTb td{border:1px solid black}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h3>example</h3>
<table id="repTb">
<thead>
<tr><th>Col1</th><th>Column2</th><th>Description</th></tr>
</thead>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
<tr><td>info</td><td>info</td><td>info</td></tr>
</table>
Ответ 16
Немного поздно для вечеринки, но вот реализация, которая работает с несколькими таблицами на одной странице и "jank" бесплатно (с использованием requestAnimationFrame). Также нет необходимости предоставлять ширину столбцов. Горизонтальная прокрутка также работает.
Заголовки определены в div
, поэтому вы можете добавлять любую разметку там (например, кнопки), если это необходимо. Это весь HTML-код, который необходим:
<div class="tbl-resp">
<table id="tbl1" class="tbl-resp__tbl">
<thead>
<tr>
<th>col 1</th>
<th>col 2</th>
<th>col 3</th>
</tr>
</thead>
</table>
</div>
https://jsfiddle.net/lloydleo/bk5pt5gs/
Ответ 17
Создайте дополнительную таблицу с тем же заголовком, что и основная таблица. Просто поместите thead в новый стол с одной строкой и всеми заголовками в ней. Сделайте положение абсолютным и фоновым белым. Для основной таблицы поместите его в div и используйте прокрутку высоты и переполнения. Таким образом, наша новая таблица преодолеет заголовок главной таблицы и останется там. Окуните все в div. Ниже приведен пример кода.
<div class="col-sm-8">
<table id="header-fixed" class="table table-bordered table-hover" style="width: 351px;position: absolute;background: white;">
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
</tr>
</thead>
</table>
<div style="height: 300px;overflow-y: scroll;">
<table id="tableMain" class="table table-bordered table-hover" style="table-layout:fixed;overflow-wrap: break-word;cursor:pointer">
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
</tr>
</thead>
<tbody>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
</tbody>
</table>
</div>
</div>
Ответ 18
Вы можете использовать этот подход, чистый HTML и CSS не нужны JS :)
.table-fixed-header {
display: flex;
justify-content: space-between;
margin-right: 18px
}
.table-fixed {
display: flex;
justify-content: space-between;
height: 150px;
overflow: scroll;
}
.column {
flex-basis: 24%;
border-radius: 5px;
padding: 5px;
text-align: center;
}
.column .title {
border-bottom: 2px grey solid;
border-top: 2px grey solid;
text-align: center;
display: block;
font-weight: bold;
}
.cell {
padding: 5px;
border-right: 1px solid;
border-left: 1px solid;
}
.cell:nth-of-type(even) {
background-color: lightgrey;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Fixed header Bin</title>
</head>
<body>
<div class="table-fixed-header">
<div class="column">
<span class="title">col 1</span>
</div>
<div class="column">
<span class="title">col 2</span>
</div>
<div class="column">
<span class="title">col 3</span>
</div>
<div class="column">
<span class="title">col 4</span>
</div>
</div>
<div class="table-fixed">
<div class="column">
<div class="cell">alpha</div>
<div class="cell">beta</div>
<div class="cell">ceta</div>
</div>
<div class="column">
<div class="cell">alpha</div>
<div class="cell">beta</div>
<div class="cell">ceta</div>
<div class="cell">alpha</div>
<div class="cell">beta</div>
<div class="cell">ceta</div>
<div class="cell">alpha</div>
<div class="cell">beta</div>
<div class="cell">ceta</div>
</div>
<div class="column">
<div class="cell">alpha</div>
<div class="cell">beta</div>
<div class="cell">ceta</div>
<div class="cell">beta</div>
<div class="cell">beta</div>
<div class="cell">beta</div>
</div>
<div class="column">
<div class="cell">alpha</div>
<div class="cell">beta</div>
<div class="cell">ceta</div>
</div>
</div>
</body>
</html>
Ответ 19
div.wrapper {
padding:20px;
}
table.scroll thead {
width: 100%;
background: #FC6822;
}
table.scroll thead tr:after {
content: '';
overflow-y: scroll;
visibility: hidden;
}
table.scroll thead th {
flex: 1 auto;
display: block;
color: #fff;
}
table.scroll tbody {
display: block;
width: 100%;
overflow-y: auto;
height: auto;
max-height: 200px;
}
table.scroll thead tr,
table.scroll tbody tr {
display: flex;
}
table.scroll tbody tr td {
flex: 1 auto;
word-wrap: break;
}
table.scroll thead tr th,
table.scroll tbody tr td {
width: 25%;
padding: 5px;
text-align-left;
border-bottom: 1px solid rgba(0,0,0,0.3);
}
<div class="wrapper">
<table border="0" cellpadding="0" cellspacing="0" class="scroll">
<thead>
<tr>
<th>Name</th>
<th>Vorname</th>
<th>Beruf</th>
<th>Alter</th>
</tr>
</thead>
<tbody>
<tr>
<td>Müller</td>
<td>Marie</td>
<td>Künstlerin</td>
<td>26</td>
</tr>
<tr>
<td>Meier</td>
<td>Stefan</td>
<td>Chemiker</td>
<td>52</td>
</tr>
<tr>
<td>Schmidt</td>
<td>Sabrine</td>
<td>Studentin</td>
<td>38</td>
</tr>
<tr>
<td>Mustermann</td>
<td>Max</td>
<td>Lehrer</td>
<td>41</td>
</tr>
<tr>
<td>Müller</td>
<td>Marie</td>
<td>Künstlerin</td>
<td>26</td>
</tr>
<tr>
<td>Meier</td>
<td>Stefan</td>
<td>Chemiker</td>
<td>52</td>
</tr>
<tr>
<td>Schmidt</td>
<td>Sabrine</td>
<td>Studentin</td>
<td>38</td>
</tr>
<tr>
<td>Mustermann</td>
<td>Max</td>
<td>Lehrer</td>
<td>41</td>
</tr>
<tr>
<td>Müller</td>
<td>Marie</td>
<td>Künstlerin</td>
<td>26</td>
</tr>
<tr>
<td>Meier</td>
<td>Stefan</td>
<td>Chemiker</td>
<td>52</td>
</tr>
<tr>
<td>Schmidt</td>
<td>Sabrine</td>
<td>Studentin</td>
<td>38</td>
</tr>
<tr>
<td>Mustermann</td>
<td>Max</td>
<td>Lehrer</td>
<td>41</td>
</tr>
</tbody>
</table>
</div>
Ответ 20
Это может быть достигнуто с помощью преобразования свойства стиля.
Все, что вам нужно сделать, это обернуть таблицу в некоторый div с фиксированной высотой и переполнением, установленным в auto, например:
.tableWrapper {
overflow: auto;
height: calc( 100% - 10rem );
}
И тогда вы можете прикрепить к нему обработчик onscroll, здесь у вас есть метод, который находит каждую таблицу, заключенную в <div class="tableWrapper"></div>
:
fixTables () {
document.querySelectorAll('.tableWrapper').forEach((tableWrapper) => {
tableWrapper.addEventListener('scroll', () => {
var translate = 'translate(0,' + tableWrapper.scrollTop + 'px)'
tableWrapper.querySelector('thead').style.transform = translate
})
})
}
И вот рабочий пример этого в действии (я использовал бутстрап, чтобы сделать его более красивым): fiddle
Для тех, кто также хочет поддерживать IE и Edge, вот фрагмент:
fixTables () {
const tableWrappers = document.querySelectorAll('.tableWrapper')
for (let i = 0, len = tableWrappers.length; i < len; i++) {
tableWrappers[i].addEventListener('scroll', () => {
const translate = 'translate(0,' + tableWrappers[i].scrollTop + 'px)'
const headers = tableWrappers[i].querySelectorAll('thead th')
for (let i = 0, len = headers.length; i < len; i++) {
headers[i].style.transform = translate
}
})
}
}
В прокрутке IE и Edge немного лагги... но он работает
Вот ответ, который помогает мне это выяснить: answer
Ответ 21
Я испробовал большинство из этих решений и в итоге нашел (IMO) лучшее современное решение:
CSS сетки
С помощью CSS-сеток вы можете определить "сетку" и, наконец, создать красивое кросс-браузерное решение без использования JavaScript для таблицы с фиксированным заголовком и прокручиваемого содержимого. Высота заголовка может быть даже динамической.
CSS: отображение в виде сетки и установка количества template-rows
:
.grid {
display: grid;
grid-template-rows: 50px auto; // For fixed height header
grid-template-rows: auto auto; // For dynamic height header
}
HTML: создайте контейнер сетки и количество определенных rows
:
<div class="grid">
<div></div>
<div></div>
</div>
Вот рабочий пример:
CSS
body {
margin: 0px;
padding: 0px;
text-align: center;
}
.table {
width: 100%;
height: 100%;
display: grid;
grid-template-rows: 50px auto;
}
.table-heading {
background-color: #ddd;
}
.table-content {
overflow-x: hidden;
overflow-y: scroll;
}
HTML
<html>
<head>
</head>
<body>
<div class="table">
<div class="table-heading">
HEADING
</div>
<div class="table-content">
CONTENT - CONTENT - CONTENT <br/>
CONTENT - CONTENT - CONTENT <br/>
CONTENT - CONTENT - CONTENT <br/>
CONTENT - CONTENT - CONTENT <br/>
CONTENT - CONTENT - CONTENT <br/>
CONTENT - CONTENT - CONTENT <br/>
</div>
</div>
</body>
</html>
Ответ 22
Я пробовал это с помощью преобразования: перевод. Хотя он хорошо работает в Firefox и Chrome, в IE11 просто нет функции. Нет двойных полос прокрутки. Поддерживает таблицу tfoot и заголовок. Чистый Javascript, нет JQuery.
http://jsfiddle.net/wbLqzrfb/42/
thead.style.transform="translate(0,"+(dY-top-1)+"px)";
Ответ 23
Исправьте эту проблему с этим
tbody {
display: table-caption;
height: 200px;
caption-side: bottom;
overflow: auto;
}
Ответ 24
Я нашел решение без jquery
HTML
<table class="fixed_header">
<thead>
<tr>
<th>Col 1</th>
<th>Col 2</th>
<th>Col 3</th>
<th>Col 4</th>
<th>Col 5</th>
</tr>
</thead>
<tbody>
<tr>
<td>row 1-0</td>
<td>row 1-1</td>
<td>row 1-2</td>
<td>row 1-3</td>
<td>row 1-4</td>
</tr>
<tr>
<td>row 2-0</td>
<td>row 2-1</td>
<td>row 2-2</td>
<td>row 2-3</td>
<td>row 2-4</td>
</tr>
<tr>
<td>row 3-0</td>
<td>row 3-1</td>
<td>row 3-2</td>
<td>row 3-3</td>
<td>row 3-4</td>
</tr>
<tr>
<td>row 4-0</td>
<td>row 4-1</td>
<td>row 4-2</td>
<td>row 4-3</td>
<td>row 4-4</td>
</tr>
<tr>
<td>row 5-0</td>
<td>row 5-1</td>
<td>row 5-2</td>
<td>row 5-3</td>
<td>row 5-4</td>
</tr>
<tr>
<td>row 6-0</td>
<td>row 6-1</td>
<td>row 6-2</td>
<td>row 6-3</td>
<td>row 6-4</td>
</tr>
<tr>
<td>row 7-0</td>
<td>row 7-1</td>
<td>row 7-2</td>
<td>row 7-3</td>
<td>row 7-4</td>
</tr>
</tbody>
</table>
CSS
.fixed_header{
width: 400px;
table-layout: fixed;
border-collapse: collapse;
}
.fixed_header tbody{
display:block;
width: 100%;
overflow: auto;
height: 100px;
}
.fixed_header thead tr {
display: block;
}
.fixed_header thead {
background: black;
color:#fff;
}
.fixed_header th, .fixed_header td {
padding: 5px;
text-align: left;
width: 200px;
}
Вы можете увидеть это работает здесь: https://jsfiddle.net/lexsoul/fqbsty3h
Источник: https://medium.com/@vembarrajan/html-css-tricks-scroll-able-table-body-tbody-d23182ae0fbc
Ответ 25
Начиная с 2019 года, лучший ответ, который я нашел, был @shahriyar-ahmed с использованием position:sticky
CSS position:sticky
:
fooobar.com/questions/311314/...
Он использовал этот CSS:
/*This will work on every browser but Chrome Browser*/
.table-fixed thead {
position: sticky;
position: -webkit-sticky;
top: 0;
z-index: 999;
background-color: #000;
color: #fff;
}
/*This will work on every browser*/
.table-fixed thead th {
position: sticky;
position: -webkit-sticky;
top: 0;
z-index: 999;
background-color: #000;
color: #fff;
}
<table class="table-fixed">
<thead>
<tr>
<th>Table Header 1</th>
<th>Table Header 2</th>
<th>Table Header 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</tr>
</tbody>
</table>
Ответ 26
Вы устанавливаете липкую позицию в ячейке таблицы заголовка вместо строки таблицы.
.td.header {
position: sticky;
top:0px;
}
Проверьте этот jsfiddle для простого примера.