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

有时表格太大,滚动时信息查看不方便,需要对表格进行全局表头、首列固定,
上效果:
Vue多种方法实现表头、首列固定_第1张图片

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

    思路:当页面滚动到临界值时,出现固定表头、首列
    先创建一个活动表格

<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;
    }

<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

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

思路:当表格达到临界值时,改变表头,首列的样式
首先实现表头固定

<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//因为设置了“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的思路其实也一样。
直接上代码

<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>
        
        <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

你可能感兴趣的:(前端)