js table 表格冻结

可以实现 html table 的 上+下+左+右 4个方向的冻结功能,废话不多话,直接上代码。

相关的配置如下,表格 id,以及4个属性,data-top-row-num、data-bottom-row-num、data-left-column-num、data-right-column-num 请根据实际情况进行设置。

有个在线 demo 链接,可以看看效果。

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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值