之前gridview用js来冻结表头,但gridview的width不能超过100%,原理就是复制整个表头的样式,然后用position:fixed固定。代码示例:
<div id='ucgv_divhead' style="position:fixed;z-index:100;"></div>
<div id="ucgv_cs" style="display:none;"></div>
<div id="ucgv_divbody" style="position:absolute;width:100%;">
<asp:GridView ID="gv1" runat="server" >
</asp:GridView>
</div>
<script type="text/javascript" >
try {
var gdvList = document.getElementById("ucgv_gv1");
var gdvHeader = gdvList.cloneNode(true);
gdvHeader.id = "gvtitle";
for (i = gdvHeader.rows.length - 1; i > 0; i--) { gdvHeader.deleteRow(i); }
document.getElementById("ucgv_cs").appendChild(gdvHeader);
var cs = document.getElementById("ucgv_cs");
var divb = document.getElementById("ucgv_divbody");
var tbl = document.getElementById("ucgv_divhead");
var htm = cs.innerHTML.replace("table-layout:fixed;", "");
htm = htm.replace("table-layout:fixed", "");
htm = htm.replace("all", "");
htm = htm.replace("</tbody>", "");
htm = htm.replace("<tbody>", "");
var tbs = gdvList.rows[1].cells.length;
for (i = 0; i < tbs; i++) {
var tbw = gdvList.rows[1].cells[i].offsetWidth;
htm = htm.replace('scope="col"', 'style="height:50px;width:' + tbw.toString() + 'px;"');
htm = htm.replace('scope=col', 'style="height:50px;width:' + tbw.toString() + 'px;"');
}
htm = htm.replace("gvtitle", "gvtitle2");
tbl.innerHTML = htm;
tbl.style.top = divb.style.top;
tbl.style.left = divb.style.left;
}
catch(e) { }
</script>
同理,冻结首列,变换下参数即可。
<script type="text/javascript">
try {
var gdvListqb = document.getElementById("gvqb");
var gdvHeaderqb = gdvListqb.cloneNode(true);
gdvHeaderqb.id = "gvtitleqb";
let csqb = document.getElementById("cs");
cs.appendChild(gdvHeaderqb);
let divbqb = document.getElementById("divbodyqb");
let tblqb = document.getElementById("divhead");
let htmqb = cs.innerHTML.replace("table-layout:fixed;", "");
htmqb = htmqb.replace("table-layout:fixed", "");
htmqb = htmqb.replace("all", "");
htmqb = htmqb.replace("</tbody>", "");
htmqb = htmqb.replace("<tbody>", "");
let whqb = 0;
for (let i = 0; i < gdvHeaderqb.rows.length; i++) {
let tr = gdvListqb.rows[i];
for (let j = 0; j < tr.cells.length; j++) {
let tbw = tr.cells[j].offsetWidth;
if (i == 0) {
htmqb = htmqb.replace('scope="col"', 'style="height:40px;width:' + tbw.toString() + 'px;"');
htmqb = htmqb.replace('scope="col"', 'style="height:40px;width:' + tbw.toString() + 'px;"');
if (j < 1)
whqb += tbw;
}
else {
htmqb = htmqb.replace('scope="col"', 'style="height:40px;width:' + tbw.toString() + 'px;"');
htmqb = htmqb.replace('scope=col', 'style="height:40px;width:' + tbw.toString() + 'px;"');
}
}
}
htmqb = htmqb.replace("gvtitleqb", "gvtitle2qb");
tblqb.innerHTML = htmqb;
let tb2qb = document.getElementById("gvtitle2qb");
for (let i = 0; i < tb2qb.rows.length; i++) {
let tr = tb2qb.rows[i];
for (let j = tr.cells.length - 1; j > 0; j--) {
tr.deleteCell(j);
}
}
tb2qb.style.width = whqb + 'px';
csqb.innerHTML = "";
}
catch (e) {
}
</script>
现在项目要求同时冻结首列首行,上面的js就不起作用了。后面百度了下,发现有个position: sticky;可以满足要求,经过多次调试,终于达成效果。
<style>
.fixed-table {
display: block;
}
.fixed-table thead,
.fixed-table tbody tr {
display: table;
width: 100%;
table-layout: fixed;
}
.fixed-table tbody {
/*height: 200px; 不能设置高度,不然会滑动一半就不固定了 */
display: block;
}
.fixed-table tbody tr:first-child { /*表头*/
position: sticky;
top: 100px; /* 要与父元素top位置一致*/
z-index: 10;
background-color: inherit;
}
.fixed-table tbody tr th:first-child, /*表头第一列*/
.fixed-table tbody td:first-child { /*第一列*/
position: sticky;
left: 0;
z-index: 1;
background-color: inherit;
}
.fixed-table tbody tr th:first-child { /* 确保表头第一列 */
z-index: 20;
}
</style>
gridview只要加上 class="fixed-table"即可。不过浏览器要求较高,不适合IE那种的。