Vue多种方法实现表头、首列固定

来源:互联网 发布:宣城太守知不知全诗 编辑:程序博客网 时间:2024/06/06 01:53

有时表格太大,滚动时信息查看不方便,需要对表格进行全局表头、首列固定,
上效果:
固定表头首列

一、创建多个表格进行覆盖

    思路:当页面滚动到临界值时,出现固定表头、首列    先创建一个活动表格
<!DOCTYPE html><html>    <head>        <meta charset="UTF-8">        <title></title>        <style type="text/css">            th,            td {                min-width: 200px;                height: 50px;            }            #sTable {                margin-top: 300px            }            [v-cloak]{                display: none;            }        </style>    </head>    <body v-cloak>        <!--活动的表格-->        <table id="sTable" border="1" cellspacing="0">            <thead>                <tr>                    <th v-for="item in th">{{item.key}}</th>                </tr>            </thead>            <tbody>                <tr v-for="item in tl">                    <td  v-for="list in item">{{list.key}}</td>                </tr>            </tbody>        </table>        <script src="vue.js"></script>        <script src="jquery.js"></script>        <script>            var vm = new Vue({                el: "body",                data: function() {                    return {                        th: [],                        tl: [],                        temp: [],                    }                },                methods: {                    //生成表格                    CTable: function() {                        for(var i = 0; i < 10; i++) {                            this.th.push({                                key: "head" + i                            })                        }                        for(var i = 0; i < 100; i++) {                            for(var j = 0; j < 10; j++) {                                this.temp.push({                                    key: j + "body" + i                                })                            }                            this.tl.push(this.temp)                            this.temp = []                        }                    },                },                ready: function() {                    this.CTable();                },            })        </script>    </body></html>

再添加固定表头:

#fHeader {    background: lightblue;    position: fixed;    top: 0;}
<!--固定表头--><table border="1" id="fHeader" cellspacing="0" v-show="fixedHeader">     <thead>        <tr >            <th v-for="item in th">{{item.key}}</th>        </tr>    </thead></table>

监控表格位置到达窗口顶部时出现固定表头

//监控表头位置headerMonitor:function(){    var self=this    var hHeight=$("#sTable").offset().top;    $(document).scroll(function(){        //当滚动条达到偏移值的时候,出现固定表头        if($(this).scrollTop()>hHeight){            self.fixedHeader=true        }else{            self.fixedHeader=false        }    })}

当然需要调用该方法

ready: function() {    this.CTable();    this.headerMonitor()},

然后添加固定首列以及固定的A1单元格

#fHeader {    background: lightblue;        position: fixed;        top: 0;        z-index: 1;    }    .fixedA1{        background: lightblue;        position: fixed;        top: 0;        left: 0;        z-index:2;    }
<!--固定A1--><table border="1" cellspacing="0" class="fixedA1" v-show="fixedA1">    <thead>        <tr>            <th v-for="item in th" v-if="$index==0">{{item.key}}</th>        </tr>    </thead></table><!--固定首列--><table border="1" cellspacing="0" class="fixedCol" v-show="fixedCol">    <thead>        <tr>            <th v-for="item in th" v-if="$index==0">{{item.key}}</th>        </tr>    </thead>    <tbody>        <tr v-for="item in tl">            <td  v-for="list in item" v-if="$index==0">{{list.key}}</td>        </tr>    </tbody></table >

同理监控表格的位置

//监控表头、首列位置monitor:function(){    var self=this    $(document).scroll(function(){        self.setPosition()        //当滚动条达到左偏移值的时候,出现固定列头        if($(this).scrollLeft()>self.hLeft){            self.fixedCol=true        }else{            self.fixedCol=false        }        //当滚动条达到上偏移值的时候,出现固定表头        if($(this).scrollTop()>self.hHeight){            self.fixedHeader=true        }else{            self.fixedHeader=false        }        //当表格移到左上角时,出现固定的A1表格        if($(this).scrollLeft()>self.hLeft&&$(this).scrollTop()>self.hHeight){            self.fixedA1=true        }else{            self.fixedA1=false        }    })},

因为表格的移动会影响表头的位置的定位位置,因此需要将当前表格的偏移值赋给固定表头。首列

