首行表头和最左列和最右列固定中间滚动的html table样式
效果图
html(index.html)
<!DOCTYPE html>
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< meta http-equiv = " X-UA-Compatible" content = " ie=edge" >
< title> 左右两侧固定列,中间内容可以横向拖动</ title>
< link rel = " stylesheet" href = " ./table.css" >
< script src = " ./jquery.min.js" > </ script>
< script src = " ./table.js" > </ script>
< style>
</ style>
</ head>
< body>
< div class = " fixed-table-box row-col-fixed" >
< div class = " fixed-table_header-wraper" >
< table class = " fixed-table_header" cellspacing = " 0" cellpadding = " 0" >
< thead>
< tr>
< th class = " w-150" data-fixed = " true" >
< div class = " table-cell" > 字段1</ div>
</ th>
< th class = " w-120" >
< div class = " table-cell" > 字段2</ div>
</ th>
< th class = " w-120" >
< div class = " table-cell" > 字段3</ div>
</ th>
< th class = " w-120" >
< div class = " table-cell" > 字段4</ div>
</ th>
< th class = " w-300" >
< div class = " table-cell" > 字段5</ div>
</ th>
< th class = " w-120" >
< div class = " table-cell" > 字段6</ div>
</ th>
< th class = " w-100" data-fixed = " true" data-direction = " right" >
< div class = " table-cell" > 字段7</ div>
</ th>
</ tr>
</ thead>
</ table>
</ div>
< div class = " fixed-table_body-wraper" >
< table class = " fixed-table_body" cellspacing = " 0" cellpadding = " 0" >
< tbody>
</ tbody>
</ table>
</ div>
< div id = " date" class = " fixed-table_fixed fixed-table_fixed-left" >
< div class = " fixed-table_header-wraper" >
< table class = " fixed-table_header" cellspacing = " 0" cellpadding = " 0" >
< thead>
< tr>
< th class = " w-150" >
< div class = " table-cell" > 字段1</ div>
</ th>
</ tr>
</ thead>
</ table>
</ div>
< div class = " fixed-table_body-wraper" >
< table class = " fixed-table_body" cellspacing = " 0" cellpadding = " 0" >
< tbody>
</ tbody>
</ table>
</ div>
</ div>
< div id = " operate" class = " fixed-table_fixed fixed-table_fixed-right" style =" right : 1px; " >
< div id = " operate1" class = " fixed-table_header-wraper" >
< table class = " fixed-table_header" cellspacing = " 0" cellpadding = " 0" >
< thead>
< tr>
< th class = " w-100" >
< div class = " table-cell" > 字段7</ div>
</ th>
</ tr>
</ thead>
</ table>
</ div>
< div class = " fixed-table_body-wraper" style =" margin-top : 41px; " >
< table class = " fixed-table_body" cellspacing = " 0" cellpadding = " 0" >
< tbody>
</ tbody>
</ table>
</ div>
</ div>
</ div>
< div class = " fixed-table-box_fixed-right-patch" style =" width : 0px; height : 39px; " > </ div>
< div class = " btns" >
< button type = " button" id = " empty_data" > 清空数据</ button>
< button type = " button" id = " add_data" > 添加数据</ button>
< button type = " button" id = " del_row" > 删除行</ button>
</ div>
< script>
var random = 10000 ;
$ ( ".fixed-table-box" ) . fixedTable ( ) ;
$ ( "#empty_data" ) . on ( "click" , function ( ) {
$ ( ".fixed-table-box" ) . emptyTable ( ) ;
} ) ;
$ ( "#add_data" ) . on ( "click" , function ( ) {
$ ( ".fixed-table-box" ) . addRow ( function ( ) {
return getRowHtml ( ) ;
} ) ;
} ) ;
$ ( "#del_row" ) . on ( "click" , function ( ) {
$ ( ".fixed-table-box" ) . deleteRow ( $ ( ".fixed-table-box" ) . children ( '.fixed-table_fixed-left' ) . children ( '.fixed-table_body-wraper' ) . find ( 'tr' ) . eq ( 0 ) ) ;
} ) ;
$ ( ".fixed-table-box" ) . addRow ( function ( ) {
var html = '' ;
for ( let i = 0 ; i < 20 ; i++ ) {
html += getRowHtml ( ) ;
}
return html;
} ) ;
function getRowHtml ( ) {
random++ ;
var html = '' ;
html += '<tr>' ;
html += ' <td class="w-150"><div class="table-cell">' + random + '</div></td>' ;
html += ' <td class="w-120"><div class="table-cell">' + random + '</div></td>' ;
html += ' <td class="w-120"><div class="table-cell">' + random + '</div></td>' ;
html += ' <td class="w-120"><div class="table-cell">' + random + '</div></td>' ;
html += ' <td class="w-300"><div class="table-cell">' + random + '</div></td>' ;
html += ' <td class="w-120"><div class="table-cell">' + random + '</div></td>' ;
html += ' <td class="w-100">' ;
html += ' <div class="table-cell">' ;
html += ' <a href="###">查看</a>' ;
html += ' <a href="###">编辑</a>' ;
html += ' </div>' ;
html += ' </td>' ;
html += '</tr>' ;
return html;
}
</ script>
</ body>
</ html>
js(table.js)
; ( function ( ) {
$. fn. extend ( {
fixedTable: function ( ) {
var $this = this ;
return $this . each ( function ( index, item) {
var $this = $ ( this ) ;
if ( ! $this . hasClass ( 'fixed-table-box' ) ) { return ; }
if ( $this . hasClass ( 'head-fixed' ) ) { return ; }
$. calFixedTableWidth ( item) ;
$. calFixedColHeight ( item) ;
$. syncScroll ( item) ;
$this . _setFixedIndex ( ) ;
$this . rowHover ( ) ;
} ) ;
} ,
getRow: function ( row) {
var $this = this ,
rowDom = undefined,
index = undefined,
rows = [ ] ;
if ( typeof row != "number" ) {
rowDom = $ ( row) ;
if ( rowDom. length == 0 ) { return ; }
index = rowDom. index ( ) ;
} else if ( typeof row == "number" ) {
index = row;
}
if ( index == undefined) { return this ; }
$this . each ( function ( index2, item) {
var $item = $ ( item) ,
row = {
bodyRow: undefined,
leftFixedRow: undefined,
rightFixedRow: undefined
} ;
if ( ! $item. hasClass ( 'fixed-table-box' ) ) { return ; }
var bodyRows = $item. children ( '.fixed-table_body-wraper' ) . find ( "tr" ) ,
leftFixed = $item. children ( '.fixed-table_fixed-left' ) ,
rightFixed = $item. children ( '.fixed-table_fixed-right' ) ;
row. bodyRow = bodyRows. eq ( index) ;
if ( leftFixed. length > 0 ) {
row. leftFixedRow = leftFixed. children ( '.fixed-table_body-wraper' ) . find ( "tr" ) . eq ( index) ;
}
if ( rightFixed. length > 0 ) {
row. rightFixedRow = rightFixed. children ( '.fixed-table_body-wraper' ) . find ( "tr" ) . eq ( index) ;
}
rows. push ( row) ;
} ) ;
return rows;
} ,
deleteRow: function ( row, cb) {
var $this = this ;
if ( row == undefined) { return this ; }
return $this . each ( function ( index, item) {
if ( ! $ ( item) . hasClass ( 'fixed-table-box' ) ) { return ; }
var $item = $ ( item) ,
rows = $item. getRow ( row) ;
if ( ! rows || rows. length == 0 ) { return ; }
$. each ( rows, function ( index, row) {
if ( row. bodyRow) {
row. bodyRow. remove ( ) ;
}
if ( row. leftFixedRow) {
row. leftFixedRow. remove ( ) ;
}
if ( row. rightFixedRow) {
row. rightFixedRow. remove ( ) ;
}
$. calFixedColHeight ( item) ;
} ) ;
} ) ;
} ,
addRow: function ( htmlDom, cb) {
var $this = this ,
returnVal = undefined,
rowDoms = undefined;
if ( ! htmlDom) { return this ; }
if ( ( { } ) . toString. call ( htmlDom) == "[object Function]" ) {
returnVal = htmlDom ( ) ;
} else {
returnVal = htmlDom;
}
if ( ! returnVal) { return this ; }
rowDoms = $ ( returnVal) ;
if ( rowDoms. length == 0 ) { return this ; }
return $this . each ( function ( index, item) {
if ( ! $ ( item) . hasClass ( 'fixed-table-box' ) ) { return ; }
var $item = $ ( item) ,
$fixedTableBody = $item. children ( '.fixed-table_body-wraper' ) . find ( "tbody" ) ,
$leftFixed = $item. children ( '.fixed-table_fixed-left' ) ,
$rightFixed = $item. children ( '.fixed-table_fixed-right' ) ;
$fixedTableBody. append ( rowDoms) ;
if ( ! item. fixedIndex) { return ; }
if ( item. fixedIndex. left. length > 0 && $leftFixed. length > 0 ) {
var cloneRows = rowDoms. clone ( true ) ,
$leftFixedBody = $leftFixed. children ( '.fixed-table_body-wraper' ) . find ( "tbody" ) ,
leftTrs = [ ] ;
$. each ( item. fixedIndex. left, function ( index2, fixedIndex) {
cloneRows. each ( function ( index3, cloneRow) {
var leftTr = $ ( this ) . clone ( true ) . html ( "" ) ;
$ ( cloneRow) . find ( "td" ) . each ( function ( index4, td) {
if ( index4 == fixedIndex. index) {
leftTr. append ( td) ;
}
} ) ;
leftTrs. push ( leftTr) ;
} ) ;
} ) ;
$leftFixedBody. append ( leftTrs) ;
}
if ( item. fixedIndex. right. length > 0 && $rightFixed. length > 0 ) {
var cloneRows = rowDoms. clone ( true ) ,
$rightFixedBody = $rightFixed. children ( '.fixed-table_body-wraper' ) . find ( "tbody" ) ,
rightTrs = [ ] ;
$. each ( item. fixedIndex. right, function ( index2, fixedIndex) {
cloneRows. each ( function ( index3, cloneRow) {
var rightTr = $ ( this ) . clone ( true ) . html ( "" ) ;
$ ( cloneRow) . find ( "td" ) . each ( function ( index4, td) {
if ( index4 == fixedIndex. index) {
rightTr. append ( td) ;
}
} ) ;
rightTrs. push ( rightTr) ;
} ) ;
} ) ;
$rightFixedBody. append ( rightTrs) ;
}
$. calFixedColHeight ( item) ;
$ ( item) . rowHover ( ) ;
} ) ;
} ,
emptyTable: function ( cb) {
var $this = this ;
return $this . each ( function ( index, item) {
var $item = $ ( item) ;
if ( ! $item. hasClass ( 'fixed-table-box' ) ) { return ; }
var bodyRows = $item. children ( '.fixed-table_body-wraper' ) ,
leftFixed = $item. children ( '.fixed-table_fixed-left' ) ,
rightFixed = $item. children ( '.fixed-table_fixed-right' ) ;
bodyRows. find ( "tbody" ) . html ( "" ) ;
leftFixed. find ( ".fixed-table_body-wraper tbody" ) . html ( "" ) ;
rightFixed. find ( ".fixed-table_body-wraper tbody" ) . html ( "" ) ;
$. calFixedColHeight ( item) ;
} ) ;
} ,
rowHover: function ( cb) {
var $this = this ;
return $this . each ( function ( index, item) {
if ( ! $ ( item) . hasClass ( 'fixed-table-box' ) ) { return ; }
var $item = $ ( item) ,
hoverClass = $item. attr ( "data-hover" ) || "rowHover" ,
$fixedTableBodyTrs = $item. children ( '.fixed-table_body-wraper' ) . find ( "tr" ) ,
$leftFixed = $item. children ( '.fixed-table_fixed-left' ) ,
$rightFixed = $item. children ( '.fixed-table_fixed-right' ) ;
$fixedTableBodyTrs. off ( "mouseenter.rowHover" ) . off ( "mouseleave.rowHover" ) ;
$fixedTableBodyTrs. on ( "mouseenter.rowHover" , _process) . on ( "mouseleave.rowHover" , _process) ;
if ( $leftFixed. length > 0 ) {
var $leftFixedTrs = $leftFixed. children ( '.fixed-table_body-wraper' ) . find ( "tr" ) ;
$leftFixedTrs. off ( "mouseenter.rowHover" ) . off ( "mouseleave.rowHover" ) ;
$leftFixedTrs. on ( "mouseenter.rowHover" , _process) . on ( "mouseleave.rowHover" , _process) ;
}
if ( $rightFixed. length > 0 ) {
var $rightFixedTrs = $rightFixed. children ( '.fixed-table_body-wraper' ) . find ( "tr" ) ;
$rightFixedTrs. off ( "mouseenter.rowHover" ) . off ( "mouseleave.rowHover" ) ;
$rightFixedTrs. on ( "mouseenter.rowHover" , _process) . on ( "mouseleave.rowHover" , _process) ;
}
} ) ;
function _process ( ) {
var $this = $ ( this ) ,
fixedTableBox = $this . parents ( ".fixed-table-box" ) ,
hoverClass = fixedTableBox. attr ( "data-hover" ) || "rowHover" ,
rows = fixedTableBox. getRow ( $this . index ( ) ) ;
if ( ! rows || rows. length == 0 ) { return ; }
$. each ( rows, function ( index, row) {
row. bodyRow. toggleClass ( hoverClass) ;
if ( row. leftFixedRow) {
row. leftFixedRow. toggleClass ( hoverClass) ;
}
if ( row. rightFixedRow) {
row. rightFixedRow. toggleClass ( hoverClass) ;
}
} ) ;
}
} ,
_setFixedIndex: function ( ) {
return this . each ( function ( ) {
var that = this ,
$this = $ ( this ) ,
$fixedTableHeaderTd = $this . children ( '.fixed-table_header-wraper' ) . find ( 'th' ) ;
if ( this . fixedIndex) { return ; }
this . fixedIndex = { } ;
$fixedTableHeaderTd. each ( function ( index, th) {
if ( th. hasAttribute ( "data-fixed" ) ) {
var direction = ( $ ( th) . attr ( "data-direction" ) || "left" ) . toLowerCase ( ) ;
if ( ! that. fixedIndex. left) {
that. fixedIndex. left = [ ] ;
}
if ( ! that. fixedIndex. right) {
that. fixedIndex. right = [ ] ;
}
that. fixedIndex[ direction] . push ( {
index: index,
direction: direction
} ) ;
}
} ) ;
} ) ;
}
} ) ;
$. extend ( {
calFixedColHeight: function ( fixedTableBox) {
if ( ! $ ( fixedTableBox) . hasClass ( 'fixed-table-box' ) ) { return this ; }
var $fixedTableBox = $ ( fixedTableBox) ,
$fixedTableHeader = $fixedTableBox. children ( '.fixed-table_header-wraper' ) ,
$fixedTableBody = $fixedTableBox. children ( ".fixed-table_body-wraper" ) ,
fixedTableBody = $fixedTableBody[ 0 ] ,
$fixedTableLeft = $ ( ".fixed-table_fixed-left" ) ,
$fixedTableRight = $ ( ".fixed-table_fixed-right" ) ,
hasCrosswiseScroll = true ,
hasVerticalScroll = false ,
scrollWidth = 0 ,
scrollWidth2 = 0 ,
maxHeight = 0 ,
isIE = $. isIE ( ) ;
if ( isIE) {
maxHeight = $fixedTableBox. height ( ) || $fixedTableBox[ 0 ] . clientHeight || $fixedTableBox[ 0 ] . scrollHeight;
} else {
maxHeight = $fixedTableBox. height ( ) ;
}
if ( fixedTableBody. scrollWidth > fixedTableBody. clientWidth || fixedTableBody. offsetWidth > fixedTableBody. clientWidth) {
hasCrosswiseScroll = true ;
} else {
hasCrosswiseScroll = false ;
}
if ( fixedTableBody. scrollHeight > fixedTableBody. clientHeight || ( fixedTableBody. offsetHeight - $. getScrollWidth ( ) ) > fixedTableBody. clientHeight) {
hasVerticalScroll = true ;
} else {
hasVerticalScroll = false ;
}
if ( hasCrosswiseScroll) {
scrollWidth = $. getScrollWidth ( ) ;
}
if ( hasVerticalScroll) {
scrollWidth2 = $. getScrollWidth ( ) ;
if ( $fixedTableBox. find ( ".fixed-table-box_fixed-right-patch" ) . length == 0 ) {
var rightPatch = $ ( '<div class="fixed-table-box_fixed-right-patch"></div>' ) ,
height = $fixedTableHeader. height ( ) ;
rightPatch. css ( {
width: scrollWidth2,
height: height- 2
} ) ;
$fixedTableBox. append ( rightPatch) ;
}
} else {
if ( $fixedTableBox. find ( ".fixed-table-box_fixed-right-patch" ) . length == 0 ) {
$fixedTableBox. find ( ".fixed-table-box_fixed-right-patch" ) . remove ( ) ;
}
}
var height = maxHeight - scrollWidth,
fixedTable = $fixedTableBox. find ( ".fixed-table_fixed" ) ;
if ( fixedTable. height ( ) != Math. abs ( maxHeight - scrollWidth) ) {
var height = maxHeight - scrollWidth;
fixedTable. height ( maxHeight - scrollWidth) ;
}
$fixedTableBox. find ( ".fixed-table_fixed.fixed-table_fixed-right" ) . css ( "right" , ( scrollWidth2- 1 ) < 0 ? 1 : ( scrollWidth2 - 1 ) ) ;
return $fixedTableBox;
} ,
calFixedTableWidth: function ( fixedTableBox) {
if ( ! $ ( fixedTableBox) . hasClass ( 'fixed-table-box' ) ) { return this ; }
var $this = $ ( fixedTableBox) ,
$body = $ ( "body" ) ,
$fixedTableHeader = $this . children ( ) . children ( ".fixed-table_header" ) ,
$fixedTableBody = $this . children ( ) . children ( ".fixed-table_body" ) ,
$cloneNode = $fixedTableHeader. clone ( true ) ,
width = 0 ;
$cloneNode. css ( {
position: "fixed" ,
top: "-1000px"
} ) ;
$body. append ( $cloneNode) ;
width = $cloneNode. width ( ) ;
$fixedTableHeader. width ( width) ;
$fixedTableBody. width ( width) ;
$cloneNode. remove ( ) ;
return this ;
} ,
syncScroll: function ( fixedTableBox) {
if ( ! $ ( fixedTableBox) . hasClass ( 'fixed-table-box' ) ) { return this ; }
var $fixedTableBox = $ ( fixedTableBox) ,
fixedTableHeader = $fixedTableBox. children ( ".fixed-table_header-wraper" ) ,
$fixedTableBody = $fixedTableBox. children ( '.fixed-table_body-wraper' ) ,
$fixedCols = $fixedTableBox. children ( '.fixed-table_fixed' ) . children ( '.fixed-table_body-wraper' ) ;
$fixedTableBody. on ( "scroll" , function ( ) {
var $this = $ ( this ) ;
fixedTableHeader. scrollLeft ( $this . scrollLeft ( ) ) ;
$fixedCols. scrollTop ( $this . scrollTop ( ) ) ;
} ) ;
return this ;
} ,
getScrollWidth: function ( ) {
var div = document. createElement ( "div" ) ,
w1 = 0 ,
w2 = 0 ;
document. body. appendChild ( div) ;
div. style. position = "fixed" ;
div. style. left = "-2000px" ;
div. style. width = "200px" ;
div. style. height = "200px" ;
w1 = div. clientWidth;
div. style. overflow = "scroll" ;
w2 = div. clientWidth;
document. body. removeChild ( div) ;
return w1- w2;
} ,
isIE: function ( ) {
var ua = navigator. userAgent. toLowerCase ( ) ;
if ( /msie \d/g . test ( ua) || ( ( /trident\/\d/g . test ( ua) ) && /like gecko/g . test ( ua) ) ) {
return true ;
} else {
return false ;
}
}
} ) ;
} ) ( ) ;
css(table.css)
@charset "utf-8" ;
body {
margin : 0;
padding : 0;
}
.fixed-table-box table {
border-spacing : 0;
border-collapse : collapse;
box-sizing : border-box;
}
.fixed-table-box tr,
.fixed-table-box td,
.fixed-table-box th {
box-sizing : border-box;
}
.fixed-table-box {
position : relative;
font-size : 14px;
line-height : 1.42858;
border : 1px solid #dfe6ec;
border-bottom : 0;
border-right : 0;
overflow : hidden;
}
.fixed-table-box:before {
display : block;
position : absolute;
bottom : 0;
left : 0;
content : " " ;
width : 100%;
height : 1px;
background-color : #dfe6ec;
}
.fixed-table-box:after {
display : block;
position : absolute;
top : 0;
right : 0;
content : " " ;
width : 1px;
height : 100%;
background-color : #dfe6ec;
}
.fixed-table-box .fixed-table_header,
.fixed-table-box .fixed-table_body {
width : auto;
}
.fixed-table-box table {
background-color : #fff;
border : 0;
}
.fixed-table-box th,
.fixed-table-box td {
position : relative;
text-align : left;
padding : 5px 0;
border : 1px solid #dfe6ec;
}
.fixed-table-box .table-cell {
display : block;
height : 30px;
line-height : 30px;
word-break : break-all;
white-space : pre-line;
overflow : hidden;
text-overflow : ellipsis;
padding-left : 15px;
}
.fixed-table-box>.fixed-table_header-wraper {
overflow : hidden;
}
.fixed-table-box .fixed-table_header.fixed-header {
position : absolute;
top : 0;
left : 0;
width : 100%;
}
.fixed-table-box .fixed-table_header tr {
background-color : #eef1f6;
}
.fixed-table-box .fixed-table_header th {
color : #1f2d3d;
border-top : 0;
border-left : 0;
}
.fixed-table-box .fixed-table_body td {
border-top : 0;
border-left : 0;
}
.fixed-table-box .fixed-table_body tr.rowHover {
background-color : #eef1f6;
}
.fixed-table-box.head-fixed .fixed-table_body-wraper {
overflow-y : auto;
}
.fixed-table-box.head-fixed .fixed-table_header,
.fixed-table-box.head-fixed .fixed-table_body {
width : 100%;
}
.fixed-table-box.col-fixed {
border-right : 1px solid #eef1f6;
}
.fixed-table-box.col-fixed:after {
display : none;
}
.fixed-table-box.col-fixed .fixed-table_header-wraper {
overflow : hidden;
}
.fixed-table-box.col-fixed .fixed-table_body-wraper {
overflow-x : auto;
}
.fixed-table_fixed {
position : absolute;
top : 0;
z-index : 5;
background-color : #fff;
overflow : hidden;
}
.fixed-table_fixed-left {
left : 0;
box-shadow : 1px -1px 8px 1px #d3d4d6;
}
.fixed-table_fixed-right {
right : 0;
box-shadow : -2px -1px 8px 1px #d3d4d6;
}
.fixed-table_fixed .fixed-table_header-wraper,
.fixed-table_fixed .fixed-table_body-wraper {
overflow-y : hidden;
}
.fixed-table_fixed.fixed-table_fixed-right td {
border-right : none;
border-left : 1px solid #dfe6ec;
}
.fixed-table-box.row-col-fixed>.fixed-table_body-wraper {
overflow : auto;
}
.fixed-table-box_fixed-right-patch {
background-color : #eef1f6;
position : absolute;
top : 0;
right : 0;
}
html,
body {
margin : 0;
padding : 0;
height : 100%;
}
body {
height : 95%;
}
table {
border : 0;
}
.fixed-table-box {
width : 800px;
margin : 50px auto;
max-height : 700px;
}
.fixed-table-box>.fixed-table_body-wraper,
.fixed-table_fixed>.fixed-table_body-wraper,
.fixed-table-box>.fixed-table_body-wraper .fixed-table_body .fixed-table_body {
max-height : 659px;
}
.fixed-table_fixed {
max-height : 700px;
}
.w-150 {
width : 150px;
}
.w-120 {
width : 120px;
}
.w-300 {
width : 300px;
}
.w-100 {
width : 100px;
}
.w-150,
.w-120,
.w-300,
.w-100 {
table-layout : fixed;
}
.btns {
text-align : center;
}
.btns button {
padding : 10px 20px;
}
#operate1 {
position : absolute;
z-index : 1;
right : -1px;
width : 100px;
}
#operate::before {
display : block;
position : absolute;
top : 0;
left : 0;
content : " " ;
width : 1px;
height : 100%;
background-color : #dfe6ec;
}
#operate::after,
#date::after {
display : block;
position : absolute;
top : 0;
left : 0;
content : " " ;
width : 1px;
height : 100%;
background-color : #dfe6ec;
}