可以实现 html table 的 上+下+左+右 4个方向的冻结功能,废话不多话,直接上代码。
相关的配置如下,表格 id,以及4个属性,data-top-row-num、data-bottom-row-num、data-left-column-num、data-right-column-num 请根据实际情况进行设置。
function tableFreeze(id, width, height) {
var table = $("#" + id);
var topRowNum = table.attr("data-top-row-num") === undefined ? 0 : parseInt(table.attr("data-top-row-num"));
var bottomRowNum = table.attr("data-bottom-row-num") === undefined ? 0 : parseInt(table.attr("data-bottom-row-num"));
var leftColumnNum = table.attr("data-left-column-num") === undefined ? 0 : parseInt(table.attr("data-left-column-num"));
var rightColumnNum = table.attr("data-right-column-num") === undefined ? 0 : parseInt(table.attr("data-right-column-num"));
//共用变量
var freezeBottomHeight = 0;
var freezeRightWidth = 0;
//制作外部框,判断是否存在
var freezeLayout = $("#" + id + "-freeze-layout");
if (freezeLayout.length > 0) {
freezeLayout.before(table);
freezeLayout.empty();
} else {
table.after("<div id='" + id + "-freeze-layout' style='overflow:hidden;width:" + width + "px;height:" + height + "px;'></div>");
freezeLayout = $("#" + id + "-freeze-layout");
}
//判断并生成容器
var html = "";
if (topRowNum > 0 && leftColumnNum > 0) {
html += "<div id='" + id + "-freeze-top-left' style='padding:0px;'></div>";
}
if (topRowNum > 0 && rightColumnNum > 0) {
html += "<div id='" + id + "-freeze-top-right' style='padding:0px;'></div>";
}
if (bottomRowNum > 0 && leftColumnNum > 0) {
html += "<div id='" + id + "-freeze-bottom-left' style='padding:0px;'></div>";
}
if (bottomRowNum > 0 && rightColumnNum > 0) {
html += "<div id='" + id + "-freeze-bottom-right' style='padding:0px;'></div>";
}
if (topRowNum > 0) {
html += "<div id='" + id + "-freeze-top' style='padding:0px;'></div>";
}
if (bottomRowNum > 0) {
html += "<div id='" + id + "-freeze-bottom' style='padding:0px;'></div>";
}
if (leftColumnNum > 0) {
html += "<div id='" + id + "-freeze-left' style='padding:0px;'></div>";
}
if (rightColumnNum > 0) {
html += "<div id='" + id + "-freeze-right' style='padding:0px;'></div>";
}
html += "<div id='" + id + "-table-data' style='padding:0px;'></div>";
freezeLayout.append(html);
//获取容器
var freezeTopLeft = $("#" + id + "-freeze-top-left");
var freezeTopRight = $("#" + id + "-freeze-top-right");
var freezeBottomLeft = $("#" + id + "-freeze-bottom-left");
var freezeBottomRight = $("#" + id + "-freeze-bottom-right");
var freezeTop = $("#" + id + "-freeze-top");
var freezeBottom = $("#" + id + "-freeze-bottom");
var freezeLeft = $("#" + id + "-freeze-left");
var freezeRight = $("#" + id + "-freeze-right");
var tableData = $("#" + id + "-table-data");
//表格数据添加至容器
tableData.append(table);
//克隆数据
if (freezeTopLeft.length > 0) {
var freezeTopLeftClone = table.clone(true);
freezeTopLeftClone.attr("id", id + "-freeze-top-left-clone");
freezeTopLeft.append(freezeTopLeftClone);
}
if (freezeTopRight.length > 0) {
var freezeTopRightClone = table.clone(true);
freezeTopRightClone.attr("id", id + "-freeze-top-right-clone");
freezeTopRight.append(freezeTopRightClone);
}
if (freezeBottomLeft.length > 0) {
var freezeBottomLeftClone = table.clone(true);
freezeBottomLeftClone.attr("id", id + "-freeze-bottom-left-clone");
freezeBottomLeft.append(freezeBottomLeftClone);
}
if (freezeBottomRight.length > 0) {
var freezeBottomRightClone = table.clone(true);
freezeBottomRightClone.attr("id", id + "-freeze-bottom-right-clone");
freezeBottomRight.append(freezeBottomRightClone);
}
if (freezeTop.length > 0) {
var freezeTopClone = table.clone(true);
freezeTopClone.attr("id", id + "-freeze-top-clone");
freezeTop.append(freezeTopClone);
}
if (freezeBottom.length > 0) {
var freezeBottomClone = table.clone(true);
freezeBottomClone.attr("id", id + "-freeze-bottom-clone");
freezeBottom.append(freezeBottomClone);
}
if (freezeLeft.length > 0) {
var freezeLeftClone = table.clone(true);
freezeLeftClone.attr("id", id + "-freeze-left-clone");
freezeLeft.append(freezeLeftClone);
}
if (freezeRight.length > 0) {
var freezeRightClone = table.clone(true);
freezeRightClone.attr("id", id + "-freeze-right-clone");
freezeRight.append(freezeRightClone);
}
$("#" + id + "-freeze-layout table").css("margin", "0");
//顶部高度计算
if (freezeTop.length > 0) {
var freezeTopHeight = 0;
var ignoreRowNum = 0;
$("#" + id + "-freeze-top tr:lt(" + topRowNum + ")").each(function () {
var row = $(this);
if (ignoreRowNum > 0) {
ignoreRowNum -= 1;
} else {
var td = row.find("td:first,th:first");
freezeTopHeight += td.outerHeight(true);
if (typeof (td.attr("rowspan")) != "undefined") {
ignoreRowNum = parseInt(td.attr("rowspan")) - 1;
}
}
});
freezeTopHeight += 2;
//设置高度,涉及3个容器,上,上左,上右
freezeTop.css("height", freezeTopHeight);
if (freezeTopLeft.length > 0) {
freezeTopLeft.css("height", freezeTopHeight);
}
if (freezeTopRight.length > 0) {
freezeTopRight.css("height", freezeTopHeight);
}
}
//底部高度计算
if (freezeBottom.length > 0) {
var ignoreRowNum = 0;
$("#" + id + "-freeze-bottom tr:gt(" + (table.find("tr").length - 1 - bottomRowNum) + ")").each(function () {
var row = $(this);
if (ignoreRowNum > 0) {
ignoreRowNum -= 1;
} else {
var td = row.find("td:first,th:first");
freezeBottomHeight += td.outerHeight(true);
if (typeof (td.attr("rowspan")) != "undefined") {
ignoreRowNum = parseInt(td.attr("rowspan")) - 1;
}
}
});
freezeBottomHeight += 2;
//设置高度,涉及3个容器,下,下左,下右
freezeBottom.css("height", freezeBottomHeight);
if (freezeBottomLeft.length > 0) {
freezeBottomLeft.css("height", freezeBottomHeight);
}
if (freezeBottomRight.length > 0) {
freezeBottomRight.css("height", freezeBottomHeight);
}
}
//左边宽度计算
if (freezeLeft.length > 0) {
//逐行判断,如 colspan<=leftColumnNum 即满足
var freezeLeftWidth = 0;
$("#" + id + "-freeze-left tr").each(function () {
var row = $(this);
var tds = row.find("td,th");
var tempColumnCount = 0;
var tempFreezeLeftWidth = 0;
for (var i = 0; i < leftColumnNum; i++) {
tempColumnCount += $(tds[i]).attr("colspan") ? parseInt($(tds[i]).attr("colspan")) : 1;
tempFreezeLeftWidth += $(tds[i]).outerWidth(true);
}
if (tempColumnCount === leftColumnNum) {
freezeLeftWidth = tempFreezeLeftWidth;
return false;
}
});
freezeLeftWidth += 2;
//设置宽度,涉及3个容器,左,上左,下左
freezeLeft.css("width", freezeLeftWidth);
if (freezeTopLeft.length > 0) {
freezeTopLeft.css("width", freezeLeftWidth);
}
if (freezeBottomLeft.length > 0) {
freezeBottomLeft.css("width", freezeLeftWidth);
}
}
//右边宽度计算
if (freezeRight.length > 0) {
//逐行判断,如 colspan<=rightColumnNum 即满足,需要从右边开始计算
$("#" + id + "-freeze-right tr").each(function () {
var row = $(this);
var tds = row.find("td,th");
var tempColumnCount = 0;
var tempFreezeRightWidth = 0;
for (var i = 0; i < rightColumnNum; i++) {
var td = $(tds[tds.length - i - 1]);
tempColumnCount += td.attr("colspan") ? parseInt(td.attr("colspan")) : 1;
tempFreezeRightWidth += $(td).outerWidth(true);
}
if (tempColumnCount === rightColumnNum) {
freezeRightWidth = tempFreezeRightWidth;
return false;
}
});
freezeRightWidth += 2;
//高度宽度,涉及3个容器,右,上右,下右
freezeRight.css("width", freezeRightWidth);
if (freezeTopRight.length > 0) {
freezeTopRight.css("width", freezeRightWidth);
}
if (freezeBottomRight.length > 0) {
freezeBottomRight.css("width", freezeRightWidth);
}
}
//滚动事件
tableData.scroll(function () {
if (freezeTop.length > 0) {
freezeTop.scrollLeft(tableData.scrollLeft());
}
if (freezeLeft.length > 0) {
freezeLeft.scrollTop(tableData.scrollTop());
}
if (freezeBottom.length > 0) {
freezeBottom.scrollLeft(tableData.scrollLeft());
}
if (freezeRight.length > 0) {
freezeRight.scrollTop(tableData.scrollTop());
}
});
//位置设置
tableData.css({ "overflow": "scroll", "width": width, "height": height, "position": "absolute" });
if (freezeTop.length > 0) {
freezeTop.css({ "overflow": "hidden", "width": width - 17, "position": "absolute", "z-index": "60" });
freezeTop.offset(freezeLayout.offset());
}
if (freezeLeft.length > 0) {
freezeLeft.css({ "overflow": "hidden", "height": height - 17, "position": "absolute", "z-index": "55" });
freezeLeft.offset(freezeLayout.offset());
}
if (freezeTopLeft.length > 0) {
freezeTopLeft.css({ "overflow": "hidden", "position": "absolute", "z-index": "65" });
freezeTopLeft.offset(freezeLayout.offset());
}
if (freezeBottom.length > 0) {
freezeBottom.css({ "overflow": "hidden", "width": width - 17, "position": "absolute", "z-index": "60" });
$("#" + id + "-freeze-bottom-clone").css({ "position": "absolute", "bottom": "0px" });
freezeBottom.offset({ top: freezeLayout.offset().top + height - freezeBottomHeight - 17, left: freezeLayout.offset().left });
}
if (freezeBottomLeft.length > 0) {
freezeBottomLeft.css({ "overflow": "hidden", "position": "absolute", "z-index": "65" });
$("#" + id + "-freeze-bottom-left-clone").css({ "position": "absolute", "bottom": "0px" });
freezeBottomLeft.offset({ top: freezeLayout.offset().top + height - freezeBottomHeight - 17, left: freezeLayout.offset().left });
}
if (freezeRight.length > 0) {
freezeRight.css({ "overflow": "hidden", "height": height - 17, "position": "absolute", "z-index": "55" });
$("#" + id + "-freeze-right-clone").css({ "position": "absolute", "right": "0px" });
freezeRight.offset({ top: freezeLayout.offset().top, left: freezeLayout.offset().left + width - freezeRightWidth - 17 });
}
if (freezeTopRight.length > 0) {
freezeTopRight.css({ "overflow": "hidden", "position": "absolute", "z-index": "65" });
$("#" + id + "-freeze-top-right-clone").css({ "position": "absolute", "right": "0px" });
freezeTopRight.offset({ top: freezeLayout.offset().top, left: freezeLayout.offset().left + width - freezeRightWidth - 17 });
}
if (freezeBottomRight.length > 0) {
freezeBottomRight.css({ "overflow": "hidden", "position": "absolute", "z-index": "65" });
$("#" + id + "-freeze-bottom-right-clone").css({ "position": "absolute", "bottom": "0px", "right": "0px" });
freezeBottomRight.offset({ top: freezeLayout.offset().top + height - freezeBottomHeight - 17, left: freezeLayout.offset().left + width - freezeRightWidth - 17 });
}
tableData.offset(freezeLayout.offset());
}