Vue多种方法实现表头和首列固定的示例代码


Posted in Javascript onFebruary 02, 2018

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

上效果:

Vue多种方法实现表头和首列固定的示例代码

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

思路:当页面滚动到临界值时,出现固定表头、首列

先创建一个活动表格

<!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)()
      })
    }
  }
},

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js控制淡入淡出示例代码
Nov 12 Javascript
jQuery 2.0.3 源码分析之core(一)整体架构
May 27 Javascript
提升PHP安全:8个必须修改的PHP默认配置
Nov 17 Javascript
JavaScript中的数学运算介绍
Dec 29 Javascript
jQuery实现美观的多级动画效果菜单代码
Sep 06 Javascript
JavaScript实现的Tween算法及缓冲特效实例代码
Nov 03 Javascript
基于javascript实现图片滑动效果
May 07 Javascript
js实现页面跳转的几种方法小结
May 16 Javascript
关于JavaScript限制字数的输入框的那些事
Aug 14 Javascript
jQuery 如何实现一个滑动按钮开关
Dec 01 Javascript
详解JS中的attribute属性
Apr 25 Javascript
解决axios post 后端无法接收数据的问题
Oct 29 Javascript
jquery.picsign图片标注组件实例详解
Feb 02 #jQuery
使用webpack打包koa2 框架app
Feb 02 #Javascript
Vue组件化开发思考
Feb 02 #Javascript
微信小程序实现导航栏选项卡效果
Jun 19 #Javascript
解析Vue.js中的组件
Feb 02 #Javascript
如何将你的AngularJS1.x应用迁移至React的方法
Feb 01 #Javascript
vue 2.0 购物车小球抛物线的示例代码
Feb 01 #Javascript
You might like
php实现邮件发送并带有附件
2014/01/24 PHP
PHP遍历数组的方法汇总
2015/04/30 PHP
php反序列化长度变化尾部字符串逃逸(0CTF-2016-piapiapia)
2020/02/15 PHP
判断是否安装flash player及当前版本的JS代码
2013/08/08 Javascript
Jquery右下角抖动、浮动 实例代码(兼容ie6、FF)
2013/08/15 Javascript
js 浏览本地文件夹系统示例代码
2013/10/24 Javascript
js打开windows上的可执行文件示例
2014/05/27 Javascript
jQuery的animate函数学习记录
2014/08/08 Javascript
node.js操作mongodb学习小结
2015/04/25 Javascript
Javascript之String对象详解
2016/06/08 Javascript
滚动条的监听与内容随着滚动条动态加载的实现
2017/02/08 Javascript
浅谈JavaScript中的apply/call/bind和this的使用
2017/02/26 Javascript
浅谈ajax请求不同页面的微信JSSDK问题
2018/02/26 Javascript
解决angular2在双向数据绑定时[(ngModel)]无法使用的问题
2018/09/13 Javascript
JS添加或删除HTML dom元素的方法实例分析
2019/03/05 Javascript
vue-cli3项目展示本地Markdown文件的方法
2019/06/07 Javascript
Vue Router的手写实现方法实现
2020/03/02 Javascript
JavaScript图片旋转效果实现方法详解
2020/06/28 Javascript
[02:02]DOTA2英雄基础教程 斯拉达
2013/12/11 DOTA
[43:57]LGD vs Mineski 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
Python实现抓取页面上链接的简单爬虫分享
2015/01/21 Python
Python 3.8 新功能全解
2019/07/25 Python
python能做什么 python的含义
2019/10/12 Python
解决python 上传图片限制格式问题
2019/10/30 Python
使用 Python 遍历目录树的方法
2020/02/29 Python
python 实现在无序数组中找到中位数方法
2020/03/03 Python
终于搞懂了Keras中multiloss的对应关系介绍
2020/06/22 Python
伦敦新晋轻奢耳饰潮牌:Tada & Toy
2020/05/25 全球购物
.NET面试题:什么是反射
2016/09/30 面试题
如何查找网页漏洞
2016/06/22 面试题
阿德的梦教学反思
2014/02/06 职场文书
给孩子的新年寄语
2014/04/08 职场文书
部门年终奖分配方案
2014/05/07 职场文书
关于感恩的演讲稿500字
2014/08/26 职场文书
Java网络编程之UDP实现原理解析
2021/09/04 Java/Android
分享五个Node.js开发的优秀实践 
2022/04/07 NodeJs