转载请注明出处:
http://blog.youkuaiyun.com/lishihong108/article/details/52712064
由于移动端屏幕有限,在展示多行多列的表格类型数据时,需要做成可滚动的来展示,但是滚动的时候,我们需要表头和第一列固定,以便在滚动的时候,可以看到该行、该列所属。如图所示:
在横向滚动的时候,第一列[地区]保持不动,方便用户查看所属地区;纵向滚动时候,表头保持不动。
具体实现,先将这个布局划分为4部分,如下:
第一个部分就是个简单的单元格,绿色部分是一个横向滚动区域,蓝色部分是一个纵向滚动区域,紫色部分是即可纵向又可横向滚动的区域。接下来就是用ionic自带的组件ion-scroll来实现4部分布局,然后再根据滑动的方向判断。当横向滑动紫色部分x距离,则绿色部分跟着滑动x距离;当纵向滑动紫色部分y距离,则蓝色部分跟着滑动y距离。接下来看代码具体实现,在布局上有一点要注意的是,要保持这个表格的协调,每个单元格要固定宽高度。
单元格css样式代码:
<style type="text/css">
.head{
border-bottom:solid 1px #D1D3D6;
border-right:solid 1px #D1D3D6;
height:50px;
display:flex;
align-items:center;
width:125px;
font-size:14px;
color:#262626;
justify-content:center;
}
</style>
页面代码:
<ion-view view-title="表格首行首列固定">
<ion-content overflow-scroll="false">
<div style="display:flex;width:625px;">
<div class="head">地区</div>
<div style="overflow: hidden;white-space: nowrap;width:250px;">
<ion-scroll direction="x" scrollbar-x="false" overflow-scroll="false" has-bouncing="false" delegate-handle="headContainerHandle" on-scroll="noScroll()" style="margin-top:0;">
<div style="display:flex;width:500px;">
<div class="head">到件量</div>
<div class="head">出仓量</div>
<div class="head">滞留量</div>
<div class="head" style="border-right:0;">未派送量</div>
</div>
</ion-scroll>
</div>
</div>
<div style="display:flex;width:625px;">
<ion-scroll direction="y" scrollbar-y="false" overflow-scroll="false" has-bouncing="false" delegate-handle="leftContainerHandle" on-scroll="noScroll()" style="height:{{h}}px;">
<div ng-repeat="d in data" class="head">
{{d.zoneName}}
</div>
</ion-scroll>
<div style="overflow: hidden;white-space: nowrap;width:250px;">
<ion-scroll direction="xy" scrollbar-x="false" scrollbar-y="false" overflow-scroll="false" has-bouncing="false" on-scroll="scrollRightHorizon()" delegate-handle="rightContainerHandle" style="height:{{h}}px;">
<div style="width:500px;">
<div ng-repeat="d in data" style="display:flex;">
<div class="head">
{{d.arriveTickets}}
</div>
<div class="head">
{{d.moniOutCnt}}
</div>
<div class="head">
{{d.moniStayCnt}}
</div>
<div class="head" style="border-right:0;">
{{d.moniUndeliveryCnt}}
</div>
</div>
</div>
</ion-scroll>
</div>
</div>
</ion-content>
</ion-view>
controller里面的代码:
$scope.data=[
{'zoneName':'广州区','arriveTickets':'6987','moniOutCnt':'2221','moniStayCnt':'45','moniUndeliveryCnt':'44'},
{'zoneName':'深圳区','arriveTickets':'2356','moniOutCnt':'331','moniStayCnt':'45','moniUndeliveryCnt':'44'},
{'zoneName':'武汉区','arriveTickets':'6744','moniOutCnt':'2621','moniStayCnt':'45','moniUndeliveryCnt':'44'},
{'zoneName':'苏州区','arriveTickets':'6542','moniOutCnt':'2881','moniStayCnt':'45','moniUndeliveryCnt':'44'},
{'zoneName':'杭州区','arriveTickets':'2367','moniOutCnt':'5621','moniStayCnt':'45','moniUndeliveryCnt':'44'},
{'zoneName':'东莞区','arriveTickets':'1129','moniOutCnt':'1221','moniStayCnt':'45','moniUndeliveryCnt':'44'},
{'zoneName':'惠州区','arriveTickets':'7893','moniOutCnt':'4521','moniStayCnt':'45','moniUndeliveryCnt':'44'},
{'zoneName':'汕头区','arriveTickets':'2356','moniOutCnt':'7821','moniStayCnt':'45','moniUndeliveryCnt':'44'},
{'zoneName':'清远区','arriveTickets':'67554','moniOutCnt':'9921','moniStayCnt':'45','moniUndeliveryCnt':'44'},
{'zoneName':'长沙区','arriveTickets':'5534','moniOutCnt':'2221','moniStayCnt':'45','moniUndeliveryCnt':'44'},
{'zoneName':'岳阳区','arriveTickets':'6643','moniOutCnt':'2221','moniStayCnt':'45','moniUndeliveryCnt':'44'},
{'zoneName':'株洲区','arriveTickets':'6546','moniOutCnt':'2221','moniStayCnt':'45','moniUndeliveryCnt':'44'},
{'zoneName':'南充区','arriveTickets':'4353','moniOutCnt':'2221','moniStayCnt':'45','moniUndeliveryCnt':'44'},
{'zoneName':'鞍山区','arriveTickets':'4526','moniOutCnt':'2221','moniStayCnt':'45','moniUndeliveryCnt':'44'}
];
$scope.h=Math.min(document.documentElement.clientHeight,window.innerHeight)-44-50;
$scope.scrollRightHorizon=function(){
var rightHandle = $ionicScrollDelegate.$getByHandle("rightContainerHandle");
var headHandle = $ionicScrollDelegate.$getByHandle("headContainerHandle");
var leftHandle = $ionicScrollDelegate.$getByHandle("leftContainerHandle");
headHandle.scrollTo(rightHandle.getScrollPosition().left,0,false);
leftHandle.scrollTo(0,rightHandle.getScrollPosition().top,false);
};
$scope.noScroll=function(){
var headHandle = $ionicScrollDelegate.$getByHandle("headContainerHandle");
headHandle.freezeScroll(true);
var leftHandle = $ionicScrollDelegate.$getByHandle("leftContainerHandle");
leftHandle.freezeScroll(true);
};
controller里面, s c o p e . d a t a 是 数 据 , scope.data是数据, scope.data是数据,scope.h是通过屏幕的高度-减去标题栏的高度44-表头的高度50,然后把这个高度设置给纵向滚动的ion-scroll的高度。on-scroll事件是ion-scroll组件滚动的时候触发的,当紫色部分横向滚动时候,调整绿色部分滚动组件的横向滚动;当紫色部分纵向滚动时候,调整蓝色部分的滚动组件的纵向滚动;之所以绿色部分和蓝色部分滚动组件的滚动是为了防止滚动时候不断的相互触发滚动,引起冲突,也造成了该方案的一个缺点,就是必须手在紫色部分才可以操作滑动。