setPosition:function(){    $("#fHeader").css("left",this.hLeft-$(document).scrollLeft())    $(".fixedCol").css("top",this.hHeight-$(document).scrollTop())}

Jq监控滚动新建多个表格实现表头首列固定.html

二、控制样式实现固定表头,首列

思路:当表格达到临界值时,改变表头,首列的样式首先实现表头固定
<!DOCTYPE html><html>    <head>        <meta charset="UTF-8">        <title></title>        <style type="text/css">            th,            td {                min-width: 200px;                height: 50px;            }            table {                margin: 300px            }            .fHeader {                background: lightblue;                position: fixed;                top: 0;            }            [v-cloak]{                display: none;            }        </style>    </head>    <body v-cloak>        <table border="1" cellspacing="0">            <thead>                <tr :class="{fHeader:fixedHeader}">                    <th v-for="item in th">{{item.key}}</th>                </tr>            </thead>            <tbody>                <tr v-for="item in tl">                    <td v-for="list in item">{{list.key}}</td>                </tr>            </tbody>        </table>        <script src="vue.js"></script>        <script src="jquery.js"></script>        <script>            var vm = new Vue({                el: "body",                data: function() {                    return {                        th: [],                        tl: [],                        temp: [],                        fixedHeader: false,                    }                },                methods: {                    //生成表格,代码相同,省略                    CTable: function() {},                    //监控表头位置                    headerMonitor:function(){                        var self=this                        var hHeight=$("table").offset().top;                        $(document).scroll(function(){                            //当滚动条达到偏移值的时候,出现固定表头                            if($(this).scrollTop()>hHeight){                                self.fixedHeader=true                            }else{                                self.fixedHeader=false                            }                        })                    }                },                ready: function() {                    this.CTable();                    this.headerMonitor()                },            })        </script>    </body></html>

添加固定首列

.fixedCol>:first-child{    background: lightblue;    position: fixed;    z-index: 1;    border:1px solid grey;    left: 0;    line-height: 50px;}

监控表格位置

//监控表头,首列位置monitor:function(){    this.setPosition()    var self=this    $(document).scroll(function(){        self.setPosition();        //当滚动条达到偏移值的时候,出现固定表头        if($(this).scrollTop()>self.hHeight){            self.fixedHeader=true;        }else{            self.fixedHeader=false        }        //当滚动条达到左偏移值的时候,出现固定列头        if($(this).scrollLeft()>self.hLeft){            self.fixedCol=true        }else{            self.fixedCol=false        }        //当表格移到左上角时,出现固定的A1表格        if($(this).scrollLeft()>self.hLeft&&$(this).scrollTop()>self.hHeight){            self.fixedA1=true        }else{            self.fixedA1=false        }    })},

设置偏移值

//使固定表头与列头的偏差与当前表格的偏移值相等setPosition:function(){    $(".fixedHeader").css("left",this.hLeft-$(document).scrollLeft())    for(var i=0,len=this.tl.length+1;i<len;i++){        //因为设置了“border-collapse:collapse”,所以要加“54-1”        $(".fixedCol>:first-child").eq(i).css("top",this.hHeight-$(document).scrollTop()+53*i)    }}

因为当表头变成fixed定位时会脱离文档流,表格的第二行会被隐藏,所以需要多第二列进行宽高的拓展

/*因为fixed定位不占位,当固定表头出现时,有一行会补到表头位置,即有一行跳空,将tbody的第一行行高加倍*/.fixedHeaderGap:first-child>td{        padding-top:54px;    }/*因为fixed定位不占位,当固定列头出现时,有一列会补到列头位置,即有一列跳空,将tbody的第二列p设置padding*/.fixedCol>:nth-child(2){    padding-left: 205px;}

当再次浏览器打开时该页面时,需要监控表格是否还达到固定表头的临界条件

watch:{    //页面初始加载时,使固定表头与列头的偏差与当前表格的偏移值相等    "fixedHeader":function(){        this.setPosition()    },    "fixedCol":function(){        this.setPosition()    },},

改样式实现固定表头首列.html

三、Vue自定义指令实现滚动监听

当使用vue时,就很少会用到Jq这么庞大的库,而且vue官方也不推荐操作Dom元素,因此可以自定义指令实现固定表头,首列。本文用的是Vue.js v1.0.26,但V2.0的思路其实也一样。直接上代码
<!DOCTYPE html><html>    <head>        <meta charset="UTF-8">        <title></title>        <style type="text/css">            th,            td {                min-width: 200px;                height: 50px;            }            #sTable {                margin: 300px            }            .fixedCol{                position: fixed;                left: 0;                background: lightblue;                z-index: 1;            }            #fHeader {                background: lightblue;                position: fixed;                top: 0;                z-index: 1;            }            .fixedA1{                background: lightblue;                position: fixed;                top: 0;                left: 0;                z-index:2;            }            [v-cloak]{                display: none;            }        </style>    </head>    <body v-cloak>        <!--固定A1-->        <table border="1" cellspacing="0" class="fixedA1" v-show="fixedA1">            <thead>                <tr>                    <th v-for="item in th" v-if="$index==0">{{item.key}}</th>                </tr>            </thead>        </table>        <!--固定列头-->        <table border="1" cellspacing="0" class="fixedCol" v-show="fixedCol">            <thead>                <tr>                    <th v-for="item in th" v-if="$index==0">{{item.key}}</th>                </tr>            </thead>            <tbody>                <tr v-for="item in tl">                    <td  v-for="list in item" v-if="$index==0">{{list.key}}</td>                </tr>            </tbody>        </table >        <!--固定表头-->        <table border="1" id="fHeader" cellspacing="0" v-show="fixedHeader">             <thead>                <tr >                    <th v-for="item in th">{{item.key}}</th>                </tr>            </thead>        </table>        <!--活动的表格,绑定自定义指令-->        <table id="sTable" border="1" cellspacing="0" v-scroll>            <thead>                <tr>                    <th v-for="item in th">{{item.key}}</th>                </tr>            </thead>            <tbody>                <tr v-for="item in tl">                    <td  v-for="list in item">{{list.key}}</td>                </tr>            </tbody>        </table>        <script src="vue.js"></script>        <script>            var vm = new Vue({                el: "body",                data: function() {                    return {                        th: [],                        tl: [],                        temp: [],                        fixedCol: false,                        fixedHeader:false,                        fixedA1:false,                        hLeft:0,                        hHeight:0,                    }                },                directives:{                    scroll:{                        bind:function(){                            //触发滚动监听事件                            window.addEventListener('scroll',function(){                                this.vm.monitor()                            })                        }                    }                },                methods: {                    //生成表格                    CTable: function() {},                    //监控表头、列头位置                    monitor:function(){                        this.setPosition();                        //当滚动条达到左偏移值的时候,出现固定列头                        if(document.body.scrollLeft>this.hLeft){                            this.fixedCol=true;                        }else{                            this.fixedCol=false;                        }                        //当滚动条达到上偏移值的时候,出现固定表头                        if(document.body.scrollTop>this.hHeight){                            this.fixedHeader=true;                        }else{                            this.fixedHeader=false;                        }                        //当表格移到左上角时,出现固定的A1表格                        if(document.body.scrollLeft>this.hLeft&&document.body.scrollTop>this.hHeight){                            this.fixedA1=true;                        }else{                            this.fixedA1=false;                        }                    },                    //使固定表头与列头的偏差与当前表格的偏移值相等                    setPosition:function(){                        document.getElementById("fHeader").style.left=this.hLeft-document.body.scrollLeft+"px";                        document.getElementsByClassName("fixedCol")[0].style.top=this.hHeight-document.body.scrollTop+"px";                    },                },                ready: function() {                    this.CTable();                    this.hLeft=document.getElementById("sTable").offsetLeft;                    this.hHeight=document.getElementById("sTable").offsetTop                    this.monitor()                },            })        </script>    </body></html>

若想要做成自定义回调事件,可以用eval(),

<table id="sTable" border="1" cellspacing="0" v-scroll="monitor">
directives:{    scroll:{        bind:function(){            var self=this;            //触发滚动监听事件            window.addEventListener('scroll',function(){                //触发滚动回调事件                eval("self.vm."+self.expression)()            })        }    }},

自定义回调指令固定表列头.html

0 0