前言
最近做移动端的h5项目,要做一个可配置表头的复杂表格,网上找了很久也没什么好方法,结合网上的一些例子,在此做一了一个完整的vue版的例子。
效果
无图无真相,先上最终效果图再说 。
方法一:iscroll 插件版
第一步:npm install
引入 iscroll
npm i iscroll --save
第二步:封装
对插件再做一层封装,封装成 iscrollTable.js 方便调用,代码如下:
// 统一使用
const iScollProbe = require('iscroll/build/iscroll-probe');
let scroller = null;
let Selector = "";
export function createIScroller(selector) {
Selector = selector;
scroller = new iScollProbe(Selector, {
preventDefault: false, // 阻止浏览器滑动默认行为
probeType: 3, //需要使用 iscroll-probe.js 才能生效 probeType : 1 滚动不繁忙的时候触发 probeType : 2 滚动时每隔一定时间触发 probeType : 3 每滚动一像素触发一次
mouseWheel: true, //是否监听鼠标滚轮事件。
scrollX: true, // 启动x轴滑动
scrollY: true, // 启动y轴滑动
// momentum: false,
lockDirection: false,
snap: false, //自动分割容器,用于制作走马灯效果等。Options.snap:true// 根据容器尺寸自动分割
//snapSpeed: 400,
scrollbars: false, //是否显示默认滚动条
freeScroll: true, //主要在上下左右滚动都生效时使用,可以向任意方向滚动。
deceleration: 0.0001, //滚动动量减速越大越快,建议不大于 0.01,默认:0.0006
disableMouse: true, //是否关闭鼠标事件探测。如知道运行在哪个平台,可以开启它来加速。
disablePointer: true, //是否关闭指针事件探测。如知道运行在哪个平台,可以开启它来加速。
disableTouch: false, //是否关闭触摸事件探测。如知道运行在哪个平台,可以开启它来加速。
eventPassthrough: false, //使用 IScroll 的横轴滚动时,如想使用系统立轴滚动并在横轴上生效,请开启。
bounce: false //是否启用弹力动画效果,关掉可以加速
});
scroller.on('scroll', updatePosition);
scroller.on('scrollEnd', updatePosition);
scroller.on('beforeScrollStart', function () {
scroller.refresh();
});
function updatePosition() {
let frozenCols = document.querySelectorAll(selector + ' table tr td.cols');
let frozenRows = document.querySelectorAll(selector + ' table tr th.rows');
let frozenCrosses = document.querySelectorAll(selector + ' table tr th.cross');
for (let i = 0; i < frozenCols.length; i++) {
frozenCols[i].style.transform = 'translate(' + -1 * this.x + 'px, 0px) translateZ(0px)';
}
for (let i = 0; i < frozenRows.length; i++) {
frozenRows[i].style.transform = 'translate(0px, ' + -1 * this.y + 'px) translateZ(0px)';
}
for (let i = 0; i < frozenCrosses.length; i++) {
frozenCrosses[i].style.transform = 'translate(' + -1 * this.x + 'px,' + -1 * this.y + 'px) translateZ(0px)';
}
}
return scroller;
}
export function refreshScroller() {
if (scroller === null) {
console.error("先初始化scroller");
return;
}
setTimeout(() => {
scroller.refresh();
scroller.scrollTo(0, 0);
let frozenCols = document.querySelectorAll(Selector + ' table tr td.cols');
let frozenRows = document.querySelectorAll(Selector + ' table tr th.rows');
let frozenCrosses = document.querySelectorAll(Selector + ' table tr th.cross');
for (let i = 0; i < frozenCols.length; i++) {
frozenCols[i].style.transform = 'translate(0px, 0px) translateZ(0px)';
}
for (let i = 0; i < frozenRows.length; i++) {
frozenRows[i].style.transform = 'translate(0px, 0px) translateZ(0px)';
}
for (let i = 0; i < frozenCrosses.length; i++) {
frozenCrosses[i].style.transform = 'translate(0px, 0px) translateZ(0px)';
}
}, 0);
}
第三步:使用
引用前面的自己封装的iscrollTable.js,用到的table.vue的具体代码如下:
<template>
<div class="pages-tables " id="pages-tables">
<div class="waterMask" id="watermark"></div>
<div class="rolling-table meal-table" ref="tableBox" :style="{height: maxHeight + 'px'}">
<table class="table" id="table" cellpadding="0" cellspacing="0" ref="rollingTable">
<tr v-for="(x,i) in xList" :key="i">
<th class="rows " :class="{'cross': index == 0 && i == 0}" v-for="(l,index) in x" :key="index" :colspan="l.colspan" :rowspan="l.rowspan">{{l.name}}</th>
</tr>
<tr v-for="(l,i) in yList" :key="i + 'a'">
<template v-for="(x, xKey) in xField">
<td v-for="(ll,yKey) in l" :key="yKey" v-if="x === yKey" :class="{'cols': yKey == xField[0]}">
{{ yList[i][yKey]}}
</td>
</template>
</tr>
<tr></tr>
</table>
</div>
</div>
</template>
<script>
import { createIScroller, refreshScroller } from "libs/iscrollTable";
import { addWaterMarker } from "libs/common/common";
export default {
data() {
return {
maxHeight:'100%',
scroll: {
scroller: null
},
xList: [
[
{
field_name: "statis_date",
name: "第一行合并3行1列",
colspan: 1, //指定单元格 横向 跨越的 列数
rowspan: 3, //指定单元格 纵向 跨越的 行数
},
{
field_name: "custom_field",
name: "第一行合并2列",
colspan: 2,
rowspan: 1,
},
{
field_name: "custom_field",
name: "第一行合并2列",
colspan: 2,
rowspan: 1,
},
{
field_name: "custom_field",
name: "第一行合并3列",
colspan: 3,
rowspan: 1,
},
],
[
{
field_name: "custom_field",
name: "第二行日期",
colspan: 1, //指定单元格 横向 跨越的 列数
rowspan: 1, //指定单元格 纵向 跨越的 行数
},
{
field_name: "custom_field",
name: "第二行日期合并2列",
colspan: 2,
rowspan: 1,
},
{
field_name: "custom_field",
name: "第二行日期合并2列",
colspan: 2,
rowspan: 1,
},
{
field_name: "custom_field",
name: "第二行日期合并3列",
colspan: 3,
rowspan: 1,
},
],
[
{
field_name: "area_name",
name: "第三行当月新增",
colspan: 1, //指定单元格 横向 跨越的 列数
rowspan: 1, //指定单元格 纵向 跨越的 行数
},
{
field_name: "area_name1",
name: "第三行当月新增1",
colspan: 1,
rowspan: 1,
},
{
field_name: "area_name2",
name: "第三行当月新增2",
colspan: 1,
rowspan: 1,
},
{
field_name: "area_name3",
name: "第三行当月新增3",
colspan: 1,
rowspan: 1,
},
{
field_name: "area_name4",
name: "第三行当月新增4",
colspan: 1,
rowspan: 1,
},
{
field_name: "area_name5",
name: "第三行当月新增5",
colspan: 1,
rowspan: 1,
},
{
field_name: "area_name6",
name: "第三行当月新增6",
colspan: 1,
rowspan: 1,
},
],
],
xField: ['statis_date', 'area_name', "area_name1", "area_name2", "area_name3", "area_name4", "area_name5", "area_name6",],
yList: [
{
area_name: "新增数据开始",
area_name1: "新增数据开始1",
area_name2: "新增数据开始2",
area_name3: "新增数据开始3",
area_name4: "新增数据开始4",
area_name5: "新增数据开始5",
area_name6: "新增数据开始6",
statis_date: 100007,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据最后",
area_name1: "新增数据最后1",
area_name2: "新增数据最后2",
area_name3: "新增数据最后3",
area_name4: "新增数据最后4",
area_name5: "新增数据最后5",
area_name6: "新增数据最后6",
statis_date: 222222,
}
]
}
},
mounted() {
this.maxHeight = window.screen.height
this.scroll.scroller = createIScroller(".meal-table");
// addWaterMarker(document.getElementById('watermark'))
}
}
</script>
<style lang="less" scoped>
.pages-tables {
-webkit-overflow-scrolling: touch; // ios滑动顺畅
position: relative;
}
.rolling-table {
height: 100%;
font-size: 0.28rem;
color: #86939a;
background-color: #fff;
width: 100%;
-webkit-overflow-scrolling: touch;
position: relative;
top: 0;
overflow: hidden;
}
.rows {
position: relative;
z-index: 3;
}
.cross {
position: relative;
z-index: 5;
}
table td {
border: 0px solid #000;
font-size: 0.32rem;
background: #fff;
}
::-webkit-scrollbar {
display: none;
}
.table {
// border-collapse: collapse; //去掉重复的border
color: #86939e;
font-size: 0.32rem;
border: 0px solid #000;
min-height: 100%;
text-align: center;
td {
border-bottom: 0.02rem solid #eee;
white-space: nowrap;
height: 0.86rem;
line-height: 0.86rem;
padding: 0 0.2rem;
}
th {
color: #43484d;
white-space: nowrap;
height: 0.74rem;
line-height: 0.74rem;
padding: 0rem 0.3rem;
background-color: #f3f4f6;
font-weight: normal;
padding-bottom: 0;
padding-top: 0;
border: 0.02rem solid red;
}
}
tr{
position: relative;
background-color: #fff;
&:nth-of-type(odd){
td{
// background-color: pink;
}
}
}
</style>
注意点:
- table 外的盒子 .rolling-table 要设置高度,不然向上滚动失效
2.固定和行与列,即:rows、cross 的position要设为relative
最终效果就如上图。
方法二: 结合css,自定义封装版
原理
因为除了表头和第一列,其他都可以滚动所以需要:
1.一个展示的table表格
2.一个用来覆盖上表头的 thead,一个用来覆盖左上角的 div,一个固定在第一列的 tbody。
- 展示的table表格放在最底层,覆盖上表头的 thead固定定位在最上面,固定在第一列的 tbody固定定位在最左边,左上角的 div固定是左上角且z-index最大,在最上层。
- 固定的表格头部与第一列的宽、高、行高都是通过获取真实的表格的宽高来设定的。
- 通过展示的table表格的上下滚动从而带动固定在第一列的 tbody向上滚动,向左右滚动带动覆盖上表头的 thead的左右滚动。
完整代码如下:
<template>
<div class="pages" id="pages" :style="{height: maxHeight + 'px'}">
<table id="table" class="table" cellpadding="0" cellspacing="0">
<thead v-show="showFixedHeaderCloFirst" class="fixedThead" id="fixedThead" :style="{left: fixedTheadLeft}">
<tr v-for="(x,i) in xList" :key="i+'a'">
<th v-for="(l,i) in x" :key="i" :colspan="l.colspan" :rowspan="l.rowspan">{{l.name}}</th>
</tr>
</thead>
<div v-show="showFixedHeaderCloFirst" class="fixedHeaderCenter" id="fixedHeaderCenter" :style="{'line-height': firstCloHeight + 'px',width: firstCloWidth-1 + 'px'}">{{xList[0][0].name}}</div>
<tbody v-show="showFixedHeaderCloFirst" class="fixedHeaderCloFirst" id="fixedHeaderCloFirst" :style="{'top': fixedHeaderCloFirstTop ,'height': fixedHeaderCloFirstHeight}">
<tr v-for="(l,i) in yList" :key="i" :style="{width: firstCloWidth + 'px',height: cloFirstLineHeight + 'px'}">
<td :style="{width: firstCloWidth + 'px',height: cloFirstLineHeight -1 + 'px' }">{{l.statis_date }} </td>
</tr>
</tbody>
<thead >
<tr v-for="(x,index) in xList" :key="index+'b'">
<th :class="{firstCol: index == 0 && i == 0}" v-for="(l,i) in x" :key="i" :colspan="l.colspan" :rowspan="l.rowspan">{{l.name}}</th>
</tr>
</thead>
<tbody id="tbody">
<tr v-for="(l,i) in yList" :key="i">
<td v-for="(x,xKey) in xField" :key="xKey">
<div v-for="(ll,yKey) in l" v-if="x === yKey" :key="yKey" :class="{'tables-content-item-yellow':yList[i][yKey] > 0 && validateVal(x),'tables-content-item-green':yList[i][yKey] <= 0 && validateVal(x),}">
{{ yList[i][yKey]}}
</div>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
data() {
return {
maxHeight: '100%',
fixedTheadLeft: 0,
fixedHeaderCloFirstTop: 0,
fixedHeaderCloFirstHeight: '100%',
th: [],
tl: [],
temp: [],
firstCloWidth: 0,
firstCloHeight: 0,
showFixedHeaderCloFirst: false,
cloFirstLineHeight: '0',
fixedCol: false,
fixedHeader: false,
fixedA1: false,
hLeft: 0,
hHeight: 0,
xList: [
[
{
field_name: "statis_date",
name: "第一行合并3行1列",
colspan: 1, //指定单元格 横向 跨越的 列数
rowspan: 3, //指定单元格 纵向 跨越的 行数
},
{
field_name: "custom_field",
name: "第一行合并2列",
colspan: 2,
rowspan: 1,
},
{
field_name: "custom_field",
name: "第一行合并2列",
colspan: 2,
rowspan: 1,
},
{
field_name: "custom_field",
name: "第一行合并3列",
colspan: 3,
rowspan: 1,
},
],
[
{
field_name: "custom_field",
name: "第二行日期",
colspan: 1, //指定单元格 横向 跨越的 列数
rowspan: 1, //指定单元格 纵向 跨越的 行数
},
{
field_name: "custom_field",
name: "第二行日期合并2列",
colspan: 2,
rowspan: 1,
},
{
field_name: "custom_field",
name: "第二行日期合并2列",
colspan: 2,
rowspan: 1,
},
{
field_name: "custom_field",
name: "第二行日期合并3列",
colspan: 3,
rowspan: 1,
},
],
[
{
field_name: "area_name",
name: "第三行当月新增",
colspan: 1, //指定单元格 横向 跨越的 列数
rowspan: 1, //指定单元格 纵向 跨越的 行数
},
{
field_name: "area_name1",
name: "第三行当月新增1",
colspan: 1,
rowspan: 1,
},
{
field_name: "area_name2",
name: "第三行当月新增2",
colspan: 1,
rowspan: 1,
},
{
field_name: "area_name3",
name: "第三行当月新增3",
colspan: 1,
rowspan: 1,
},
{
field_name: "area_name4",
name: "第三行当月新增4",
colspan: 1,
rowspan: 1,
},
{
field_name: "area_name5",
name: "第三行当月新增5",
colspan: 1,
rowspan: 1,
},
{
field_name: "area_name6",
name: "第三行当月新增6",
colspan: 1,
rowspan: 1,
},
],
],
xField: ['statis_date', 'area_name', "area_name1", "area_name2", "area_name3", "area_name4", "area_name5", "area_name6",],
yList: [
{
area_name: "新增数据开始",
area_name1: "新增数据开始1",
area_name2: "新增数据开始2",
area_name3: "新增数据开始3",
area_name4: "新增数据开始4",
area_name5: "新增数据开始5",
area_name6: "新增数据开始6",
statis_date: 100007,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据",
area_name1: "新增数据1",
area_name2: "新增数据2",
area_name3: "新增数据3",
area_name4: "新增数据4",
area_name5: "新增数据5",
area_name6: "新增数据6",
statis_date: 201807,
},
{
area_name: "新增数据最后",
area_name1: "新增数据最后1",
area_name2: "新增数据最后2",
area_name3: "新增数据最后3",
area_name4: "新增数据最后4",
area_name5: "新增数据最后5",
area_name6: "新增数据最后6",
statis_date: 222222,
}
]
}
},
filters: {
dateFromt: function (value) {
if (!value) return ''
value = value.toString()
return value.slice(4)
},
},
methods: {
// 返回
vdVal(val, value) {
return value
},
// 是否包含 % 标志,有就要颜色控制
validateVal(value) {
let flag = false
this.xList.forEach((e, i) => {
if (e.zd_name == value) {
if (e.zx_name.includes('%')) {
flag = true
}
}
})
return flag
},
$$(dom){
return document.getElementById(dom)
},
savePosition(){
this.maxHeight = window.screen.height
this.$$("pages").onscroll = (()=> {
let offsetHeight = this.$$("fixedHeaderCenter").offsetHeight
let scrollTop = offsetHeight + 1 - this.$$("pages").scrollTop
this.fixedTheadLeft = - this.$$("pages").scrollLeft + 'px'
this.fixedHeaderCloFirstTop = scrollTop + 'px'
console.log("scrollTop:",scrollTop)
console.log("this.fixedHeaderCloFirstTop:",this.fixedHeaderCloFirstTop)
});
// this.$$("fixedHeaderCloFirst").onscroll = (()=> {
// let offsetHeight = this.$$("fixedHeaderCenter").offsetHeight
// let scrollTop = - this.$$("fixedHeaderCloFirst").scrollTop
// this.$$("pages").style.left = - this.$$("fixedHeaderCloFirst").scrollLeft + 'px'
// this.$$("table").style.top = scrollTop + 'px'
// });
}
},
mounted() {
setTimeout(()=>{
this.firstCloWidth = document.getElementsByClassName("firstCol")[0].offsetWidth
this.firstCloHeight = document.getElementsByClassName("firstCol")[0].offsetHeight-1
this.fixedHeaderCloFirstHeight = this.$$("tbody").offsetHeight + 'px'
this.cloFirstLineHeight = this.$$("tbody").children[0].offsetHeight + 'px'
this.fixedHeaderCloFirstTop = this.firstCloHeight + 3 + 'px'
this.showFixedHeaderCloFirst = true
this.savePosition()
},1000)
},
}
</script>
<style lang="less" scoped>
::-webkit-scrollbar {
display: none;
}
.pages{
overflow: scroll;
height: 100%;
}
.fixedHeaderCenter{
border: 1px solid red;
background-color: #f3f4f6;
color: #43484d;
text-align: center;
// padding: 0 0.3rem;
position: fixed;
left: 0;
top: 0;
z-index: 9999;
}
.fixedHeaderCloFirst{
// border-bottom: 1px solid #eee;
height: 100%;
line-height: 0.86rem;
background: #fff;
white-space: nowrap;
text-align: center;
position: fixed;
left: 0;
top: 0;
th,td{
padding: 0;
}
// overflow: scroll;
div{
background-color: #fff;
border-bottom: 1px solid #eee;
}
}
@main-color-green: #269513;
@main-color-yellow: #fc9d2e;
table {
position: relative;
color: #86939e;
font-size: 0.32rem;
border: 0px solid #000;
min-height: 100%;
text-align: center;
white-space:nowrap;
td {
border-bottom: 1px solid #eee;
white-space: nowrap;
height: 0.86rem;
line-height: 0.86rem;
padding: 0 0.2rem;
white-space:nowrap;
}
th {
white-space:nowrap;
color: #43484d;
white-space: nowrap;
height: 0.74rem;
line-height: 0.74rem;
padding: 0rem 0.3rem;
background-color: #f3f4f6;
font-weight: normal;
padding-bottom: 0;
padding-top: 0;
border: 1px solid red;
}
}
.tables-content-item-green {
color: @main-color-green;
}
.tables-content-item-yellow {
color: @main-color-yellow;
}
table {
font-size: 0.3rem;
// margin: 300px;
border-collapse:collapse
}
.fixedThead{
background: lightblue;
position: fixed;
top: 0 ;
z-index: 2;
}
/*固定表头的样式*/
.fixedHeader {
background: lightblue;
position: fixed;
top: 0 ;
z-index: 2;
}
</style>
最终效果图如下:
不过这个版本的上下滚动时的精准计算有点误差。
推荐第一种方式。
最后
希望文章内容对你有一点帮助!
对 全栈修炼 有兴趣的朋友可以扫下方二维码关注我的公众号
我会不定期更新有价值的内容,长期运营。
关注公众号并回复 福利 可领取免费学习资料,福利详情请猛戳: Python、Java、Linux、Go、node、vue、react、javaScript
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。