实现表头固定,tbody垂直滚动
准备工作:

  1. 获取页面可是区域高度
function setIframeHeight() {    var screenHeight = document.documentElement.clientHeight;}

2.屏幕旋转触发事件

window.addEventListener("resize",()=>{    //正常方向或者屏幕旋转180°    if(window.orientation===180||window.orientation===0){        console.log('竖屏');    }    //屏幕顺时针旋转90°或者逆时针旋转90°    if (window.orientation===90||window.orientation===-90) {        console.log('横屏');    }})

方法一:两个table

思路:第一个table放表头,第二个table方内容。循环获取tbody第一行单元格的宽度,给thead的单元格,使表头对齐

<!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>两个table</title>    <link rel="stylesheet" href="css/css.css">    <script src="js/jquery.min.js"></script>    <style>        .scrollX{overflow-x: scroll}        tr th,td {            border: 1px solid #000;            padding: 8px;            white-space: nowrap;        }        .table-head {            padding-right: 17px;            background-color: #eeeeee;            color: #000;        }        .table-body {            display: block;            height: 300px;            overflow-y: scroll;        }        .table-head table,        .table-body table {            border-collapse: collapse;            width: 100%;        }        .table-body table tr:nth-child(2n+1) {            background-color: #f2f2f2;        }    </style></head><body>    <div class="scrollX">        <table class="table-head">            <thead>                <tr>                    <th>部门</th>                    <th>用户名称</th>                    <th>1月</th>                    <th>2月</th>                    <th>3月</th>                    <th>4月</th>                    <th>5月</th>                    <th>6月</th>                    <th>7月</th>                    <th>8月</th>                    <th>9月</th>                    <th>10月</th>                    <th>11月</th>                    <th>12月</th>                    <th>合计</th>                </tr>            </thead>        </table>        <table class="table-body">            <tbody>                <tr>                    <td>这是一个表格内容</td>                    <td>这是一个表格内容</td>                    <td>这是一个表格内容</td>                    <td>这是一个表格内容</td>                    <td>这是一个表格内容</td>                    <td>这是一个表格内容</td>                    <td>这是一个表格内容</td>                    <td>这是一个表格内容</td>                    <td>这是一个表格内容</td>                    <td>这是一个表格内容</td>                    <td>这是一个表格内容</td>                    <td>这是一个表格内容</td>                    <td>这是一个表格内容</td>                    <td>这是一个表格内容</td>                    <td>这是一个表格内容</td>                </tr>               <!-- 循环多次tr...-->            </tbody>        </table>    </div>        <script>            //内容第一行            var bodyTR = $(".table-body tr:eq(1) td");            // 一行有多少个单元格            var bodyTRLength = bodyTR.length;            //宽度            var autoW = $('.table-body tbody').width()            var headTR = $(".table-head tr th")            //获取表头高度            var headH=$(".table-head").height();            function setIframeHeight() {                var screenHeight = document.documentElement.clientHeight-headH;                $(".table-body").height(screenHeight);            }            //屏幕发生旋转重新计算高度            window.addEventListener("resize",()=>{                if(window.orientation===180||window.orientation===0){                    setIframeHeight();                }if (window.orientation===90||window.orientation===-90) {                    setIframeHeight();                }            })            $(function () {                setIframeHeight();                $(".table-head").css("width",autoW+1);                $(".table-body").css("width",autoW+18);                for (var i = 1; i < bodyTRLength; i++) {                    var tdW = $(".table-body tr:eq(1) td:eq("+i+")").width()+1;                    $(".table-head tr th:eq(" + (i ) + ")").css("width", tdW)                }            })        </script>    </table></body></html>

第二种方法:通过JS实现

思路:监听滚动事件,动态控制表头位置

<!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>JS 实现表头tbody固定滚动</title>    <script src="js/jquery.min.js"></script>    <link rel="stylesheet" href="css/css.css" />    <style>      .table tr th,td {        border: 1px solid #000;      }      .table-responsive {        overflow-y: scroll;      }      .text-center td {        white-space: nowrap;        padding: 10px;      }      .table-th-css {        background: #efeff4 !important;        position: relative !important;        text-align: center;        top: 0;        white-space: nowrap;      }      .table-th-css div {        border-top: none;        white-space: nowrap;        padding: 10px;      }      .section-scroll {        height: 417px;      }    </style>  </head>  <body>    <div class="table-responsive section-scroll">      <table class="table table-bordered">        <thead class="table-header">          <tr>            <th class="table-th-css">              <div>部门</div>            </th>            <th class="table-th-css">              <div>用户名称</div>            </th>            <th class="text-center table-th-css">              <div>1月</div>            </th>            <th class="text-center table-th-css">              <div>2月</div>            </th>            <th class="text-center table-th-css">              <div>3月</div>            </th>            <th class="text-center table-th-css">              <div>4月</div>            </th>            <th class="text-center table-th-css">              <div>5月</div>            </th>            <th class="text-center table-th-css">              <div>6月</div>            </th>            <th class="text-center table-th-css">              <div>7月</div>            </th>            <th class="text-center table-th-css">              <div>8月</div>            </th>            <th class="text-center table-th-css">              <div>9月</div>            </th>            <th class="text-center table-th-css">              <div>10月</div>            </th>            <th class="text-center table-th-css">              <div>11月</div>            </th>            <th class="text-center table-th-css">              <div>12月</div>            </th>            <th class="text-center table-th-css">              <div>合计</div>            </th>          </tr>        </thead>        <tbody>          <tr class="text-center">            <td>这是一个表格内容</td>            <td class="table-textWidth">这是一个表格内容</td>            <td>这是一个表格内容</td>            <td>这是一个表格内容</td>            <td>这是一个表格内容</td>            <td>这是一个表格内容</td>            <td>这是一个表格内容</td>            <td>这是一个表格内容</td>            <td>这是一个表格内容</td>            <td>这是一个表格内容</td>            <td>这是一个表格内容</td>            <td>这是一个表格内容</td>            <td>这是一个表格内容</td>            <td>这是一个表格内容</td>            <td>这是一个表格内容</td>          </tr>          <!-- 循环多次tr...-->        </tbody>      </table>    </div>    <script>      $(function() {        setIframeHeight();      });      //屏幕发生旋转重新计算高度      window.addEventListener("resize",()=>{          if(window.orientation===180||window.orientation===0){            setIframeHeight();          }if (window.orientation===90||window.orientation===-90) {            setIframeHeight();          }      })      var tableCont = $(".section-scroll tr th");      //获取th      var tableCont_child = $(".section-scroll tr th div");      //获取th下边的div      var tableScroll = $(".section-scroll");      //获取滚动条同级的class      function scrollHandle() {        console.log(1)        var scrollTop = tableScroll.scrollTop();        // 当滚动距离大于0时设置top及相应的样式        if (scrollTop > 0) {          tableCont.css({"top": scrollTop + "px", "padding":"0"          });          tableCont_child.css({"borderTop": "1px solid #000","borderBottom": "1px solid #000","marginTop": "-1px","padding": "8px"          });        } else {          // 当滚动距离小于0时设置top及相应的样式          tableCont.css({ "top": scrollTop + "px", "marginTop": "0" });          tableCont_child.css({ "border": "none", "marginTop": 0, "marginBottom": 0, })        }      }      tableScroll.on("scroll", scrollHandle);      //获取可是区域高度      function setIframeHeight() {        var screenHeight = document.documentElement.clientHeight;        $(".section-scroll").height(screenHeight);      }    </script>  </body></html>

第三种方法 通过easyui实现

思路,引用easyui文件并实现触加载更多数据,合计行

<!doctype html><html><head>    <meta charset="UTF-8">      <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no">    <title>Basic DataGrid - jQuery EasyUI Mobile Demo</title>      <link rel="stylesheet" type="text/css" href="easyui/themes/metro/easyui.css">      <link rel="stylesheet" type="text/css" href="easyui/themes/mobile.css">      <link rel="stylesheet" type="text/css" href="easyui/themes/icon.css">      <script type="text/javascript" src="js/jquery.min.js"></script>      <script type="text/javascript" src="easyui/jquery.easyui.min.js"></script>     <script type="text/javascript" src="easyui/jquery.easyui.mobile.js"></script>     <!-- <script type="text/javascript" src="https://www.jeasyui.com/easyui/datagrid-bufferview.js"></script></head> --><style>    body{        margin: 0;        padding: 0;    }    .datagrid-footer td{        color: red    }</style><body>        <div id="hh">                <div class="m-toolbar">                    <div class="m-title">Basic DataGrid</div>                </div>            </div>    <table id="dg">          <thead>              <tr>                  <th data-options="field:'itemid',width:80">Item ID</th>                  <th data-options="field:'productid',width:100">Product</th>                  <th data-options="field:'listprice',width:80,align:'right'">List Price</th>                  <th data-options="field:'unitcost',width:80,align:'right'">Unit Cost</th>                  <!-- <th data-options="field:'itemid',width:80">Item ID</th>                  <th data-options="field:'productid',width:100">Product</th>                  <th data-options="field:'listprice',width:80,align:'right'">List Price</th>                  <th data-options="field:'unitcost',width:80,align:'right'">Unit Cost</th>                  <th data-options="field:'itemid',width:80">Item ID</th>                  <th data-options="field:'productid',width:100">Product</th>                  <th data-options="field:'listprice',width:80,align:'right'">List Price</th>                  <th data-options="field:'unitcost',width:80,align:'right'">Unit Cost</th>                  <th data-options="field:'itemid',width:80">Item ID</th>                  <th data-options="field:'productid',width:100">Product</th>                  <th data-options="field:'listprice',width:80,align:'right'">List Price</th>                  <th data-options="field:'unitcost',width:80,align:'right'">Unit Cost</th>                  <th data-options="field:'itemid',width:80">Item ID</th>                  <th data-options="field:'productid',width:100">Product</th>                  <th data-options="field:'listprice',width:80,align:'right'">List Price</th>                  <th data-options="field:'unitcost',width:80,align:'right'">Unit Cost</th>                  <th data-options="field:'itemid',width:80">Item ID</th>                  <th data-options="field:'productid',width:100">Product</th>                  <th data-options="field:'listprice',width:80,align:'right'">List Price</th>                  <th data-options="field:'unitcost',width:80,align:'right'">Unit Cost</th>   -->            </tr>        </thead>      </table>    <script>                var data ={                 "total":5,            "rows":[            {"productid":"FI-SW-01","productname":"Koi","unitcost":10.00,"status":"P","listprice":36.50,"attr1":"Large","itemid":"EST-1"},            {"productid":"K9-DL-01","productname":"Dalmation","unitcost":12.00,"status":"P","listprice":18.50,"attr1":"Spotted Adult Female","itemid":"EST-10"},            {"productid":"RP-SN-01","productname":"Rattlesnake","unitcost":12.00,"status":"P","listprice":38.50,"attr1":"Venomless","itemid":"EST-11"},            {"productid":"RP-SN-01","productname":"Rattlesnake","unitcost":12.00,"status":"P","listprice":26.50,"attr1":"Rattleless","itemid":"EST-12"},            {"productid":"RP-LI-02","productname":"Iguana","unitcost":12.00,"status":"P","listprice":35.50,"attr1":"Green Adult","itemid":"EST-13"},            {"productid":"FL-DSH-01","productname":"Manx","unitcost":12.00,"status":"P","listprice":158.50,"attr1":"Tailless","itemid":"EST-14"},            {"productid":"FL-DSH-01","productname":"Manx","unitcost":12.00,"status":"P","listprice":83.50,"attr1":"With tail","itemid":"EST-15"},            {"productid":"FL-DLH-02","productname":"Persian","unitcost":12.00,"status":"P","listprice":23.50,"attr1":"Adult Female","itemid":"EST-16"},            {"productid":"FL-DLH-02","productname":"Persian","unitcost":12.00,"status":"P","listprice":89.50,"attr1":"Adult Male","itemid":"EST-17"},            {"productid":"FI-SW-01","productname":"Koi","unitcost":10.00,"status":"P","listprice":36.50,"attr1":"Large","itemid":"EST-1"},            {"productid":"K9-DL-01","productname":"Dalmation","unitcost":12.00,"status":"P","listprice":18.50,"attr1":"Spotted Adult Female","itemid":"EST-10"},            {"productid":"RP-SN-01","productname":"Rattlesnake","unitcost":12.00,"status":"P","listprice":38.50,"attr1":"Venomless","itemid":"EST-11"},            {"productid":"RP-SN-01","productname":"Rattlesnake","unitcost":12.00,"status":"P","listprice":26.50,"attr1":"Rattleless","itemid":"EST-12"},            {"productid":"RP-LI-02","productname":"Iguana","unitcost":12.00,"status":"P","listprice":35.50,"attr1":"Green Adult","itemid":"EST-13"},            {"productid":"FL-DSH-01","productname":"Manx","unitcost":12.00,"status":"P","listprice":158.50,"attr1":"Tailless","itemid":"EST-14"},            {"productid":"FL-DSH-01","productname":"Manx","unitcost":12.00,"status":"P","listprice":83.50,"attr1":"With tail","itemid":"EST-15"},            {"productid":"FL-DLH-02","productname":"Persian","unitcost":12.00,"status":"P","listprice":23.50,"attr1":"Adult Female","itemid":"EST-16"},            {"productid":"FL-DLH-02","productname":"Persian","unitcost":12.00,"status":"P","listprice":89.50,"attr1":"Adult Male","itemid":"EST-17"},            {"productid":"FI-SW-01","productname":"Koi","unitcost":10.00,"status":"P","listprice":36.50,"attr1":"Large","itemid":"EST-1"},            {"productid":"K9-DL-01","productname":"Dalmation","unitcost":12.00,"status":"P","listprice":18.50,"attr1":"Spotted Adult Female","itemid":"EST-10"},            {"productid":"RP-SN-01","productname":"Rattlesnake","unitcost":12.00,"status":"P","listprice":38.50,"attr1":"Venomless","itemid":"EST-11"},            {"productid":"RP-SN-01","productname":"Rattlesnake","unitcost":12.00,"status":"P","listprice":26.50,"attr1":"Rattleless","itemid":"EST-12"},            {"productid":"RP-LI-02","productname":"Iguana","unitcost":12.00,"status":"P","listprice":35.50,"attr1":"Green Adult","itemid":"EST-13"},            {"productid":"FL-DSH-01","productname":"Manx","unitcost":12.00,"status":"P","listprice":158.50,"attr1":"Tailless","itemid":"EST-14"},            {"productid":"FL-DSH-01","productname":"Manx","unitcost":12.00,"status":"P","listprice":83.50,"attr1":"With tail","itemid":"EST-15"},            {"productid":"FL-DLH-02","productname":"Persian","unitcost":12.00,"status":"P","listprice":23.50,"attr1":"Adult Female","itemid":"EST-16"},            {"productid":"FL-DLH-02","productname":"Persian","unitcost":12.00,"status":"P","listprice":89.50,"attr1":"Adult Male","itemid":"EST-17"},            {"productid":"AV-CB-01","productname":"Amazon Parrot","unitcost":92.00,"status":"P","listprice":63.50,"attr1":"Adult Male","itemid":"EST-18"}        ],            "footer":[{"productid":"合计","unitcost":"1203.00","listprice":"5895.00"}]        };        var pushdata =[            {"productid":"FI-SW-01","productname":"Koi","unitcost":10.00,"status":"P","listprice":36.50,"attr1":"Large","itemid":"EST-1"},            {"productid":"K9-DL-01","productname":"Dalmation","unitcost":12.00,"status":"P","listprice":18.50,"attr1":"Spotted Adult Female","itemid":"EST-10"},            {"productid":"RP-SN-01","productname":"Rattlesnake","unitcost":12.00,"status":"P","listprice":38.50,"attr1":"Venomless","itemid":"EST-11"},            {"productid":"RP-SN-01","productname":"Rattlesnake","unitcost":12.00,"status":"P","listprice":26.50,"attr1":"Rattleless","itemid":"EST-12"},            {"productid":"RP-LI-02","productname":"Iguana","unitcost":12.00,"status":"P","listprice":35.50,"attr1":"Green Adult","itemid":"EST-13"},            {"productid":"FL-DSH-01","productname":"Manx","unitcost":12.00,"status":"P","listprice":158.50,"attr1":"Tailless","itemid":"EST-14"},            {"productid":"FL-DSH-01","productname":"Manx","unitcost":12.00,"status":"P","listprice":83.50,"attr1":"With tail","itemid":"EST-15"},            {"productid":"FL-DLH-02","productname":"Persian","unitcost":12.00,"status":"P","listprice":23.50,"attr1":"Adult Female","itemid":"EST-16"},            {"productid":"FL-DLH-02","productname":"Persian","unitcost":12.00,"status":"P","listprice":89.50,"attr1":"Adult Male","itemid":"EST-17"},            {"productid":"FI-SW-01","productname":"Koi","unitcost":10.00,"status":"P","listprice":36.50,"attr1":"Large","itemid":"EST-1"},            {"productid":"K9-DL-01","productname":"Dalmation","unitcost":12.00,"status":"P","listprice":18.50,"attr1":"Spotted Adult Female","itemid":"EST-10"},            {"productid":"RP-SN-01","productname":"Rattlesnake","unitcost":12.00,"status":"P","listprice":38.50,"attr1":"Venomless","itemid":"EST-11"},            {"productid":"RP-SN-01","productname":"Rattlesnake","unitcost":12.00,"status":"P","listprice":26.50,"attr1":"Rattleless","itemid":"EST-12"},            {"productid":"RP-LI-02","productname":"Iguana","unitcost":12.00,"status":"P","listprice":35.50,"attr1":"Green Adult","itemid":"EST-13"},            {"productid":"FL-DSH-01","productname":"Manx","unitcost":12.00,"status":"P","listprice":158.50,"attr1":"Tailless","itemid":"EST-14"},            {"productid":"FL-DSH-01","productname":"Manx","unitcost":12.00,"status":"P","listprice":83.50,"attr1":"With tail","itemid":"EST-15"},            {"productid":"FL-DLH-02","productname":"Persian","unitcost":12.00,"status":"P","listprice":23.50,"attr1":"Adult Female","itemid":"EST-16"},            {"productid":"FL-DLH-02","productname":"Persian","unitcost":12.00,"status":"P","listprice":89.50,"attr1":"Adult Male","itemid":"EST-17"},            {"productid":"FI-SW-01","productname":"Koi","unitcost":10.00,"status":"P","listprice":36.50,"attr1":"Large","itemid":"EST-1"},            {"productid":"K9-DL-01","productname":"Dalmation","unitcost":12.00,"status":"P","listprice":18.50,"attr1":"Spotted Adult Female","itemid":"EST-10"},            {"productid":"RP-SN-01","productname":"Rattlesnake","unitcost":12.00,"status":"P","listprice":38.50,"attr1":"Venomless","itemid":"EST-11"},            {"productid":"RP-SN-01","productname":"Rattlesnake","unitcost":12.00,"status":"P","listprice":26.50,"attr1":"Rattleless","itemid":"EST-12"},            {"productid":"RP-LI-02","productname":"Iguana","unitcost":12.00,"status":"P","listprice":35.50,"attr1":"Green Adult","itemid":"EST-13"},            {"productid":"FL-DSH-01","productname":"Manx","unitcost":12.00,"status":"P","listprice":158.50,"attr1":"Tailless","itemid":"EST-14"},            {"productid":"FL-DSH-01","productname":"Manx","unitcost":12.00,"status":"P","listprice":83.50,"attr1":"With tail","itemid":"EST-15"},            {"productid":"FL-DLH-02","productname":"Persian","unitcost":12.00,"status":"P","listprice":23.50,"attr1":"Adult Female","itemid":"EST-16"},            {"productid":"FL-DLH-02","productname":"Persian","unitcost":12.00,"status":"P","listprice":89.50,"attr1":"Adult Male","itemid":"EST-17"},            {"productid":"AV-CB-01","productname":"Amazon Parrot","unitcost":92.00,"status":"P","listprice":63.50,"attr1":"Adult Male","itemid":"EST-18"}        ];        $(function(){            var screenHeight = document.documentElement.clientHeight;            var pageNum=1            $("#dg").datagrid({                header:'#hh',                height:screenHeight,                data:data,                singleSelect:true,                showFooter : true,                //view:bufferview,                rownumbers:true,                pageSize:30            })            var scrollDiv = $(".datagrid-body").get(1);            console.log(pushdata)            $(scrollDiv).scroll(function(){                console.log("gundong")                var that=this;                var cango=true;                var scrollH=scrollDiv.scrollTop+scrollDiv.clientHeight                if(scrollH==scrollDiv.scrollHeight&&cango==true){                    for(var i=0;i<pushdata.length;i++) {                        var row_data = {                            itemid : pushdata[i].itemid,                            productid :pushdata[i].productid,                            listprice: pushdata[i].listprice,                            unitcost : pushdata[i].unitcost,                        };                        $('#dg').datagrid('appendRow', row_data);                    }                                    }            })        });        //计算表格高度        function setIframeHeight() {            var screenHeight = document.documentElement.clientHeight;            $(".table-body").height(screenHeight);            $('#dg').datagrid("resize",{                height: screenHeight            }                );        }        //屏幕发生旋转重新计算高度        window.addEventListener("resize",()=>{            if(window.orientation===180||window.orientation===0){                setIframeHeight();            }if (window.orientation===90||window.orientation===-90) {                setIframeHeight();            }        })    </script></body>    </html>

优缺点分析

EasyUI => ios:无问题;安卓:横向滚动表头抖动
JS => ios:无问题;安卓:垂直滚动表头抖动
两个table=> ios:无法横向滚动;安卓:无问题