首页 > 代码库 > 原生javascript 固定表头原理与源码

原生javascript 固定表头原理与源码

    我在工作中需要固定表头这个功能,我不想去找,没意思。于是就写了一个,我写的是angularjs 自定义指令 起了个 "fix-header" 有人叫  “freeze-header” ,算了,看心情吧,最近心情不太好就不改了~~~

想了想,我还是改成原生吧,angularjs就是个毛毛~~~。

先讲一下思路:

    1.想一想,再想一想,肯定用定位了,具体是绝对定位还是固定定位,看实际情况;

    2.clone 一份thead元素,用于再创建一个定位的表头;

    3.clone有点坑,不能clone当前元素的 实际 宽高 和 事件, 只能获取原先的加上;

    4.加scroll事件;

    5.我很开心,成功了~~~~;

先把页面创建了 ,就叫fixHeaderDemo.html,如下:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6     <style>
 7         *{box-sizing: border-box;}
 8         .table{max-width: 100%; width: 100%;border-collapse: collapse;}
 9         .table>thead>tr>th{background-color: #059ca1; color:#FFF; padding-top:10px;padding-bottom: 10px;}
10         .table>thead>tr>th,.table>tbody>tr>td{
11             border:1px solid #CCC;
12         }
13     </style>
14 </head>
15 <body>
16 <div style="width: 80%; margin:40px auto; height: 100px;overflow: auto;position: relative;">
17     <table class="table">
18         <thead>
19         <tr>
20             <th>Name</th>
21             <th>Age</th>
22             <th>Address</th>
23         </tr>
24         </thead>
25         <tbody>
26         <tr>
27             <td>亚瑟</td>
28             <td>荆轲</td>
29             <td>程咬金</td>
30         </tr><tr>
31             <td>亚瑟</td>
32             <td>荆轲</td>
33             <td>程咬金</td>
34         </tr><tr>
35             <td>亚瑟</td>
36             <td>荆轲</td>
37             <td>程咬金</td>
38         </tr><tr>
39             <td>亚瑟</td>
40             <td>荆轲</td>
41             <td>程咬金</td>
42         </tr><tr>
43             <td>亚瑟</td>
44             <td>荆轲</td>
45             <td>程咬金</td>
46         </tr><tr>
47             <td>亚瑟</td>
48             <td>荆轲</td>
49             <td>程咬金</td>
50         </tr><tr>
51             <td>亚瑟</td>
52             <td>荆轲</td>
53             <td>程咬金</td>
54         </tr><tr>
55             <td>亚瑟</td>
56             <td>荆轲</td>
57             <td>程咬金</td>
58         </tr><tr>
59             <td>亚瑟</td>
60             <td>荆轲</td>
61             <td>程咬金</td>
62         </tr><tr>
63             <td>亚瑟</td>
64             <td>荆轲</td>
65             <td>程咬金</td>
66         </tr><tr>
67             <td>亚瑟</td>
68             <td>荆轲</td>
69             <td>程咬金</td>
70         </tr><tr>
71             <td>亚瑟</td>
72             <td>荆轲</td>
73             <td>程咬金</td>
74         </tr><tr>
75             <td>亚瑟</td>
76             <td>荆轲</td>
77             <td>程咬金</td>
78         </tr>
79         </tbody>
80     </table>
81 </div>
82 </body>
83 </html>

 

上面的都太小儿科了,js才是关键。

 

代码如下,我也不细细的讲了,就是这么干脆,其实真的很简单,有兴趣还能在优化:

function FixHeader(tableElement){
        this.tableElement=tableElement;
    }
    FixHeader.prototype={
        constructor:FixHeader,
        init:function(){
            this.tableParent=this.tableElement.parentNode;
            this.header=this.tableElement.querySelector(‘thead‘);
            this.cloneHeader=this.header.cloneNode(true);
            this.tableParent.addEventListener(‘scroll‘,this.listenerScroll.bind(this),false);
        },
        listenerScroll:function(ev){
            var top=ev.target.scrollTop,
                    cloneThead=ev.target.querySelector(‘.cloneThead‘);
            if(top>0){
                if(cloneThead){
                    cloneThead.style.display=‘block‘;
                    cloneThead.style.top=top+‘px‘;
                    return;
                }
                this.cloneFixHeader();
            }else{
                if(cloneThead){
                    cloneThead.style.display=‘none‘;
                }
            }
        },
        cloneFixHeader:function(){
            var cloneThs=this.cloneHeader.children[0].children,
                ths=this.header.children[0].children,
                th,cloneTh,i=0,l=cloneThs.length;
            for(;i<l;i++){
                th=ths[i];cloneTh=cloneThs[i];
                cloneTh.style.width=th.offsetWidth+‘px‘;
                cloneTh.style.height=th.offsetHeight+‘px‘;
            }
            this.cloneHeader.className=‘cloneThead‘;
            this.cloneHeader.style.position=‘absolute‘;
            this.cloneHeader.style.top=0;
            this.cloneHeader.style.left=0;
            this.cloneHeader.style.right=‘-1px‘;
            this.tableElement.appendChild(this.cloneHeader);
        }
    };
    new FixHeader(document.querySelector(‘.table‘)).init();

 

原生javascript 固定表头原理与源码