L'intestazione della tabella rimane fissa nella parte superiore quando l'utente la scorre fuori dalla vista con jQuery


146

Sto cercando di progettare una tabella HTML in cui l'intestazione rimarrà nella parte superiore della pagina quando E SOLO quando l'utente lo fa scorrere fuori dalla vista. Ad esempio, la tabella potrebbe essere 500 pixel più in basso rispetto alla pagina, come posso fare in modo che se l'utente fa scorrere l'intestazione fuori dalla vista (il browser rileva che non è più nella vista di Windows in qualche modo), rimarrà in alto ? Chiunque 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 sopra, voglio <thead>che scorra con la pagina se non è visibile.

IMPORTANTE: NON sto cercando una soluzione in cui <tbody>sia presente una barra di scorrimento (overflow: auto).




Ho risposto a questa domanda per un'altra domanda, per favore dai un'occhiata. stackoverflow.com/a/56764334/9388978
Ersel Aktas,

Risposte:


131

Faresti qualcosa del genere toccando il scrollgestore eventi windowe utilizzandone un altro tablecon una posizione fissa per mostrare l'intestazione nella parte superiore della 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 scorre abbastanza in basso da nascondere la testa della tabella originale. Si nasconderà di nuovo quando l'utente ha fatto scorrere di nuovo la pagina abbastanza in alto.

Esempio di lavoro: http://jsfiddle.net/andrewwhitaker/fj8wM/


60
Ci stavo pensando, ma cosa succede se la larghezza delle colonne di intestazione cambia in base al contenuto? A meno che le larghezze di colonna non siano fisse, è possibile che la riga di intestazione non sia allineata con le righe del contenuto. Solo un pensiero.
Yzmir Ramirez,

16
questo esempio non funziona se i nomi delle intestazioni di colonna sono più brevi dei valori dei dati di colonna. Prova a cambiare quel violino per avere valori come infoooooooo anziché info. Sto pensando a una sorta di larghezza codificata impostata durante la clonazione della tabella.
whiterook6,

6
Ciò ha importanti limiti, il meno dei quali è quando si tenta di utilizzare la tabella in un contenitore diverso da window. mkoryak.github.io/floatThead ha una soluzione più generalmente applicabile.
Yuck,

13
Questo potrebbe aiutare chiunque abbia bisogno di ampiezze dinamiche, è quello che ho fatto, è un fork di @AndrewWhitaker: jsfiddle.net/noahkoch/wLcjh/1
Noah Koch

1
L'intestazione fissa di @NoahKoch usando la tua soluzione può non essere larga quanto la testa originale quando le celle originali hanno un'imbottitura. Ho migliorato la tua soluzione per aggiungere imbottitura a celle duplicate. JSFiddle's fork: jsfiddle.net/1n23m69u/2
fandasson

47

CSS puro (senza supporto 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;
}

1
Non lo vedo nemmeno funzionare in Chrome. Gli strumenti di ispezione vengono visualizzati -webkit-stickycome valore non valido per position.
carmenismo,

@carmenism -webkit-stickyè per Safari (desktop e iOS), non per Chrome. position: stickyfunziona in Chrome dalla versione 56. Dovresti impostare ENTRAMBE le regole: -webkit-stickye stickyesattamente nello stesso ordine del mio esempio di codice. Safari diventa webkit-stickye tutti gli altri browser lo sovrascrivono sticky.
Ihor Zenich,

2
Non sono riuscito a farlo funzionare. Da un rapido google sembra position: stickyche non funzionerà con gli elementi della tabella.
rjh

3
applicando a ha funzionato per me: table thead tr th {...}
nurp

1
Devi applicarlo al th perché non funzionerà su thead né su tr
helado il

46

Bene, stavo cercando di ottenere lo stesso effetto senza ricorrere a colonne di dimensioni fisse o con un'altezza fissa per l'intero tavolo.

La soluzione che mi è venuta in mente è un hack. Consiste nel duplicare l'intera tabella, quindi nascondere tutto tranne l'intestazione e renderla fissa.

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); 

Vedi qui: http://jsfiddle.net/QHQGF/7/

