Vue多种方法实现表头和首列固定的示例代码
程序员文章站
2022-08-09 22:53:43
有时表格太大,滚动时信息查看不方便,需要对表格进行全局表头、首列固定,
上效果:
一、创建多个表格进行覆盖
思路:当页面滚动到临界值时,出现固定表头、...
有时表格太大,滚动时信息查看不方便,需要对表格进行全局表头、首列固定,
上效果:
一、创建多个表格进行覆盖
思路:当页面滚动到临界值时,出现固定表头、首列
先创建一个活动表格
<!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()) }
二、控制样式实现固定表头,首列
思路:当表格达到临界值时,改变表头,首列的样式
首先实现表头固定
<!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() }, },
三、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)() }) } } },
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。