Grande tablette html à taille dynamique avec une ligne de défilement fixe et une colonne de défilement fixe

J'ai besoin d'afficher une grande table sur une page Web et je dois empêcher la première colonne et la première ligne de défiler. Je voudrais configurer dynamiquement la taille verticale de cette table (entre un contenu de page d'en-tête / pied de page de taille statique) pour la rendre aussi grande que possible sans forcer la fenêtre de navigateur à disposer d'une barre de défilement verticale.

browser window\/ +--------------------------------------------------------------+ /\ | /\ /\ /\ /\ /\ /\ /\ /\ | fixed static | web page header fields and text | | size | \/ \/ \/ \/ \/ \/ \/ \/ |__\/__ | +----<<<table-scrollbar>>>>>----------------+ | /\ |+--------------+--------+--------+--------+--------+-------+ | | || | |colspan | | | fixed | | | || fixed | fixed | fixed | fixed | fixed | more> | | | |+--------------+--+--+--+---+----+--+--+--+--------+-------++ | | || fixed | | | | | | | | | | || | | |+--------------+--+--+--+---+----+--+--+--+--------+-------+t | | || fixed | | | | | | | | | | |a | | |+--------------+--+--+--+---+----+--+--+--+--------+-------+b | | || fixed | | | | | | | | | | |l | | |+--------------+--+--+--+---+----+--+--+--+--------+-------+e | set || fixed | | | | | | | | | | || | dynamic || multi-line | | | | | | | | | | |s | size at |+--------------+--+--+--+---+----+--+--+--+--------+-------+c | runtime || fixed | | | | | | | | | | |r | | |+--------------+--+--+--+---+----+--+--+--+--------+-------+o | | || fixed | | | | | | | | | | |l | | |+--------------+--+--+--+---+----+--+--+--+--------+-------+l | | || fixed | | | | | | | | | | |b | | || | | | | | | | | | | |a |+--------------+--+--+--+---+----+--+--+--+--------+-------+r | | || fixed, moreV | | | | | | | | | | || | | |+--------------+--+--+--+---+----+--+--+--+--------+-------++ |__\/__ | /\ /\ /\ /\ /\ /\ /\ /\ | /\ | web page footer fields and text | fixed static | \/ \/ \/ \/ \/ \/ \/ \/ | | size +--------------------------------------------------------------+ \/ 

Cela ne nécessite que de travailler dans des navigateurs modernes, en utilisant tous / tous: html, css, javascript, jquery

ordre d'importance:

  • Table complexe avec de nombreux champs de formulaire, valeurs cachées, effondrement javascript des lignes, etc. que j'ajouterai plus tard
  • 1ère rang aura colspans
  • Les rangées auront une hauteur variable
  • 1ère ligne: fixée à partir du défilement vertical, mais peut défiler horizontalement
  • 1ère colonne: fixée à partir du défilement horizontal, mais peut faire défiler verticalement
  • Taille dynamiquement cette "table" pour remplir l'écran entre l'en-tête / pied de page statique html
  • L'emplacement des barres de défilement (tel que représenté dans mon superbe art ascii ci-dessus) n'est pas critique.

Voici un échantillon html très basique de l'écran, sans aucune des fonctionnalités scroll / sizing:

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"> <HTML> <HEAD> <TITLE>big scrolling table example</TITLE> </HEAD> <BODY> <form name="MyForm" method="POST" action=""> <!-- static size header junk--><!-- static size header junk--><!-- static size header junk--> <table border="1" width="100%" cellspacing="1" cellpadding="0" align="center"> <tr> <td width="35%" align="left">header junk left</td> <td >- HEADER JUNK MIDDLE -</td> <td width="35%" align="right">header junk right</td> </tr> </table> <br> <table border="0" width="95%" cellspacing="1" cellpadding="0" align="center"> <tr> <td width="60%" align="left">header junk left</td> <td width="40%" align="right">check it out! <input type="checkbox" onchange="alert('your javascript here');" value="Y" name="checkitout"></td> </tr> <!-- big table here!!--><!-- big table here!!--><!-- big table here!!--><!-- big table here!!--> <table border="1" width="95%" cellspacing="1" cellpadding="0" align="center"> <tr> <td>fixed can be long<br>or short</td> <td colspan="4">scroll A</td> <td colspan="2">scroll B</td> <td >scroll C</td> <td colspan="4">scroll D</td> <td colspan="2">scroll E</td> <td >scroll F</td> <td colspan="4">scroll G</td> <td colspan="2">scroll H</td> <td >scroll I</td> <td colspan="4">scroll J</td> <td colspan="2">scroll K</td> <td >scroll L</td> <td colspan="4">scroll M</td> <td colspan="2">scroll N</td> <td >scroll O</td> </tr> <tr> <td>fixed 2</td> <td>1 1 1 1 1 A</td><td>2 2 2 2 2 A</td><td>3 3 3 3 3 A</td><td>4 4 4 4 4 A</td> <td>1 B</td><td>2 B</td> <td >1 C</td> <td>1 D</td><td>2 D</td><td>3 D</td><td>4 D<br>more...</td> <td>1 E</td><td>2 E</td> <td >1 F</td> <td>1 1 1 G</td><td>2 2 G</td><td>3 G</td><td>4 4 4 4 G</td> <td>1 H</td><td>222 H</td> <td >1 I</td> <td>1 J</td><td>2 J</td><td>3 J</td><td>4 J</td> <td>1 K</td><td>2 2 K<br>more..<br>more..</td> <td >1 L</td> <td>1 M</td><td>22 M</td><td>333 M</td><td>4444 M</td> <td>1 N</td><td>2 N</td> <td >1 1 1 1 1 1 1 O</td> </tr> <tr> <td>fixed 3</td> <td>1 1 1 1 1 A</td><td>2 2 2 2 2 A</td><td>3 3 3 3 3 A</td><td>4 4 4 4 4 A</td> <td>1 B</td><td>2 B</td> <td >1 C</td> <td>1 D</td><td>2 D</td><td>3 D</td><td>4 D<br>more...</td> <td>1 E</td><td>2 E</td> <td >1 F</td> <td>1 1 1 G</td><td>2 2 G</td><td>3 G</td><td>4 4 4 4 G</td> <td>1 H</td><td>222 H</td> <td >1 I</td> <td>1 J</td><td>2 J</td><td>3 J</td><td>4 J</td> <td>1 K</td><td>2 2 K<br>more..<br>more..</td> <td >1 L</td> <td>1 M</td><td>22 M</td><td>333 M</td><td>4444 M</td> <td>1 N</td><td>2 N</td> <td >1 1 1 1 1 1 1 O</td> </tr> <tr> <td>fixed 4</td> <td>1 1 1 1 1 A</td><td>2 2 2 2 2 A</td><td>3 3 3 3 3 A</td><td>4 4 4 4 4 A</td> <td>1 B</td><td>2 B</td> <td >1 C</td> <td>1 D</td><td>2 D</td><td>3 D</td><td>4 D<br>more...<br>more...<br>more...<br>more...</td> <td>1 E</td><td>2 E</td> <td >1 F</td> <td>1 1 1 G</td><td>2 2 G</td><td>3 G</td><td>4 4 4 4 G</td> <td>1 H</td><td>222 H</td> <td >1 I</td> <td>1 J</td><td>2 J</td><td>3 J</td><td>4 J</td> <td>1 K</td><td>2 2 K<br>more..<br>more..</td> <td >1 L</td> <td>1 M</td><td>22 M</td><td>333 M</td><td>4444 M</td> <td>1 N</td><td>2 N</td> <td >1 1 1 1 1 1 1 O</td> </tr> <tr> <td>fixed 5</td> <td>1 1 1 1 1 A</td><td>2 2 2 2 2 A</td><td>3 3 3 3 3 A</td><td>4 4 4 4 4 A</td> <td>1 B</td><td>2 B</td> <td >1 C</td> <td>1 D</td><td>2 D</td><td>3 D</td><td>4 D<br>more...</td> <td>1 E</td><td>2 E</td> <td >1 F</td> <td>1 1 1 G</td><td>2 2 G</td><td>3 G</td><td>4 4 4 4 G</td> <td>1 H</td><td>222 H<br>H<br>H<br>H<br>H</td> <td >1 I</td> <td>1 J</td><td>2 J</td><td>3 J</td><td>4 J</td> <td>1 K</td><td>2 2 K<br>more..<br>more..</td> <td >1 L</td> <td>1 M</td><td>22 M</td><td>333 M</td><td>4444 M</td> <td>1 N</td><td>2 N</td> <td >1 1 1 1 1 1 1 O</td> </tr> <tr> <td>fixed 6<br>6<br>6<br>6</td> <td>1 1 1 1 1 A</td><td>2 2 2 2 2 A</td><td>3 3 3 3 3 A</td><td>4 4 4 4 4 A</td> <td>1 B</td><td>2 B</td> <td >1 C</td> <td>1 D</td><td>2 D</td><td>3 D</td><td>4 D<br>more...</td> <td>1 E</td><td>2 E</td> <td >1 F</td> <td>1 1 1 G</td><td>2 2 G</td><td>3 G</td><td>4 4 4 4 G</td> <td>1 H</td><td>222 H</td> <td >1 I</td> <td>1 J</td><td>2 J</td><td>3 J</td><td>4 J</td> <td>1 K</td><td>2 2 K<br>more..<br>more..</td> <td >1 L</td> <td>1 M</td><td>22 M</td><td>333 M</td><td>4444 M</td> <td>1 N</td><td>2 N</td> <td >1 1 1 1 1 1 1 O</td> </tr> </table> <!-- static size footer junk--><!-- static size footer junk--><!-- static size footer junk--><!-- static size footer junk--> <table border="1" width="100%" cellspacing="1" cellpadding="0" align="center"> <tr> <td width="35%" align="left">footer junk left</td> <td >- FOOTER JUNK MIDDLE -</td> <td width="35%" align="right">footer junk right</td> </tr> </form> </BODY> </HTML> 

Edition 5: – Ajout de lignes et de colonnes configurables configurables. – Résolution des problèmes de largeur et de hauteur des colonnes – Utilisation réduite des sélecteurs complexes

Usage:

  $('#cTable').cTable({ width: 1300, height: 500, fCols: 2, fRows: 2 }); 

DEMO: http://jsfiddle.net/rCuPf/7/embedded/result/ (mise à jour de démonstration)

Edit 4: Mis à jour pour colSpan sur la colonne 1. Démo: http://jsfiddle.net/skram/rKjk3/26/

Edit 3: Certains travaux de nettoyage et certains correctifs: http://jsfiddle.net/rKjk3/22 Testé dans IE9, FF et Chrome. (Je n'ai pas le dernier IE pour le tester maintenant)

Edit 2: Correction pour IE: http://jsfiddle.net/rKjk3/15/embedded/result/ (Voir plus haut)

Edit 1: Correction de la fenêtre de redimensionnement http://jsfiddle.net/rKjk3/11/ (Voir plus haut)

  • Ajouté window.resize le gestionnaire d'événements pour définir la largeur du droit du rightContainer afin que la largeur de la table réelle augmente à mesure que vous redimensionnez.
  • SBWrapper largeur fixe sur SBWrapper afin qu'elle puisse utiliser pleinement l'espace disponible dans le conteneur.

J'ai créé 2 démo pour vos besoins.

  1. Exemple pour montrer comment le html rendu apparaîtra avec une structure de balisage simple. Cela vous permettra de regarder la structure qui est en cours et sa fonction 🙂
    DEMO: http://jsfiddle.net/GmJ22/7/

  2. Démo réelle avec le balisage que vous avez posté. Le code est juste une version approximative et peut nécessiter un certain nettoyage. En ce moment, vous pouvez configurer la largeur et la hauteur de la table. Je le publie pour que vous puissiez regarder et me donner des commentaires.
    DEMO: http://jsfiddle.net/rKjk3/10/embedded/result/ (voir les versions fixes ci-dessous)

Code complet:

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <HTML> <HEAD> <TITLE>big scrolling table example</TITLE> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script> $(function() { $.fn.cTable = function(o) { this.wrap('<div class="cTContainer" />'); this.wrap('<div class="relativeContainer" />'); //Update below template as how you have it in orig table var origTableTmpl = '<table border="1" cellspacing="1" cellpadding="0" align="center" width="95%" ></table>'; //get row 1 and clone it for creating sub tables var row1 = this.find('tr').slice(0, o.fRows).clone(); var r1c1ColSpan = 0; for (var i = 0; i < o.fCols; i++ ) { r1c1ColSpan += this[0].rows[0].cells[i].colSpan; } //create table with just r1c1 which is fixed for both scrolls var tr1c1 = $(origTableTmpl); row1.each(function () { var tdct = 0; $(this).find('td').filter( function () { tdct += this.colSpan; return tdct > r1c1ColSpan; }).remove(); }); row1.appendTo(tr1c1); tr1c1.wrap('<div class="fixedTB" />'); tr1c1.parent().prependTo(this.closest('.relativeContainer')); //create a table with just c1 var c1= this.clone().prop({'id': ''}); c1.find('tr').slice(0, o.fRows).remove(); c1.find('tr').each(function (idx) { var c = 0; $(this).find('td').filter(function () { c += this.colSpan; return c > r1c1ColSpan; }).remove(); }); var prependRow = row1.first().clone(); prependRow.find('td').empty(); c1.prepend(prependRow).wrap('<div class="leftSBWrapper" />') c1.parent().wrap('<div class="leftContainer" />'); c1.closest('.leftContainer').insertAfter('.fixedTB'); //create table with just row 1 without col 1 var r1 = $(origTableTmpl); row1 = this.find('tr').slice(0, o.fRows).clone(); row1.each(function () { var tds = $(this).find('td'), tdct = 0; tds.filter (function () { tdct += this.colSpan; return tdct <= r1c1ColSpan; }).remove(); }); row1.appendTo(r1); r1.wrap('<div class="topSBWrapper" />') r1.parent().wrap('<div class="rightContainer" />') r1.closest('.rightContainer').appendTo('.relativeContainer'); $('.relativeContainer').css({'width': 'auto', 'height': o.height}); this.wrap('<div class="SBWrapper"> /') this.parent().appendTo('.rightContainer'); this.prop({'width': o.width}); var tw = 0; //set width and height of rendered tables for (var i = 0; i < o.fCols; i++) { tw += $(this[0].rows[0].cells[i]).outerWidth(true); } tr1c1.width(tw); c1.width(tw); $('.rightContainer').css('left', tr1c1.outerWidth(true)); for (var i = 0; i < o.fRows; i++) { var tr1c1Ht = $(c1[0].rows[i]).outerHeight(true); var thisHt = $(this[0].rows[i]).outerHeight(true); var finHt = (tr1c1Ht > thisHt)?tr1c1Ht:thisHt; $(tr1c1[0].rows[i]).height(finHt); $(r1[0].rows[i]).height(finHt); } $('.leftContainer').css({'top': tr1c1.outerHeight(true), 'width': tr1c1.outerWidth(true)}); var rtw = $('.relativeContainer').width() - tw; $('.rightContainer').css({'width' : rtw, 'height': o.height, 'max-width': o.width - tw}); var trs = this.find('tr'); trs.slice(1, o.fRows).remove(); trs.slice(0, 1).find('td').empty(); trs.each(function () { var c = 0; $(this).find('td').filter(function () { c += this.colSpan; return c <= r1c1ColSpan; }).remove(); }); r1.width(this.outerWidth(true)); for (var i = 1; i < c1[0].rows.length; i++) { var c1Ht = $(c1[0].rows[i]).outerHeight(true); var thisHt = $(this[0].rows[i]).outerHeight(true); var finHt = (c1Ht > thisHt)?c1Ht:thisHt; $(c1[0].rows[i]).height(finHt); $(this[0].rows[i]).height(finHt); } $('.SBWrapper').css({'height': $('.relativeContainer').height() - $('.topSBWrapper').height()}); $('.SBWrapper').scroll(function () { var rc = $(this).closest('.relativeContainer'); var lfW = rc.find('.leftSBWrapper'); var tpW = rc.find('.topSBWrapper'); lfW.css('top', ($(this).scrollTop()*-1)); tpW.css('left', ($(this).scrollLeft()*-1)); }); $(window).resize(function () { $('.rightContainer').width(function () { return $(this).closest('.relativeContainer').outerWidth() - $(this).siblings('.leftContainer').outerWidth(); }); }); } $('#cTable').cTable({ width: 1300, height: 500, fCols: 2, fRows: 2 }); }); </script> <style> .cTContainer { overflow: hidden; padding: 2px; } .cTContainer table { table-layout: fixed; } .relativeContainer { position: relative; overflow: hidden;} .fixedTB { position: absolute; z-index: 11; } .leftContainer { position: absolute; overflow: hidden; } .rightContainer { position: absolute; overflow: hidden; } .leftSBWrapper { position: relative; z-index: 10; } .topSBWrapper { position: relative; z-index: 10; width: 100%; } .SBWrapper { width: 100%; overflow: auto; } td { background-color: white; overflow: hidden; padding: 1px; } </style> </HEAD> <BODY> <form name="MyForm" method="POST" action=""> <table border="1" width="100%" cellspacing="1" cellpadding="0" align="center"> <tr> <td width="35%" align="left">header junk left</td> <td >- HEADER JUNK MIDDLE -</td> <td width="35%" align="right">header junk right</td> </tr> </table> <br /> <table border="0" width="95%" cellspacing="1" cellpadding="0" align="center"> <tr> <td width="60%" align="left">header junk left</td> <td width="40%" align="right">check it out! <input type="checkbox" onchange="alert('your javascript here');" value="Y" name="checkitout"></td> </tr> </table> <!-- big table here!!--><!-- big table here!!--><!-- big table here!!--><!-- big table here!!--> <table border="1" width="95%" cellspacing="1" cellpadding="0" align="center" id="cTable" > <tr> <td width="5%" colspan="3">fixed can be long<br>or short</td> <td width="9%" colspan="4">scroll A</td> <td width="7%" colspan="2">scroll B</td> <td width="3%">scroll C</td> <td width="9%" colspan="4">scroll D</td> <td width="7%" colspan="2">scroll E</td> <td width="3%">scroll F</td> <td width="9%" colspan="4">scroll G</td> <td width="7%" colspan="2">scroll H</td> <td width="3%">scroll I</td> <td width="9%" colspan="4">scroll J</td> <td width="7%" colspan="2">scroll K</td> <td width="3%">scroll L</td> <td width="9%" colspan="4">scroll M</td> <td width="7%" colspan="2">scroll N</td> <td width="3%">scroll O</td> </tr> <tr> <td width="5%" colspan="3">2nd fixed header</td> <td width="9%" colspan="4">scroll 2A</td> <td width="7%">scroll 2B-1</td> <td width="7%">scroll 2B-2 </td> <td width="3%">scroll 2C</td> <td width="9%" colspan="4">scroll 2D</td> <td width="7%" colspan="2">scroll 2E</td> <td width="3%">scroll 2F</td> <td width="9%" colspan="4">scroll 2G</td> <td width="7%" colspan="2">scroll 2H</td> <td width="3%">scroll 2I</td> <td width="9%" colspan="4">scroll 2J</td> <td width="7%" colspan="2">scroll 2K</td> <td width="3%">scroll 2L</td> <td width="9%" colspan="4">scroll 2M</td> <td width="7%" colspan="2">scroll 2N</td> <td width="3%">scroll 2O</td> </tr> <tr> <td>2</td> <td>2</td> <td>2</td> <td>1 1 1 1 1 A</td> <td>2 2 2 2 2 A</td> <td>3 3 3 3 3 A</td> <td>4 4 4 4 4 A</td> <td>1 B</td> <td>2 B</td> <td >1 C</td> <td>1 D</td> <td>2 D</td> <td>3 D</td> <td>4 D<br>more...</td> <td>1 E</td> <td>2 E</td> <td >1 F</td> <td>1 1 1 G</td> <td>2 2 G</td> <td>3 G</td> <td>4 4 4 4 G</td> <td>1 H</td> <td>222 H</td> <td >1 I</td> <td>1 J</td> <td>2 J</td> <td>3 J</td> <td>4 J</td> <td>1 K</td> <td>2 2 K<br>more..<br>more..</td> <td >1 L</td> <td>1 M</td> <td>22 M</td> <td>333 M</td> <td>4444 M</td> <td>1 N</td> <td>2 N</td> <td >1 1 1 1 1 1 1 O</td> </tr> <tr> <td colspan="2">fixed 3</td> <td>3</td> <td>1 1 1 1 1 A</td><td>2 2 2 2 2 A</td><td>3 3 3 3 3 A</td><td>4 4 4 4 4 A</td> <td>1 B</td><td>2 B</td> <td >1 C</td> <td>1 D</td><td>2 D</td><td>3 D</td><td>4 D<br>more...</td> <td>1 E</td><td>2 E</td> <td >1 F</td> <td>1 1 1 G</td><td>2 2 G</td><td>3 G</td><td>4 4 4 4 G</td> <td>1 H</td><td>222 H</td> <td >1 I</td> <td>1 J</td><td>2 J</td><td>3 J</td><td>4 J</td> <td>1 K</td><td>2 2 K<br>more..<br>more..</td> <td >1 L</td> <td>1 M</td><td>22 M</td><td>333 M</td><td>4444 M</td> <td>1 N</td><td>2 N</td> <td >1 1 1 1 1 1 1 O</td> </tr> <tr> <td colspan="3">fixed 4</td> <td>1 1 1 1 1 A</td><td>2 2 2 2 2 A</td><td>3 3 3 3 3 A</td><td>4 4 4 4 4 A</td> <td>1 B</td><td>2 B</td> <td >1 C</td> <td>1 D</td><td>2 D</td><td>3 D</td><td>4 D<br>more...<br>more...<br>more...<br>more...</td> <td>1 E</td><td>2 E</td> <td >1 F</td> <td>1 1 1 G</td><td>2 2 G</td><td>3 G</td><td>4 4 4 4 G</td> <td>1 H</td><td>222 H</td> <td >1 I</td> <td>1 J</td><td>2 J</td><td>3 J</td><td>4 J</td> <td>1 K</td><td>2 2 K<br>more..<br>more..</td> <td >1 L</td> <td>1 M</td><td>22 M</td><td>333 M</td><td>4444 M</td> <td>1 N</td><td>2 N</td> <td >1 1 1 1 1 1 1 O</td> </tr> <tr> <td colspan="3">fixed 5</td> <td>1 1 1 1 1 A</td><td>2 2 2 2 2 A</td><td>3 3 3 3 3 A</td><td>4 4 4 4 4 A</td> <td>1 B</td><td>2 B</td> <td >1 C</td> <td>1 D</td><td>2 D</td><td>3 D</td><td>4 D<br>more...</td> <td>1 E</td><td>2 E</td> <td >1 F</td> <td>1 1 1 G</td><td>2 2 G</td><td>3 G</td><td>4 4 4 4 G</td> <td>1 H</td><td>222 H<br>H<br>H<br>H<br>H</td> <td >1 I</td> <td>1 J</td><td>2 J</td><td>3 J</td><td>4 J</td> <td>1 K</td><td>2 2 K<br>more..<br>more..</td> <td >1 L</td> <td>1 M</td><td>22 M</td><td>333 M</td><td>4444 M</td> <td>1 N</td><td>2 N</td> <td >1 1 1 1 1 1 1 O</td> </tr> <tr> <td>6</td> <td>6</td> <td>6</td> <td>1 1 1 1 1 A</td><td>2 2 2 2 2 A</td><td>3 3 3 3 3 A</td><td>4 4 4 4 4 A</td> <td>1 B</td><td>2 B</td> <td >1 C</td> <td>1 D</td><td>2 D</td><td>3 D</td><td>4 D<br>more...</td> <td>1 E</td><td>2 E</td> <td >1 F</td> <td>1 1 1 G</td><td>2 2 G</td><td>3 G</td><td>4 4 4 4 G</td> <td>1 H</td><td>222 H</td> <td >1 I</td> <td>1 J</td><td>2 J</td><td>3 J</td><td>4 J</td> <td>1 K</td><td>2 2 K<br>more..<br>more..</td> <td >1 L</td> <td>1 M</td><td>22 M</td><td>333 M</td><td>4444 M</td> <td>1 N</td><td>2 N</td> <td >1 1 1 1 1 1 1 O</td> </tr> </table> <br /> <!-- static size footer junk--><!-- static size footer junk--><!-- static size footer junk--><!-- static size footer junk--> <table border="1" width="100%" cellspacing="1" cellpadding="0" align="center"> <tr> <td width="35%" align="left">footer junk left</td> <td >- FOOTER JUNK MIDDLE -</td> <td width="35%" align="right">footer junk right</td> </tr> </table> </form> </BODY> </HTML> 

Je suis d'accord avec la réponse de @ FedericoGiust ; Mais puisque vous avez demandé plus de détails …

 <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"> </script> <script type="text/javascript" src="http://datatables.net/download/build/jquery.dataTables.min.js"> </script> <script type="text/javascript" src="http://datatables.net/download/build/FixedColumns.min.js"> </script> <script type="text/javascript"> $(document).ready(function() { var oTable = $('#bigtable').dataTable({ "sScrollY": "300px", // set vertical size dynamically here "sScrollX": "100%", "bPaginate": false, "bFilter": false }); new FixedColumns(oTable); });​ </script> 

Vous devez ajouter une rangée d'en-têtes de colonne fictive afin que Datatables puisse faire face aux colspans.

Regardez-le sur jsfiddle .

Vous pouvez utiliser DataTables

DataTables

C'est un incroyable plugin jquery pour les tables, et il dispose également d'un nombre intéressant d'extras et de plugins, y compris l'en-tête et le pied de page fixes, le tri des colonnes, la largeur variable, la largeur fixe, l'ajax et beaucoup plus.

Fonctionne avec des tables normales et ne modifie que les cellules d'en-tête, en place (pas de suppression, de copie ou de l'injection d'élément de table). Cela a l'avantage d'autoriser tout contenu, dans n'importe quelle cellule, de toutes les dimensions (+ permet une modification dynamique de ce contenu).

Consultez-le en action: fullpage.html , overflow_scroll.html , fullpage_untouched.html .

Les cellules th verticales et horizontales doivent rester visibles et alignées lors du défilement.

Cette solution n'utilise aucun cadre. N'hésitez pas à remplacer les assistants existants (défilements décalés) en utilisant jquery ou prototype (ou tout autre cadre).

Vous devez ajouter des crochets de code pour appeler _table_make_fixed_header_reposition lors de modifications dynamiques au contenu de la table.

Je n'ai pas testé ceci sur Windows XP (où le rendu accéléré est absent dans tous les navigateurs).

Le fond bleu, l'ombre portée, les bordures, etc. sont juste des choses intéressantes de CSS. Vous pouvez faire cela comme vous le souhaitez, et il vous suffit de créer une table normale (il suffit d'ajouter des styles de cellule sur .DivWrapper au lieu de TH ).

 <!DOCTYPE html> <body> <head> <style> .TableLarge td, .TableLarge th{ border-style: solid; border-width: 1px; border-color: #CAE3EF; padding: 7px; white-space: nowrap; font-family: Verdana; font-size: 10px; } .TableLarge{ border-style: none; border-collapse: collapse; } #padding_for_test{ height: 3000px; width: 9000px; } </style> <script type="text/javascript"> function table_make_fixed_header(elTable, bHorizontal, bVertical, nRepositionIntervalMilliseconds, bWrappedByScrollableDiv) { if(!bHorizontal && !bVertical) return; if(!elTable.id) elTable.id="FixedVH_Headers_"+(new Date().getTime())+Math.floor(Math.random()*10000000); var zIndex=1; if(window.getComputedStyle) zIndex=parseInt(window.getComputedStyle(elTable))?parseInt(window.getComputedStyle(elTable))+1:1; var fnSetupHeaderCell=function(elCell, zIndex) { var elDivWrapper=document.createElement("div"); elDivWrapper.setAttribute("style", "-moz-box-shadow: 3px 3px 4px #aaaaaa; -webkit-box-shadow: 3px 3px 4px #aaaaaa; box-shadow: 3px 3px 4px #aaaaaa;"); elDivWrapper.style.zIndex=zIndex; elDivWrapper.style.backgroundColor="#0000ee"; elDivWrapper.style.color="white"; elDivWrapper.style.padding="3px"; elDivWrapper.className="DivWrapper"; elDivWrapper.style.position="relative"; while(elCell.childNodes.length) elDivWrapper.appendChild(elCell.childNodes[0]); elCell.appendChild(elDivWrapper); }; if(bVertical) for(var r=bHorizontal?1:0; r<elTable.rows.length; r++) fnSetupHeaderCell(elTable.rows[r].cells[0], zIndex); if(bHorizontal) for(var c=bVertical?1:0; c<elTable.rows[0].cells.length; c++) fnSetupHeaderCell(elTable.rows[0].cells[c], zIndex); _table_make_fixed_header_reposition(elTable.id, bHorizontal, bVertical, bWrappedByScrollableDiv); //this could be CPU intensive, depending on the number of events fired and size of the table. var onScrollEventHandler=function(ev){ _table_make_fixed_header_reposition(elTable.id, bHorizontal, bVertical, bWrappedByScrollableDiv); }; var elScrollable=bWrappedByScrollableDiv?elTable.parentNode:window; if(elScrollable.addEventListener) elScrollable.addEventListener('scroll', onScrollEventHandler, false); else if (elScrollable.attachEvent) elScrollable.attachEvent('scroll', onScrollEventHandler); //this is undesired for performance reasons, hooks and event listeners are prefered instead. if(nRepositionIntervalMilliseconds>0) setInterval("_table_make_fixed_header_reposition('"+elTable.id+"', "+(bHorizontal?"true":"false")+", "+(bVertical?"true":"false")+", "+(bWrappedByScrollableDiv?"true":"false")+")", nRepositionIntervalMilliseconds); } function _table_make_fixed_header_reposition(strTableID, bHorizontal, bVertical, bWrappedByScrollableDiv) { var elTable=document.getElementById(strTableID); var strLeft; var strTop; if(bWrappedByScrollableDiv) { strLeft=Math.min(Math.max(elTable.parentNode.scrollLeft-elTable.offsetLeft+elTable.parentNode.offsetLeft, 0), elTable.offsetWidth)+"px"; strTop=Math.min(Math.max(elTable.parentNode.scrollTop-elTable.offsetTop+elTable.parentNode.offsetTop, 0), elTable.offsetHeight)+"px"; } else { strLeft=Math.min(Math.max(f_scrollLeft()-elTable.offsetLeft, 0), elTable.offsetWidth)+"px"; strTop=Math.min(Math.max(f_scrollTop()-elTable.offsetTop, 0), elTable.offsetHeight)+"px"; } if(bVertical) for(var r=bHorizontal?1:0; r<elTable.rows.length; r++) elTable.rows[r].cells[0].childNodes[0].style.left=strLeft; if(bHorizontal) for(var c=bVertical?1:0; c<elTable.rows[0].cells.length; c++) elTable.rows[0].cells[c].childNodes[0].style.top=strTop; } //http://www.softcomplex.com/docs/get_window_size_and_scrollbar_position.html function f_scrollLeft(){ return f_filterResults ( window.pageXOffset ? window.pageXOffset : 0, document.documentElement ? document.documentElement.scrollLeft : 0, document.body ? document.body.scrollLeft : 0 ); } function f_scrollTop() { return f_filterResults ( window.pageYOffset ? window.pageYOffset : 0, document.documentElement ? document.documentElement.scrollTop : 0, document.body ? document.body.scrollTop : 0 ); } function f_filterResults(n_win, n_docel, n_body) { var n_result = n_win ? n_win : 0; if (n_docel && (!n_result || (n_result > n_docel))) n_result = n_docel; return n_body && (!n_result || (n_result > n_body)) ? n_body : n_result; } //you should add an event handler for onload here </script> </head> <body> <p> Vertical and horizontal th cells should remain visible and aligned while scrolling.<br> This solution does not use any frameworks. Feel free to replace existing helpers (scroll offsets) using jquery or prototype (or any other framework). </p> <div style="width: 800px; height: 600px; overflow: scroll"> <table class="TableLarge" id="mySpecialHugeTable"> <tr> <th>Fixed!</th> <th>Fixed!</th> <th>Fixed!</th> <th>Fixed!</th> <th>Fixed!</th> <th>Fixed!</th> <th>Fixed!</th> <th>Fixed!</th> <th>Fixed!</th> </tr> <tr> <th>Fixed!</th> <td>My mother has apples.</td> <td>My mother has apples.</td> <td>The goose is pretty.</td> <td>Hello world!</td> <td>This is a very short story...Real short.</td> <td>Umm...how is this done again?</td> <td>Umm...how is this done again?</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> </tr> <tr> <th>Fixed!</th> <td>The goose is pretty.</td> <td>Hello world!</td> <td>Umm...how is this done again?</td> <td>Umm...how is this done again?</td> <td>My mother has apples.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> <td>This is a very short story...Real short.</td> <td>This is a very short story...Real short.</td> </tr> <tr> <th>Fixed!<br>multi-line</th> <td>My mother has apples.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> <td>Hello world!</td> <td>This is a very short story...Real short.</td> <td>The goose is pretty.</td> <td>The goose is pretty.</td> <td>Umm...how is this done again?</td> </tr> <tr> <th>Fixed!</th> <td>My mother has apples.</td> <td>Umm...how is this done again?</td> <td>The goose is pretty.</td> <td>The goose is pretty.</td> <td>This is a very short story...Real short.</td> <td>Hello world!</td> <td>Hello world!</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> </tr> <tr> <th>Fixed!</th> <td>My mother has apples.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> <td>Umm...how is this done again?</td> <td>Umm...how is this done again?</td> <td>Hello world!</td> <td>This is a very short story...Real short.</td> <td>This is a very short story...Real short.</td> <td>The goose is pretty.</td> </tr> <tr> <th>Fixed!</th> <td>My mother has apples.</td> <td>My mother has apples.</td> <td>My mother has apples.</td> <td>The goose is pretty.</td> <td>Umm...how is this done again?</td> <td>Hello world!</td> <td>This is a very short story...Real short.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> </tr> <tr> <th>Fixed!</th> <td>The goose is pretty.</td> <td>Hello world!</td> <td>Hello world!</td> <td>Umm...how is this done again?</td> <td>My mother has apples.</td> <td>My mother has apples.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> <td>This is a very short story...Real short.</td> </tr> <tr> <th>Fixed!<br>multi-line</th> <td>My mother has apples.</td> <td>My mother has apples.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> <td>Hello world!</td> <td>This is a very short story...Real short.</td> <td>The goose is pretty.</td> <td>The goose is pretty.</td> <td>Umm...how is this done again?</td> </tr> <tr> <th>Fixed!</th> <td>My mother has apples.</td> <td>My mother has apples.</td> <td>My mother has apples.</td> <td>The goose is pretty.</td> <td>Hello world!</td> <td>This is a very short story...Real short.</td> <td>Umm...how is this done again?</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> </tr> <tr> <th>Fixed!</th> <td>The goose is pretty.</td> <td>Hello world!</td> <td>Hello world!</td> <td>Umm...how is this done again?</td> <td>My mother has apples.</td> <td>My mother has apples.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> <td>This is a very short story...Real short.</td> </tr> <tr> <th>Fixed!<br>multi-line</th> <td>My mother has apples.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> <td>Hello world!</td> <td>Hello world!</td> <td>This is a very short story...Real short.</td> <td>This is a very short story...Real short.</td> <td>The goose is pretty.</td> <td>Umm...how is this done again?</td> </tr> <tr> <th>Fixed!</th> <td>My mother has apples.</td> <td>Umm...how is this done again?</td> <td>The goose is pretty.</td> <td>This is a very short story...Real short.</td> <td>This is a very short story...Real short.</td> <td>This is a very short story...Real short.</td> <td>Hello world!</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> </tr> <tr> <th>Fixed!</th> <td>My mother has apples.</td> <td>My mother has apples.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> <td>Umm...how is this done again?</td> <td>Umm...how is this done again?</td> <td>Hello world!</td> <td>This is a very short story...Real short.</td> <td>The goose is pretty.</td> </tr> <tr> <th>Fixed!</th> <td>My mother has apples.</td> <td>The goose is pretty.</td> <td>Umm...how is this done again?</td> <td>Hello world!</td> <td>This is a very short story...Real short.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> </tr> <tr> <th>Fixed!</th> <td>My mother has apples.</td> <td>The goose is pretty.</td> <td>Hello world!</td> <td>This is a very short story...Real short.</td> <td>This is a very short story...Real short.</td> <td>Umm...how is this done again?</td> <td>Umm...how is this done again?</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> </tr> <tr> <th>Fixed!</th> <td>My mother has apples.</td> <td>My mother has apples.</td> <td>My mother has apples.</td> <td>The goose is pretty.</td> <td>Umm...how is this done again?</td> <td>Hello world!</td> <td>This is a very short story...Real short.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> </tr> <tr> <th>Fixed!</th> <td>My mother has apples.</td> <td>My mother has apples.</td> <td>The goose is pretty.</td> <td>Hello world!</td> <td>This is a very short story...Real short.</td> <td>Umm...how is this done again?</td> <td>Umm...how is this done again?</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> </tr> <tr> <th>Fixed!</th> <td>The goose is pretty.</td> <td>Hello world!</td> <td>Umm...how is this done again?</td> <td>Umm...how is this done again?</td> <td>My mother has apples.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> <td>This is a very short story...Real short.</td> <td>This is a very short story...Real short.</td> </tr> <tr> <th>Fixed!<br>multi-line</th> <td>My mother has apples.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> <td>Hello world!</td> <td>This is a very short story...Real short.</td> <td>The goose is pretty.</td> <td>The goose is pretty.</td> <td>Umm...how is this done again?</td> </tr> <tr> <th>Fixed!</th> <td>My mother has apples.</td> <td>Umm...how is this done again?</td> <td>The goose is pretty.</td> <td>The goose is pretty.</td> <td>This is a very short story...Real short.</td> <td>Hello world!</td> <td>Hello world!</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> </tr> <tr> <th>Fixed!</th> <td>My mother has apples.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> <td>Umm...how is this done again?</td> <td>Umm...how is this done again?</td> <td>Hello world!</td> <td>This is a very short story...Real short.</td> <td>This is a very short story...Real short.</td> <td>The goose is pretty.</td> </tr> <tr> <th>Fixed!</th> <td>My mother has apples.</td> <td>My mother has apples.</td> <td>My mother has apples.</td> <td>The goose is pretty.</td> <td>Umm...how is this done again?</td> <td>Hello world!</td> <td>This is a very short story...Real short.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> </tr> <tr> <th>Fixed!</th> <td>My mother has apples.</td> <td>The goose is pretty.</td> <td>Hello world!</td> <td>Hello world!</td> <td>This is a very short story...Real short.</td> <td>This is a very short story...Real short.</td> <td>Umm...how is this done again?</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> </tr> <tr> <th>Fixed!</th> <td>The goose is pretty.</td> <td>Hello world!</td> <td>Hello world!</td> <td>Umm...how is this done again?</td> <td>My mother has apples.</td> <td>My mother has apples.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> <td>This is a very short story...Real short.</td> </tr> <tr> <th>Fixed!<br>multi-line</th> <td>My mother has apples.</td> <td>My mother has apples.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> <td>Hello world!</td> <td>This is a very short story...Real short.</td> <td>The goose is pretty.</td> <td>The goose is pretty.</td> <td>Umm...how is this done again?</td> </tr> <tr> <th>Fixed!</th> <td>My mother has apples.</td> <td>Umm...how is this done again?</td> <td>The goose is pretty.</td> <td>The goose is pretty.</td> <td>This is a very short story...Real short.</td> <td>Hello world!</td> <td>Hello world!</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> </tr> <tr> <th>Fixed!</th> <td>My mother has apples.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> <td>Umm...how is this done again?</td> <td>Hello world!</td> <td>This is a very short story...Real short.</td> <td>The goose is pretty.</td> <td>The goose is pretty.</td> </tr> <tr> <th>Fixed!</th> <td>My mother has apples.</td> <td>My mother has apples.</td> <td>My mother has apples.</td> <td>The goose is pretty.</td> <td>Umm...how is this done again?</td> <td>Hello world!</td> <td>This is a very short story...Real short.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> </tr> <tr> <th>Fixed!</th> <td>The goose is pretty.</td> <td>Hello world!</td> <td>Hello world!</td> <td>Umm...how is this done again?</td> <td>My mother has apples.</td> <td>My mother has apples.</td> <td>I think Javascript is some kind of Voodoo on the DOM.</td> <td>This is a very short story...Real short.</td> </tr> </table> </div> <div id="padding_for_test">&nbsp;</div> <script type="text/javascript"> table_make_fixed_header(document.getElementById("mySpecialHugeTable"), /*bHorizontal*/ true, /*bVertical*/ true, 1000, /*bWrappedByScrollableDiv*/ true); </script> </body> </html> 

It should be fairly easy to delete some CSS and make the fixed cells identical to scrollable cells. Also if you want a dedicated scrollbar, you could wrap this in a scrollable DIV and adjust inside _table_make_fixed_header_reposition by using the DIV 's scroll offsets too.

Edit : updated code to keep headers as close to edge as possible, when table goes outside the viewport (+option to choose between vertical or horizontal headers, or both).

Edit2 : added scrollable div support, and made this the default in the example.

If you'd rather not go with a plugin, combine fixed header vertical scrolling (CSS)

 tbody{display:block;overflow-y:auto;/*+fixed height set w/jQuery etc*/} 

​with the fixed first column horizontal scrolling (JS)

 $('#table-container').scroll(function() { var _left = $(this).scrollLeft(); $('#table th').css('left', _left); //"stick" the first column to viewport }); #table-container{overflow-x:scroll;/*+fixed width set*/} thead, tbody{display:block;} th {position:relative;left:0;/*gets adjusted with JS above*/} 

Fiddle'd here , this does not address resizing to fit browser dimensions though. Assuming it will be run in a dedicated window, it would be fairly trivial; if not and it's intended to be run in-page, it would be rather tough keeping it uncluttered.

Bonne chance.

If you don't like to use heavy loaded plugins you could do:

Create a table with only the fixed table header

Create a div with fixed width (remember the scrollbar width) and height and set scrolling Y direction. Within this div you place the body of the table.

Create the 3th and last table and place the table below the div to make it look like 1 big table.

 <table> HEADER </table> <div><table> BODY </table></div> (div is scrollable) <table> Foot </table> 

If you need to make changes dynamicly use bare javascript, you don't need to use jquery or other heavy plugin.