Modifica: aggiornato il codice in modo che il thead possa ricevere eventi puntatore (quindi i pulsanti e i collegamenti nell'intestazione funzionano ancora). Questo risolve il problema segnalato da luhfluh e Joe M.

Nuovo jsfiddle qui: http://jsfiddle.net/cjKEx/


3
L'ho provato prima, il problema è che la dimensione degli elementi nell'intestazione dipende dal contenuto della tabella. Se hai una riga con contenuti di grandi dimensioni l'intera colonna, inclusa l'intestazione, aumenterà. Se cloni solo il thead perdi quelle informazioni e non ottieni l'effetto desiderato. Vedi il commento di Yzmir Ramirez sulla risposta accettata. Questo è l'unico modo che ho scoperto che funziona senza colonne a larghezza fissa. Non è pulito, lo so, che è il modo in cui ho detto che era un trucco.
entropia

1
Oh ho capito. Questo metodo è eccezionale perché funziona con colonne fluide, ho cercato su Google un po 'e non ne ho trovato un altro con quella funzionalità. Comunque, se lo farò in qualche modo, lo menzionerò qui
M2_

1
@luhfluh, sì, il problema era dovuto agli eventi puntatore: nessuno nella tabella clonata. Questo viene utilizzato in modo che i clic passino attraverso il clone e alla tabella originale. Ripristinandolo nell'intestazione della tabella clonata in modo che l'intestazione (e solo l'intestazione) sia cliccabile, risolve il problema. Ho aggiornato il mio post per riflettere questo :)
entropia

4
problema durante l'aggiunta del bordo su <thead> <th>
Jam Ville

1
@JamVille Perché la tabella clonata ha visibility: hidden. Puoi nascondere solo #clone tbodye dopo puoi impostare il bordo ... Fiddle di lavoro: jsfiddle.net/QHQGF/1707
Lajdák Marek

26

Ho scritto un plugin che fa questo. Ci sto lavorando da circa un anno e penso che gestisca abbastanza bene tutti i casi d'angolo:

  • scorrimento all'interno di un contenitore con troppo pieno
  • scorrendo all'interno di una finestra
  • prendersi cura di ciò che accade quando si ridimensiona la finestra
  • mantenendo i tuoi eventi legati all'intestazione
  • soprattutto, non ti obbliga a cambiare il CSS del tuo tavolo per farlo funzionare

Ecco alcuni demo / documenti:
http://mkoryak.github.io/floatThead/


grande sforzo, ma non funziona con IE 10 e presenta alcune stranezze sul ridimensionamento di Windows su Firefox / Ubuntu.
Janning,

2
Cordiali saluti: ho risolto i problemi con IE9 e 10 nell'ultima versione.
mkoryak,

2
Puoi creare una versione che non richiede jQuery?
Curtis W,

2
probabilmente perché non usa jquery ... e no - non farò una versione che non usa jquery.
mkoryak,

1
Uso un semplice plugin jQery tablesorter e in base alle tue FAQ il tuo plugin non piace la maggior parte delle regole CSS come #sortable td {..} e così. Ho provato a modificare un po 'ma non sono riuscito a farlo funzionare.
Masche,

25

Sono stato in grado di risolvere il problema con la modifica della larghezza delle colonne. Ho iniziato con la soluzione di Andrew sopra (grazie mille!) E poi ho aggiunto un piccolo loop 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'intero tavolo e nascondere il corpo. Sono nuovo di zecca per JavaScript e jQuery (e per lo stack overflow), quindi ogni commento è apprezzato.


4
Funzionava bene ma dovevo aggiungere la seguente riga $ ("# header-fixed"). Width ($ ("# table-1"). Width ()); affinché le colonne si allineino correttamente.
Ilya Fedotov,

17

Questa è di gran lunga la migliore soluzione che ho trovato per avere un'intestazione di tabella fissa.

AGGIORNAMENTO 5/11: corretto bug di scorrimento orizzontale come indicato da Kerry Johnson

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>&darr; SCROLL &darr;</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">&darr; SCROLL MORE &darr;</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">&uarr; UP &uarr;</h1>


Ho corretto questo script in modo che potesse gestire <th> elementi con bordo e riempimento (altrimenti imposta le larghezze fisse dell'intestazione <th> su larghezze troppo larghe). Passare semplicemente outerWidtha widthnella definizione della funzione resizeFixed ().
alanng,

Potrebbe anche essere necessario aggiungere una proprietà CSS di z-indexun numero positivo sulla .fixedclasse in modo che gli oggetti resi post-pageload nella tabella non galleggino sopra l'intestazione fissa durante lo scorrimento.
alanng,

Semplice e utile.
RitchieD,

come gestire dinamicamente la posizione più alta. Diciamo, ho bisogno di scorrere fino al mio contenuto di intestazione fissa della mia pagina principale. .fixed {top: 0;} .
VijayVishnu,

2
@KerryJohnson Grazie per la nota. Ho apportato alcune modifiche in modo che supporti lo scorrimento orizzontale e la larghezza dinamica delle colonne.
Giuseppe,

7

La soluzione migliore è utilizzare questo plugin jquery:

https://github.com/jmosbech/StickyTableHeaders

Questo plugin ha funzionato benissimo per noi e abbiamo provato molte altre soluzioni. Lo abbiamo testato su IE, Chrome e Firefox


Conosci qualche soluzione che preservi anche la funzionalità dei controlli associati ai dati knockout nell'intestazione?
Csaba Toth,

Non ha funzionato per me: le intestazioni sono al di fuori del tavolo e si attaccano alla parte superiore del browser (finestra), anche con l'opzione "scrollableArea". Ho visto che questo è stato menzionato prima senza ulteriori commenti. Forse ha bisogno di un CSS che usa e non è disponibile per farlo funzionare.
Exel Gamboa,

6

Ci sono già molte soluzioni davvero valide qui. Ma una delle soluzioni CSS più semplici che utilizzo in queste situazioni è la seguente:

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>

Poiché non è richiesto JavaScript, semplifica notevolmente la situazione. In sostanza, è necessario concentrarsi sulla seconda regola CSS, che contiene le condizioni per garantire che la testa della tabella rimanga in alto, indipendentemente dallo spazio di scorrimento.

Per approfondire ciascuna delle regole in dettaglio. positionha lo scopo di indicare al browser che l'oggetto head, la sua riga e le sue celle devono tutti aderire in alto. Questo deve necessariamente essere accompagnato datop , che specifica al browser che la testa si attaccherà nella parte superiore della pagina o della finestra. Inoltre, puoi aggiungere z-indexper assicurarti che il contenuto della testa rimanga sempre in primo piano.

Il colore di sfondo serve semplicemente a illustrare il punto. Non è necessario utilizzare alcun JavaScript aggiuntivo per ottenere questo effetto. Questo è supportato nella maggior parte dei principali browser dopo il 2016.


1
imo la risposta semplice e pulita, c'è sempre un modo semplice per risolvere un problema, questo è il caso. Anche se sto usando ng-repeat con angularjs funziona come un incantesimo.
David Castro,

5

Ho trovato una semplice libreria jQuery chiamata Sticky Table Headers. Due righe di codice e ha fatto esattamente quello che volevo. Le soluzioni sopra non gestiscono le larghezze di colonna, quindi se hai celle di tabella che occupano molto spazio, la dimensione risultante dell'intestazione persistente non corrisponderà alla larghezza della tua tabella.

http://plugins.jquery.com/StickyTableHeaders/

Informazioni di utilizzo qui: https://github.com/jmosbech/StickyTableHeaders


3

Bene, dopo aver esaminato tutte le soluzioni disponibili ho scritto plugin che possono congelare qualsiasi riga (non solo th) nella parte superiore della pagina o del contenitore. È molto semplice e molto veloce. Sentiti libero di usarlo. http://maslianok.github.io/stickyRows/


3

puoi usare questo approccio, puro HTML e CSS senza bisogno di 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>


3

Ho trovato una soluzione semplice senza usare JQuery e usare solo CSS .

Devi inserire i contenuti fissi all'interno dei tag 'th' e aggiungere il CSS

table th {
    position:sticky;
    top:0;
    z-index:1;
    border-top:0;
    background: #ededed;
}
   

La posizione, l'indice z e le proprietà migliori sono sufficienti. Ma puoi applicare il resto per dare una visione migliore.


2

Anch'io ho riscontrato gli stessi problemi con la formattazione del bordo non mostrata usando il codice di entrophy ma alcune piccole correzioni e ora la tabella è espandibile e visualizza tutte le regole di stile CSS che è possibile aggiungere.

a css aggiungi:

#maintable{width: 100%}    

allora ecco il nuovo 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);

Funziona meglio della soluzione entropica per quanto riguarda la formattazione del bordo nell'intestazione. Tuttavia, nell'attuale Firefox (ma non in Chrome) crea artefatti visibili sul bordo della cella sotto la tabella una volta iniziato lo scorrimento.
alanng,

2

Ecco una soluzione che si basa sulla risposta accettata. Corregge per: larghezza di colonna, stile della tabella corrispondente e quando la tabella viene fatta scorrere in un div contenitore.

uso

Assicurati che la tua tabella abbia un <thead>tag perché sarà riparato solo il contenuto del 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);

1
Questo ha funzionato bene per me. L'unica cosa è un problema con le tabelle che devono scorrere in senso orizzontale. Ho fatto un aggiornamento in una JSFiddle qui jsfiddle.net/4mgneob1/1 Sottrai $sp.scrollLeft()che sottrae la quantità che scorre da sinistra, quindi quando si scorre verso il basso la tabella fissa viene posizionata correttamente. Aggiunto anche controllo quando si scorre in orizzontale se è visibile una tabella fissa per regolare la posizione a sinistra. Un altro problema che non sono riuscito a risolvere è quando la tabella supera la finestra che la tabella fissa dovrebbe nascondere fino a quando l'utente non torna indietro.
Henesnarfel,

1
Come arrivareUncaught TypeError: $table.scrollParent is not a function
karlingen,

1

Questo ti aiuterà ad avere un'intestazione fissa che può anche essere fatta scorrere orizzontalmente con i dati.

<!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>&nbsp;&nbsp;&nbsp;</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>

Questo ti aiuterà ad avere un'intestazione fissa che può anche essere fatta scorrere orizzontalmente con i dati.
user2669926

1
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>");}

Questa è la mia soluzione


1

Un po 'in ritardo per la festa, ma ecco un'implementazione che funziona con più tabelle nella stessa pagina e "jank" gratis (usando requestAnimationFrame). Inoltre non è necessario fornire alcuna larghezza sulle colonne. Anche lo scorrimento orizzontale funziona.

Le intestazioni sono definite in divmodo che tu sia libero di aggiungere qualsiasi markup (come i pulsanti), se necessario. Questo è tutto l'HTML necessario:

<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/


1

In questa soluzione l'intestazione fissa viene creata dinamicamente, il contenuto e lo stile vengono clonati da THEAD

tutto ciò di cui hai bisogno sono due righe per esempio:

var $myfixedHeader = $("#Ttodo").FixedHeader(); //create fixed header $(window).scroll($myfixedHeader.moveScroll); //bind function to scroll event

Il mio plugin jquery FixedHeader e getStyleObject fornito di seguito è possibile inserire nel file .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>


1

Crea una tabella aggiuntiva con la stessa intestazione della tabella principale. Inserisci il thead nel nuovo tavolo con una riga e tutte le intestazioni. Posiziona assoluto e sfondo bianco. Per la tabella principale mettilo in un div e usa un po 'di altezza e scorrimento overflow-y. In questo modo il nostro nuovo tavolo supererà l'intestazione del tavolo principale e rimarrà lì. Circonda tutto in un div. Di seguito è riportato il codice approssimativo per farlo.

      <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>

1

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>

Demo: demo di intestazione tabella fissa css


1

Risolvi il tuo problema con questo

tbody {
  display: table-caption;
  height: 200px;
  caption-side: bottom;
  overflow: auto;
}

0

Ciò può essere ottenuto utilizzando la trasformazione della proprietà dello stile. Tutto quello che devi fare è avvolgere il tuo tavolo in alcuni div con altezza fissa e overflow impostati su auto, ad esempio:

.tableWrapper {
  overflow: auto;
  height: calc( 100% - 10rem );
}

E quindi puoi collegare il gestore onscroll ad esso, qui hai un metodo che trova ogni tabella avvolta con <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
      })
    })
  }

