先看效果圖
效果圖.gif
第一步:引入 iscroll
npm i iscroll --save
第二步:封裝
對插件再做一層封裝,封裝成 iscrollTable.js 方便調(diào)用节芥,代碼如下:
// 統(tǒng)一使用
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 滾動不繁忙的時候觸發(fā) probeType : 2 滾動時每隔一定時間觸發(fā) probeType : 3 每滾動一像素觸發(fā)一次
mouseWheel: true, // 是否監(jiān)聽鼠標滾輪事件在刺。
scrollX: true, // 啟動x軸滑動
scrollY: true, // 啟動y軸滑動
// momentum: false,
lockDirection: false,
snap: false, // 自動分割容器逆害,用于制作走馬燈效果等。Options.snap:true// 根據(jù)容器尺寸自動分割
// snapSpeed: 400,
scrollbars: false, // 是否顯示默認滾動條
freeScroll: true, // 主要在上下左右滾動都生效時使用蚣驼,可以向任意方向滾動魄幕。
deceleration: 0.0001, // 滾動動量減速越大越快,建議不大于 0.01,默認:0.0006
disableMouse: true, // 是否關(guān)閉鼠標事件探測颖杏。如知道運行在哪個平臺纯陨,可以開啟它來加速。
disablePointer: true, // 是否關(guān)閉指針事件探測留储。如知道運行在哪個平臺翼抠,可以開啟它來加速。
disableTouch: false, // 是否關(guān)閉觸摸事件探測获讳。如知道運行在哪個平臺阴颖,可以開啟它來加速。
eventPassthrough: false, // 使用 IScroll 的橫軸滾動時丐膝,如想使用系統(tǒng)立軸滾動并在橫軸上生效量愧,請開啟。
bounce: false, // 是否啟用彈力動畫效果帅矗,關(guān)掉可以加速
});
function updatePosition() {
const frozenCols = document.querySelectorAll(`${selector} table tr td.cols`);
const frozenRows = document.querySelectorAll(`${selector} table tr th.rows`);
const 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)`;
}
}
scroller.on('scroll', updatePosition);
scroller.on('scrollEnd', updatePosition);
scroller.on('beforeScrollStart', () => {
scroller.refresh();
});
return scroller;
}
export function refreshScroller() {
if (scroller === null) {
console.error('先初始化scroller');
return;
}
setTimeout(() => {
scroller.refresh();
scroller.scrollTo(0, 0);
const frozenCols = document.querySelectorAll(`${Selector} table tr td.cols`);
const frozenRows = document.querySelectorAll(`${Selector} table tr th.rows`);
const 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);
}
export function destroyScroller() {
if (scroller === null) {
return;
}
scroller.destroy();
scroller = null;
}
第三步:頁面使用
引用前面的自己封裝的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" >
<template v-for="(ll,yKey) in l">
<td :key="xKey+yKey" v-if="x === yKey" :class="{'cols': yKey == xField[0]|| yKey == xField[1]}">
{{ yList[i][yKey]}}
</td>
</template>
</template>
</tr>
<tr></tr>
</table>
</div>
</div>
</template>
<script>
//demo中沒有用到refreshScroller,當需要刷新回到頁面頂部時調(diào)用
import { createIScroller, refreshScroller, destroyScroller } from "libs/iscrollTable";
export default {
data() {
return {
maxHeight:'100%',
scroll: {
scroller: null
},
xList: [
[
{
field_name: "statis_date",
name: "第一行合并3行1列",
colspan: 1, //指定單元格 橫向 跨越的 列數(shù)
rowspan: 3, //指定單元格 縱向 跨越的 行數(shù)
},
{
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, //指定單元格 橫向 跨越的 列數(shù)
rowspan: 1, //指定單元格 縱向 跨越的 行數(shù)
},
{
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, //指定單元格 橫向 跨越的 列數(shù)
rowspan: 1, //指定單元格 縱向 跨越的 行數(shù)
},
{
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: "新增數(shù)據(jù)開始",
area_name1: "新增數(shù)據(jù)開始1",
area_name2: "新增數(shù)據(jù)開始2",
area_name3: "新增數(shù)據(jù)開始3",
area_name4: "新增數(shù)據(jù)開始4",
area_name5: "新增數(shù)據(jù)開始5",
area_name6: "新增數(shù)據(jù)開始6",
statis_date: 100007,
},
{
area_name: "新增數(shù)據(jù)",
area_name1: "新增數(shù)據(jù)1",
area_name2: "新增數(shù)據(jù)2",
area_name3: "新增數(shù)據(jù)3",
area_name4: "新增數(shù)據(jù)4",
area_name5: "新增數(shù)據(jù)5",
area_name6: "新增數(shù)據(jù)6",
statis_date: 201807,
},
{
area_name: "新增數(shù)據(jù)",
area_name1: "新增數(shù)據(jù)1",
area_name2: "新增數(shù)據(jù)2",
area_name3: "新增數(shù)據(jù)3",
area_name4: "新增數(shù)據(jù)4",
area_name5: "新增數(shù)據(jù)5",
area_name6: "新增數(shù)據(jù)6",
statis_date: 201807,
},
{
area_name: "新增數(shù)據(jù)",
area_name1: "新增數(shù)據(jù)1",
area_name2: "新增數(shù)據(jù)2",
area_name3: "新增數(shù)據(jù)3",
area_name4: "新增數(shù)據(jù)4",
area_name5: "新增數(shù)據(jù)5",
area_name6: "新增數(shù)據(jù)6",
statis_date: 201807,
},
{
area_name: "新增數(shù)據(jù)",
area_name1: "新增數(shù)據(jù)1",
area_name2: "新增數(shù)據(jù)2",
area_name3: "新增數(shù)據(jù)3",
area_name4: "新增數(shù)據(jù)4",
area_name5: "新增數(shù)據(jù)5",
area_name6: "新增數(shù)據(jù)6",
statis_date: 201807,
},
{
area_name: "新增數(shù)據(jù)",
area_name1: "新增數(shù)據(jù)1",
area_name2: "新增數(shù)據(jù)2",
area_name3: "新增數(shù)據(jù)3",
area_name4: "新增數(shù)據(jù)4",
area_name5: "新增數(shù)據(jù)5",
area_name6: "新增數(shù)據(jù)6",
statis_date: 201807,
},
{
area_name: "新增數(shù)據(jù)",
area_name1: "新增數(shù)據(jù)1",
area_name2: "新增數(shù)據(jù)2",
area_name3: "新增數(shù)據(jù)3",
area_name4: "新增數(shù)據(jù)4",
area_name5: "新增數(shù)據(jù)5",
area_name6: "新增數(shù)據(jù)6",
statis_date: 201807,
},
{
area_name: "新增數(shù)據(jù)",
area_name1: "新增數(shù)據(jù)1",
area_name2: "新增數(shù)據(jù)2",
area_name3: "新增數(shù)據(jù)3",
area_name4: "新增數(shù)據(jù)4",
area_name5: "新增數(shù)據(jù)5",
area_name6: "新增數(shù)據(jù)6",
statis_date: 201807,
},
{
area_name: "新增數(shù)據(jù)",
area_name1: "新增數(shù)據(jù)1",
area_name2: "新增數(shù)據(jù)2",
area_name3: "新增數(shù)據(jù)3",
area_name4: "新增數(shù)據(jù)4",
area_name5: "新增數(shù)據(jù)5",
area_name6: "新增數(shù)據(jù)6",
statis_date: 201807,
},
{
area_name: "新增數(shù)據(jù)",
area_name1: "新增數(shù)據(jù)1",
area_name2: "新增數(shù)據(jù)2",
area_name3: "新增數(shù)據(jù)3",
area_name4: "新增數(shù)據(jù)4",
area_name5: "新增數(shù)據(jù)5",
area_name6: "新增數(shù)據(jù)6",
statis_date: 201807,
},
{
area_name: "新增數(shù)據(jù)",
area_name1: "新增數(shù)據(jù)1",
area_name2: "新增數(shù)據(jù)2",
area_name3: "新增數(shù)據(jù)3",
area_name4: "新增數(shù)據(jù)4",
area_name5: "新增數(shù)據(jù)5",
area_name6: "新增數(shù)據(jù)6",
statis_date: 201807,
},
{
area_name: "新增數(shù)據(jù)",
area_name1: "新增數(shù)據(jù)1",
area_name2: "新增數(shù)據(jù)2",
area_name3: "新增數(shù)據(jù)3",
area_name4: "新增數(shù)據(jù)4",
area_name5: "新增數(shù)據(jù)5",
area_name6: "新增數(shù)據(jù)6",
statis_date: 201807,
},
{
area_name: "新增數(shù)據(jù)",
area_name1: "新增數(shù)據(jù)1",
area_name2: "新增數(shù)據(jù)2",
area_name3: "新增數(shù)據(jù)3",
area_name4: "新增數(shù)據(jù)4",
area_name5: "新增數(shù)據(jù)5",
area_name6: "新增數(shù)據(jù)6",
statis_date: 201807,
},
{
area_name: "新增數(shù)據(jù)",
area_name1: "新增數(shù)據(jù)1",
area_name2: "新增數(shù)據(jù)2",
area_name3: "新增數(shù)據(jù)3",
area_name4: "新增數(shù)據(jù)4",
area_name5: "新增數(shù)據(jù)5",
area_name6: "新增數(shù)據(jù)6",
statis_date: 201807,
},
{
area_name: "新增數(shù)據(jù)",
area_name1: "新增數(shù)據(jù)1",
area_name2: "新增數(shù)據(jù)2",
area_name3: "新增數(shù)據(jù)3",
area_name4: "新增數(shù)據(jù)4",
area_name5: "新增數(shù)據(jù)5",
area_name6: "新增數(shù)據(jù)6",
statis_date: 201807,
},
{
area_name: "新增數(shù)據(jù)",
area_name1: "新增數(shù)據(jù)1",
area_name2: "新增數(shù)據(jù)2",
area_name3: "新增數(shù)據(jù)3",
area_name4: "新增數(shù)據(jù)4",
area_name5: "新增數(shù)據(jù)5",
area_name6: "新增數(shù)據(jù)6",
statis_date: 201807,
},
{
area_name: "新增數(shù)據(jù)",
area_name1: "新增數(shù)據(jù)1",
area_name2: "新增數(shù)據(jù)2",
area_name3: "新增數(shù)據(jù)3",
area_name4: "新增數(shù)據(jù)4",
area_name5: "新增數(shù)據(jù)5",
area_name6: "新增數(shù)據(jù)6",
statis_date: 201807,
},
{
area_name: "新增數(shù)據(jù)",
area_name1: "新增數(shù)據(jù)1",
area_name2: "新增數(shù)據(jù)2",
area_name3: "新增數(shù)據(jù)3",
area_name4: "新增數(shù)據(jù)4",
area_name5: "新增數(shù)據(jù)5",
area_name6: "新增數(shù)據(jù)6",
statis_date: 201807,
},
{
area_name: "新增數(shù)據(jù)",
area_name1: "新增數(shù)據(jù)1",
area_name2: "新增數(shù)據(jù)2",
area_name3: "新增數(shù)據(jù)3",
area_name4: "新增數(shù)據(jù)4",
area_name5: "新增數(shù)據(jù)5",
area_name6: "新增數(shù)據(jù)6",
statis_date: 201807,
},
{
area_name: "新增數(shù)據(jù)最后",
area_name1: "新增數(shù)據(jù)最后1",
area_name2: "新增數(shù)據(jù)最后2",
area_name3: "新增數(shù)據(jù)最后3",
area_name4: "新增數(shù)據(jù)最后4",
area_name5: "新增數(shù)據(jù)最后5",
area_name6: "新增數(shù)據(jù)最后6",
statis_date: 222222,
}
]
}
},
mounted() {
this.maxHeight = window.screen.height
this.scroll.scroller = createIScroller(".meal-table");
// addWaterMarker(document.getElementById('watermark'))
},
beforeDestroy() {
destroyScroller();
},
}
</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; //去掉重復(fù)的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>
注意:
如果頁面中需要多個列固定损晤,參考下圖:
image.png
如果幫組到您软棺,請舉小手手贊一下,筆芯 ???