前端时间移动端在做表格的时候需要这个功能,由于还有实现类似原生的惯性滚动功能,于是使用了iscroll插件。
iscroll插件下载地址:iscroll5
该功能demo github地址: https://github.com/lyc152/front-special-effects/tree/master/table-fixed
下面看下代码结构:
HTML:
1 <div class="data-table">
2 <div class="t_l">
3 <table>
4 <tbody>
5 <tr>
6 <th>品类</th>
7 </tr>
8 </tbody>
9 </table>
10 <div class="t_l_freeze" id="t_l_freeze">
11 <table>
12 <tr>
13 <td>品类</td>
14 </tr>
15 <tr>
16 <td>男鞋</td>
17 </tr>
18 <tr>
19 <td>男鞋</td>
20 </tr>
21 <tr>
22 <td>男鞋</td>
23 </tr>
24 <tr>
25 <td>男鞋</td>
26 </tr>
27 <tr>
28 <td>男鞋</td>
29 </tr>
30 <tr>
31 <td>男鞋</td>
32 </tr>
33 <tr>
34 <td>男鞋</td>
35 </tr>
36 <tr>
37 <td>男鞋</td>
38 </tr>
39 <tr>
40 <td>男鞋</td>
41 </tr>
42 <tr>
43 <td>男鞋</td>
44 </tr>
45 <tr>
46 <td>男鞋</td>
47 </tr>
48 <tr>
49 <td>男鞋</td>
50 </tr>
51 <tr>
52 <td>男鞋</td>
53 </tr>
54 <tr>
55 <td>男鞋</td>
56 </tr>
57 <tr>
58 <td>男鞋</td>
59 </tr>
60 <tr>
61 <td>男鞋</td>
62 </tr>
63 </table>
64 </div>
65 </div>
66 <div class="t_r">
67 <div class="t_r_t" id="t_r_t">
68 <table>
69 <tbody>
70 <tr>
71 <th>1</th>
72 <th>2</th>
73 <th>3</th>
74 <th>4</th>
75 <th>5</th>
76 <th>6</th>
77 <th>7</th>
78 <th>8</th>
79 <th>9</th>
80 </tr>
81 </tbody>
82 </table>
83 </div>
84 <div class="t_r_content" id="t_r_content">
85 <table>
86 <tbody>
87 <tr>
88 <td>1</td>
89 <td>2</td>
90 <td>3</td>
91 <td>4</td>
92 <td>5</td>
93 <td>6</td>
94 <td>7</td>
95 <td>8</td>
96 <td>9</td>
97 </tr>
98 <tr>
99 <td>1</td>
100 <td>2</td>
101 <td>3</td>
102 <td>4</td>
103 <td>5</td>
104 <td>6</td>
105 <td>7</td>
106 <td>8</td>
107 <td>9</td>
108 </tr>
109 <tr>
110 <td>1</td>
111 <td>2</td>
112 <td>3</td>
113 <td>4</td>
114 <td>5</td>
115 <td>6</td>
116 <td>7</td>
117 <td>8</td>
118 <td>9</td>
119 </tr>
120 <tr>
121 <td>1</td>
122 <td>2</td>
123 <td>3</td>
124 <td>4</td>
125 <td>5</td>
126 <td>6</td>
127 <td>7</td>
128 <td>8</td>
129 <td>9</td>
130 </tr>
131 <tr>
132 <td>1</td>
133 <td>2</td>
134 <td>3</td>
135 <td>4</td>
136 <td>5</td>
137 <td>6</td>
138 <td>7</td>
139 <td>8</td>
140 <td>9</td>
141 </tr>
142 <tr>
143 <td>1</td>
144 <td>2</td>
145 <td>3</td>
146 <td>4</td>
147 <td>5</td>
148 <td>6</td>
149 <td>7</td>
150 <td>8</td>
151 <td>9</td>
152 </tr>
153 <tr>
154 <td>1</td>
155 <td>2</td>
156 <td>3</td>
157 <td>4</td>
158 <td>5</td>
159 <td>6</td>
160 <td>7</td>
161 <td>8</td>
162 <td>9</td>
163 </tr>
164 <tr>
165 <td>1</td>
166 <td>2</td>
167 <td>3</td>
168 <td>4</td>
169 <td>5</td>
170 <td>6</td>
171 <td>7</td>
172 <td>8</td>
173 <td>9</td>
174 </tr>
175 <tr>
176 <td>1</td>
177 <td>2</td>
178 <td>3</td>
179 <td>4</td>
180 <td>5</td>
181 <td>6</td>
182 <td>7</td>
183 <td>8</td>
184 <td>9</td>
185 </tr>
186 <tr>
187 <td>1</td>
188 <td>2</td>
189 <td>3</td>
190 <td>4</td>
191 <td>5</td>
192 <td>6</td>
193 <td>7</td>
194 <td>8</td>
195 <td>9</td>
196 </tr>
197 <tr>
198 <td>1</td>
199 <td>2</td>
200 <td>3</td>
201 <td>4</td>
202 <td>5</td>
203 <td>6</td>
204 <td>7</td>
205 <td>8</td>
206 <td>9</td>
207 </tr>
208 <tr>
209 <td>1</td>
210 <td>2</td>
211 <td>3</td>
212 <td>4</td>
213 <td>5</td>
214 <td>6</td>
215 <td>7</td>
216 <td>8</td>
217 <td>9</td>
218 </tr>
219 <tr>
220 <td>1</td>
221 <td>2</td>
222 <td>3</td>
223 <td>4</td>
224 <td>5</td>
225 <td>6</td>
226 <td>7</td>
227 <td>8</td>
228 <td>9</td>
229 </tr>
230 <tr>
231 <td>1</td>
232 <td>2</td>
233 <td>3</td>
234 <td>4</td>
235 <td>5</td>
236 <td>6</td>
237 <td>7</td>
238 <td>8</td>
239 <td>9</td>
240 </tr>
241 <tr>
242 <td>1</td>
243 <td>2</td>
244 <td>3</td>
245 <td>4</td>
246 <td>5</td>
247 <td>6</td>
248 <td>7</td>
249 <td>8</td>
250 <td>9</td>
251 </tr>
252 <tr>
253 <td>1</td>
254 <td>2</td>
255 <td>3</td>
256 <td>4</td>
257 <td>5</td>
258 <td>6</td>
259 <td>7</td>
260 <td>8</td>
261 <td>9</td>
262 </tr>
263 <tr>
264 <td>1</td>
265 <td>2</td>
266 <td>3</td>
267 <td>4</td>
268 <td>5</td>
269 <td>6</td>
270 <td>7</td>
271 <td>8</td>
272 <td>9</td>
273 </tr>
274 </tbody>
275 </table>
276 </div>
277 </div>
278 </div>
table-fixed
实现表头和首列固定比较简单,可以将可以滚动的content容器的scrollTop和scrollLeft值分别赋值给锁定表列容器的scrollTop和锁定表头的scrollLeft。即:
1 function aa() {
2 var a = document.getElementById("t_r_content").scrollTop;
3 var b = document.getElementById("t_r_content").scrollLeft;
4 document.getElementById("cl_freeze").scrollTop = a;
5 document.getElementById("t_r_t").scrollLeft = b;
6 }
但是实现 惯性滚动 中还要 固定表头和表列就要麻烦些:
1 var win = $(window),
2 scrollAreaEl = $('.t_r_content'),
3 leftFreezeEl = $('.t_l_freeze'),
4 leftTableEl = leftFreezeEl.find('table'),
5 rightTableEl = $('.t_r_t table');
6
7 //动态计算容器最大高度
8 function adjustHeight() {
9 var winHeight = win.height(),
10 tableHeight = winHeight - 90;
11 leftFreezeEl.height(tableHeight);
12 scrollAreaEl.height(tableHeight);
13 }
14
15 adjustHeight();
16 win.on('resize', adjustHeight);
17
18 //设置iscroll
19 var myScroll = new IScroll('.t_r_content', {
20 scrollX: true,
21 scrollY: true,
22 probeType: 3
23 });
24
25 //阻止默认滚动
26 scrollAreaEl.on('touchmove mousewheel', function(e) {
27 e.preventDefault();
28 });
29
30 //固定上左表头的滚动
31 myScroll.on('scroll', updatePosition);
32 myScroll.on('scrollEnd', updatePosition);
33
34 function updatePosition() {
35 var a = this.y;
36 var b = this.x;
37 leftTableEl.css('transform', 'translate(0px, ' + a + 'px) translateZ(0px)');
38 rightTableEl.css('transform', 'translate(' + b + 'px, 0px) translateZ(0px)');
39 }
main.js
实现步骤
1.引用 iscroll-probe.js 插件
2. 动态计算容器的最大高度,当resize的时候重新计算容器的最大高度;
3. 设置iscroll;
4. 阻止可滚动部分content的默认滚动;
5. 阻止上左表头的滚动,需要引用iscroll 中的 scroll,scrollEnd,要阻止表头和表列的滚动 ,就需要计算滚动的x和y值,更新leftTable和rightTable的transform的值就可以做到了。
当然,可以实现这个功能的方法很多