Ed ecco un esempio funzionante di questo in azione (ho usato bootstrap per renderlo più grazioso): violino

Per coloro che vogliono supportare anche IE e Edge, ecco lo snippet:

  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
        }
      })
    }
  }

In IE e Edge scroll è un po 'lento ... ma funziona

Ecco la risposta che mi aiuta a scoprire questo: risposta


0

Ho provato la maggior parte di queste soluzioni e alla fine ho trovato (IMO) la soluzione migliore, moderna:

Griglie CSS


Con le griglie CSS, puoi definire una 'griglia' e finalmente puoi creare una bella soluzione cross-browser, priva di javascript, per una tabella con un'intestazione fissa e contenuti scorrevoli. L'altezza dell'intestazione può anche essere dinamica.

CSS : visualizza come griglia e imposta il numero di template-rows:

.grid {
    display: grid;
    grid-template-rows: 50px auto; // For fixed height header
    grid-template-rows: auto auto; // For dynamic height header
}

HTML : crea un contenitore griglia e il numero di definito rows:

<div class="grid">
    <div></div>
    <div></div>
</div>

Ecco un esempio funzionante:

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>

0

L'ho provato usando la trasformazione: tradurre . Mentre funziona bene in Firefox e Chrome, in IE11 non esiste semplicemente alcuna funzione. Nessuna doppia barra di scorrimento. Supporta il foot table e la didascalia Javascript puro, no jQuery.

http://jsfiddle.net/wbLqzrfb/42/

thead.style.transform="translate(0,"+(dY-top-1)+"px)";

0

Ho trovato una soluzione senza 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;
}

Puoi vederlo funzionare qui: https://jsfiddle.net/lexsoul/fqbsty3h

Fonte: https://medium.com/@vembarrajan/html-css-tricks-scroll-able-table-body-tbody-d23182ae0fbc

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.