首行表头和最左列和最右列固定中间滚动的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">
<!-- 表头 start -->
<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>
<!-- 表头 end -->
<!-- 表格内容 start -->
<div class="fixed-table_body-wraper">
<table class="fixed-table_body" cellspacing="0" cellpadding="0">
<tbody>
<!-- 中间表格内容 -->
</tbody>
</table>
</div>
<!-- 表格内容 end -->
<!-- 固定列 start -->
<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>
<!-- 固定列 end -->
</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;
// var random = Math.random();
//初始化FixedTable
$(".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));
});
//页面初始化给定一个20行的表格S
$(".fixed-table-box").addRow(function () {
var html = '';
for (let i = 0; i < 20; i++) {
html += getRowHtml();
}
return html;
});
function getRowHtml() {
random++;
// var random = Math.random();
// var random = Math.round(Math.random());
var html = '';
// for(var i = 0; i < 5; i ++){
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){
/*根据指定任意地方的行的索引、dom对象、jquery对象获取表格中表格主体、两侧固定列对应的行*/
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){
/*删除行,参数row可以是行的索引、dom对象、jquery对象*/
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){
/*添加行,fn必须返回HTML字符串或jQuery对象*/
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){
/*鼠标hover在每一行后所处理业务*/
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;}
/*固定列的下标,数组的内容必须是一个对象,且对象格式为
{
index: 0,//下标
direction: "left"//固定列方向
}
*/
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,//用于判断右侧的固定列的right值是否需要加上滚动条的宽度,这样才能显示出垂直滚动条
scrollWidth = 0,
scrollWidth2 = 0,
maxHeight = 0,
isIE = $.isIE();
if(isIE){//IE浏览器
/*在IE浏览器中$fixedTableBox.height()、$fixedTableBox[0].offsetHeight获取的高度
都为0,不知道为什么,但$fixedTableBox[0].clientHeight和$fixedTableBox[0].scrollHeight都有值,
为了保证两边的固定列能出来,所以就使用了这种解决方案*/
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;
}
/*如果有水平滚动条fixedTableBody.offsetHeight会把水平滚动条的高度也计算进去,因此这里需要减去水平滚动条的高度*/
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 (){
/*判断浏览器是否为IE浏览器*/
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;
}
/* 表头 start */
.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;
}
/* 表头 end */
/*表格内容 start*/
.fixed-table-box .fixed-table_body td{
border-top: 0;
border-left: 0;
}
.fixed-table-box .fixed-table_body tr.rowHover{
background-color: #eef1f6;
}
/*表格内容 end*/
/* 行固定表格 start*/
.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%;
}
/* 行固定表格 end*/
/* 列固定表格 start */
.fixed-table-box.col-fixed{
/* overflow-x: auto; */
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
的时候可以同步的拖动.fixed-table-box.col-fixed .fixed-table_header-wraper*/
overflow: hidden;
}
.fixed-table-box.col-fixed .fixed-table_body-wraper{
overflow-x: auto;
}
/* 列固定表格 end */
/* 固定列 start */
.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;
/* border-left: 1px solid #dfe6ec\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;
}
/* 固定列 end */
/* 固定列和固定表头 start */
.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;
}
/* 固定列和固定表头 end */
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;
/* max-height: 70%; 可以修改滚动窗口上下的比例 */
}
/*内容了表格主体内容有纵向滚动条*/
.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;
}
/*为了让两侧固定列能够同步表格主体内容滚动,这个高度要比上边的高度大41PX(即表头的高度)*/
.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;
}
版权声明:本文为qq_42557844原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。