Sto cercando di progettare una tabella HTML in cui l'intestazione rimanga in cima alla pagina quando E SOLO quando l'utente la fa scorrere fuori dalla vista. Per esempio, la tabella può essere 500 pixel più in basso nella pagina, come faccio a fare in modo che se l'utente scorre l'intestazione fuori dalla vista (il browser rileva che non è più nella vista delle finestre in qualche modo), rimarrà in cima? Qualcuno può darmi una soluzione Javascript per questo?
<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>
Quindi, nell'esempio di cui sopra, voglio che il <thead>
scorra con la pagina se va fuori dalla vista.
IMPORTANTE: non sto NON cercando una soluzione in cui il <tbody>
avrà una barra di scorrimento (overflow:auto).
Potresti fare qualcosa del genere attingendo al gestore dell'evento scroll
su window
, e usando un'altra table
con una posizione fissa per mostrare l'intestazione in cima alla pagina.
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();
}
});
Questo mostrerà la testa della tabella quando l'utente scorrerà abbastanza in basso da nascondere la testa della tabella originale. Si nasconderà di nuovo quando l'utente avrà fatto scorrere la pagina abbastanza in alto.
Esempio di lavoro:
Beh, stavo cercando di ottenere lo stesso effetto senza ricorrere a colonne di dimensioni fisse o avere un'altezza fissa per tutta la tabella.
La soluzione che ho trovato è un hack. Consiste nel duplicare l'intera tabella e poi nascondere tutto tranne l'intestazione, e fare in modo che questa abbia una posizione fissa.
<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>
body { height: 1000px; }
thead{
background-color:white;
}
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);
Vedi qui:
Modifica: aggiornato il codice in modo che il thead possa ricevere gli eventi del puntatore (quindi i pulsanti e i link nell'intestazione funzionano ancora). Questo risolve il problema riportato da luhfluh e Joe M.
Nuovo jsfiddle qui: http://jsfiddle.net/cjKEx/
Sono riuscito a risolvere il problema con la modifica della larghezza delle colonne. Ho iniziato con la soluzione di Andrew di cui sopra (grazie mille!) e poi ho aggiunto un piccolo ciclo per impostare le larghezze dei td clonati:
$("#header-fixed td").each(function(index){
var index2 = index;
$(this).width(function(index2){
return $("#table-1 td").eq(index).width();
});
});
Questo risolve il problema senza dover clonare l'intera tabella e nascondere il corpo. Sono nuovo di zecca per JavaScript e jQuery (e per stack overflow), quindi qualsiasi commento è apprezzato.