公司有了新的需要,就是须要一个头部固定的表格,查来查去,都感觉很麻烦,罗唆本人写一个好了
如第一幅图所示,成果很好,因为宽度是由浏览器窗口变动的时候通过js计算取得,css仅仅只是设置局部的最小宽度,所以兼容性必定是没有任何问题的。
首先要明确的就是,既然头部须要固定,那么头部和身材必定是分成两个表格来做的,构造如下
<div> <div class="table1"> <table></table> </div> <div class="table2"> <table></table> </div></div>
而后问题来了,因为是两个table,那么他们的td的宽度是由各自的内容决定的,天然宽度在不通过人为操纵的状况是相对不可能一样的。既然如此,那通过同一个对象治理两个表格,那么宽度天然就雷同了。
先看ts代码内容
tabHead: Array<any> = [ { title: '操作', property: 'checkbox', type: 'checkbox', width: '' }, { title: '序号', property: 'serial', type: 'serial', width: '' }, { title: '信息类型', property: 'infoType', type: 'special', children: 'infoTypeChildren', param: 'infoTypeCode', width: '', fackItem: 'a' }, { title: '服务名称', property: 'serviceName', type: 'special', children: 'serviceChildren', param: 'serviceId', width: '', fackItem: 'b' }, { title: "数据起源", property: 'sourceName', type: 'special', children: 'sourceChildren', param: 'dataSourceId', width: '', fackItem: 'c' }, { title: "服务版本", property: 'serviceVersion', width: '' }, { title: "服务形容", property: 'description', width: '' }, { title: "注册单位", property: 'register', width: '' }, { title: "注册工夫", property: 'registerDate', width: '' }, { title: "服务状态", property: 'status', type: 'state', width: '' }, ]
下面的是两个table共用的对象,其余的字段能够不必理,只须要看title property width
三个字段就行
再看html代码内容
<div class="table1"> <table class="service-table" > <tr class="head"> <ng-container *ngFor="let item of tabHead"> <td [ngStyle]="{'width':item.width}" class="{{item.property}}"> {{item.title}} </td> </ng-container> </tr> </table> </div>
这个是头部表格的简化后的代码,利用angular的*ngFor
属性,遍历tabHead
循环出td
并且给td
的款式width
设置为tabHead
中width
的值。
<div class="table2" > <table class="service-table"> <tr *ngFor="let data of tabData;let i = index" #element> <ng-container *ngFor="let item of tabHead"> <td [ngStyle]="{'width':item.width}" class="{{item.property}}"> <span [class]="item.class" [style]="item.style" [innerHTML]="data[item.property]?data[item.property]:'--'" [title]="data[item.property]?data[item.property]:'--'"></span> </td> </ng-container> </tr> </table> </div>
同样,这个是身材表格简化后的代码,同样利用angular的*ngFor
属性,遍历tabHead
循环出td
并且给td
的款式width
设置为tabHead
中width
的值。不过外层加了一层tableData
的循环,其字段如下
export class ServiceContentListModel { dataSourceId?: string; sourceChildren?:Array<any>; description?: string; id?: string; infoType?: string; infoTypeCode?: string; register?: string; registerDate?: string; serialNumber?: number; serviceId?: string; serviceName?: string; serviceVersion?: string; sourceName?: string; status?: string; noneed?:boolean=false;}
简而言之就是tabHead
的property
会对应tableData
的字段,而后把对应上的显示到页面上。具体不表
这样一番操作,能够想到两张表格中td
的宽度都是由同一个对象tableHead
中的width
属性决定的了,那么接下来只有通过拿到身材表格每一个td
的宽度,而后赋值给tabHead
就行了。
//因为我应用的是angular,所以以下代码带有angular的个性,当然情理是相通的,用vue甚至用原生js写法略微变通一下//也是能够实现的@ViewChild('element') navListElement: ElementRef;//拿到tr的dom元素 ngAfterViewInit() {//在子元素加载实现后执行 this.setWidth() window.onresize = ($event) => {//浏览器窗口大小变动当前执行 this.setWidth() } } setWidth() { setTimeout(() => {//提早一个生命周期后进行,不然在页面渲染实现当前表格还是对不齐状态 if (this.navListElement) { let children = this.navListElement.nativeElement.children;//拿到一个tr中所有td的汇合 let widthSum = 0//寄存一个tr中所有td的宽度,用于计算每个td所占的百分比 for (let i = 0; i < this.tabHead.length; i++) {//每一列宽度换算成像素宽度(除了最初一列) let item = children[i] // this.tabHead[i]['width'] = item.offsetWidth + "px" widthSum+=item.offsetWidth } for (let i = 0; i < this.tabHead.length; i++) {//每一列宽度换算成百分比(除了最初一列) let item = children[i] this.tabHead[i]['width'] = (item.offsetWidth/widthSum)*100 + '%' } } }); }
这样就实现了,具体点的工作,比方设置最小宽度之类的,间接在css外面设置就行。