jQuery制作多表格固定表头、切换表头的特效

做了好几天的固定表头特效,总算是搞定了。先说明一下基本功能:我们在一个网页上浏览很多份表格数据的时候,肯定会碰到很多分不清表头,也分不清表 格是哪个的情况,这个时候我们就希望能有一种功能,就是我们再下拉滚动条的时候,表格的表头固定住。这样对付只有一张表格的网页还好,如果表格多了,又会 很麻烦。我做的这个特效综合了固定表格表头的功能,同时,还能在浏览不同表格时候,切换固定的表头。效果如图所示:

网页上有两个表格

网页上有两个表格

拉动滚动条,固定第一个表格的表头

拉动滚动条,固定第一个表格的表头

继续拉动滚动条,切换并到第二个表格的表头

继续拉动滚动条,切换并到第二个表格的表头

我 在做这个特效的时候,首先考虑的是怎样固定住表头。在网上搜到一个不错的固定表头Jquery插件-chromatable。基本的思路都一样,就是现将 整个表格复制一遍,然后将表头和表身分离,分别用div包住,设置好表身最大的高度,并显示滚动条,在拉动滚动条时,表头因为已经和表身分离,所以不会随 着页面下拉而滚动。我将这个插件重写了一遍,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
( function ($) {
$.fn.extend({
ScrollTable: function (options) {
var defaults = {
MaxHeight: 600,
MaxDataItemIndex: 1 // 固定前MaxDataItemIndex作为固定表头
};
options = $.extend(defaults, options);
return this .each( function () {
var $ this = $( this );
//设置表格自动换行
$ this .css({ "table-layout" : "fixed" });
$ this .find( 'td' ).css({ "word-break" : "break-all" , "word-wrap" : "break-word" });
// 产生表头部分和身体部分
var $cloneTableHeader = $ this .clone();
var $cloneTableBody = $ this .clone();
$cloneTableHeader.find( "tr" ).filter( function (index) {
return index >= options.MaxDataItemIndex
}).remove();
$cloneTableBody.find( "tr" ).filter( function (index) {
return index < options.MaxDataItemIndex
}).remove();
//设置单元格边框
$cloneTableHeader.find( "tr" ).css({ "border" : "1px blue solid" });
$cloneTableBody.find( "td" ).css({ "border" : "1px blue solid" });
// 将产生的表头和身体部分放入Container,并做一些微调
$ this .after( "<div class='ScrollTableContainer' style='border:1px solid;margin:10px 0;'></div>" );
$ this .next().append($cloneTableHeader);
$ this .next().append( "<div class='ScrollDiv' style='overflow-y:scroll;'></div>" );
$ this .next().css( "width" , $ this .width());
$ this .next().find( "div.ScrollDiv" ).css({
"max-height" : options.MaxHeight,
"margin-top" : -2
});
$ this .next().find( "div.ScrollDiv" ).append($cloneTableBody);
$ this .remove();
});
}
});
})(jQuery)

接下来,我在网上搜了一下怎样固定,同时切换块级元素。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<script>
$( function () {
//设置内容块的宽度与导航块的宽度一样
$( ".Xc_list_top" ).css( "width" ,$( ".Xc_list_main" ).width());
var resetRightPanelPostion = function () {
   //在JQuery中,可以利用导航工具类$.browser来判断浏览器类型
   var msie6 = $.browser.msie && $.browser.version == '6.0' && $.browser.version < 7;
   //获取body元素标签
   if ($.browser.safari) {
     bodyelem = $( "body" );
   } else {
     bodyelem = $( "html,body" );
   }
   //$(selector).scrollTop(offset),offset是相对滚动条顶部的偏移,以像素计。获取滚动条距离顶部的距离。
   var bodyTop = bodyelem.scrollTop();
   //offset() 方法返回或设置匹配元素相对于文档的偏移(位置)。这里是获取相对于文档的顶部偏移。
   var top = $( ".Xc_left" ).offset().top;
   //var t = $("#public_footer").offset().top;
   var t = $( "#footerDestinationBox" ).offset().top;
   //var bottom = $("#footerDestinationBox").offset().top;
   //循环遍历class为Xc_list_top的数组的成员
   for ( var i = 0; i < $( ".Xc_list .Xc_list_top" ).length ; i++){
     /*标准浏览器下:
     height:高度
     innerHeight:高度+补白
     outerHeight:高度+补白+边框,参数为true时:高度+补白+边框+边距*/
     //当滚动条向下移动的偏移量大于等于元素相对文档顶部的偏移量时(即左边的div顶部接触到窗口顶部)
     //滚动条往下拉动的距离等于底部相对顶部偏移量不断减少的距离,所以
     //bodyTop = t - $("#footerDestinationBox").offset().top
     //当底部div距离顶部的长度等于左边div的
     //outheight = $("#footerDestinationBox").offset().top时,
     //底部与$('.Xc_left')接触
     //所以(bodyTop + $(".Xc_left").outerHeight())<t)指底部的div还没有将左边的div完全顶出。
if (bodyTop >= top && ((bodyTop + $( ".Xc_left" ).outerHeight()) < t)) {
//如果ie浏览器的版本不是6或6以下
   if (!msie6) {
     if (bodyTop + $( ".Xc_gg" ).outerHeight() >= t) {
         $( ".Xc_gg" ).removeClass( 'fixed' ).css({
            "position" : "absolute" ,
            "top" : t - $( ".Xc_gg" ).outerHeight() + "px"
         });
     } else {
         $( ".Xc_gg" ).css({
            "position" : "fixed" ,
            "top" : 0
         });
     }
   }
} else {
   if (!msie6) {
     $( ".Xc_gg" ).css({
     "position" : "static"
   });
   }
}
/*if(bodyTop>$(".Xc_list").eq(i).offset().top){
   $(".Xc_list_top").eq(i).css({position:"absolute",top:top-168});
}*/
    if (bodyTop>$( ".Xc_list" ).eq(i).offset().top){
      $( ".Xc_list_top" ).eq(i).css({position: "fixed" ,top:0});
    }
    if (bodyTop<=$( ".Xc_list" ).eq(i).offset().top){
      $( ".Xc_list_top" ).eq(i).css({position: "static" ,top:0});
    }
  }
};
window.onload = function () {
//判断div.Xc_gg是否存在
if ($( ".Xc_gg" ).length) {
   resetRightPanelPostion();
    $(window).scroll( function () {
       resetRightPanelPostion();
    });
   }
}
})
</script>

最后,综合上面的两种功能,先修改插件chromatable中的代码,将 "$this.next().append("<div class='ScrollDiv' style='overflow-y:scroll;'></div>");"

这一行代码中的style='overflow-y:scroll'样式去掉,这样就不会出现滚动条。然后,将头部的代码包裹在一个class属性
为'ScrollHeader'的div中。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
( function ($) {
     $.fn.extend({
       ScrollTable : function (options){
           var defaults = {
              // SwitchTag : 'tr', //默认表头标签为tr
               MaxHeight : 400,
               MaxDataItemIndex : 1   //固定前多少列为表头
           };
           options = $.extend(defaults,options);
           return this .each( function (){
               var $ this = $( this );
               //设置表格内容自动换行
               $ this .css({ "table-layout" : "fixed" });
               $ this .find( 'td' ).css({ "word-break" : "break-all" , "word-wrap" : "break-word" });
                 // 产生表头部分和身体部分
               // 复制表格内容
               var $newTableHeader = $ this .clone();
               var $newTableBody = $ this .clone();
               // 产生表头部分和身体部分,filter()遍历并根据参数做为选择器来筛选。
               $newTableHeader.find( "tr" ).filter( function (index){
                    return index >= options.MaxDataItemIndex
               }).remove();
               $newTableBody.find( "tr" ).filter( function (index){
                    return index < options.MaxDataItemIndex
               }).remove();
               //设置单元格边框
               $newTableHeader.find( "tr" ).css({ "border" : "1px blue solid" });
               $newTableBody.find( "td" ).css({ "border" : "1px blue solid" });
          // 将产生的表头和身体部分放入Container
          $ this .after( "<div class='ScrollTableContainer' style='border:1px solid;margin:10px 0;'></div>" );
               $ this .next().append( "<div class='ScrollHeader'></div>" );
               //$this.next().append($newTableHeader);
               $ this .next().append( "<div class='ScrollDiv'></div>" );
               $ this .next().css( "width" , $ this .width());
               //将表头部分添加到class属性为ScrollHeader的div元素中
              $ this .next().find( "div.ScrollHeader" ).append($newTableHeader);
               $ this .next().find( "div.ScrollDiv" ).css({
                     "max-height" : options.MaxHeight,
                     //"margin-top": -2
                 });
               $ this .next().find( "div.ScrollDiv" ).append($newTableBody);
               $ this .remove();
         });
       }
     });
})(jQuery);

接着,我们还要将切换代码写进去,我们来到表格页面,加入以下jquery代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
   <script src= "http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js" ></script>
     <script src= "./jquery.chrometable.js" ></script>
     <script>
         $( function (){
             $( 'table' ).ScrollTable();
<span style= "text-decoration: underline;" ><span style= "color: #ff0000; text-decoration: underline;" > //$(window).scroll(function(){}),当鼠标拖动滚动条时触发一次该函数,如果不这样写,就无法动态地获取bodyTop,
//也就是滚动条距离顶部距离的值。但是如果不断地触发ScroolTable()会造成脚本运行错乱。</span></span>
             //单独将动态获取bodyTop写成一个函数。
             var bodyTop = function (){
                 //获取body元素标签
                 if ($.browser.safari) {
                     bodyelem = $( "body" );
                 } else {
                     bodyelem = $( "html,body" );
                 }
                 //获取滚动条与body元素顶部的距离
                 var bodyTop = bodyelem.scrollTop();
                 var num = $( ".ScrollTableContainer .ScrollHeader" ).length;
                 //循环遍历class为ScrollTableContainer的div成员,即遍历多个表格table元素中的表头
                 for ( var i = 0;i<num;i++){
                     if (bodyTop >$( ".ScrollTableContainer" ).eq(i).offset().top){
                         $( ".ScrollHeader" ).eq(i).css({position: "fixed" ,top:0,backgroundColor: "red" });
                     }
                     if (bodyTop <=$( ".ScrollTableContainer" ).eq(i).offset().top){
                         $( ".ScrollHeader" ).eq(i).css({position: "static" ,top:0});
                     }
                 }
             }
             $(window).scroll( function () {
                 bodyTop();
             });
         })
     </script>

最后,我在这里要说明以下我犯的两个小错误,第一个就是在写Jquery代码时,将固定格式:

1
( function ($){})(jQuery)

中的"jQuery"写成了Jquery,耗了我很多精力去排错!

jQuery(function(){ });用于存放操作DOM对象的代码,执行其中代码时DOM对象已存在。不可用于存放开发插件的代码,因为jQuery对象没有得到传递,外部通过jQuery.method也调用不了其中的方法(函数)。
(function(){ })(jQuery);用于存放开发插件的代码,执行其中代码时DOM不一定存在,所以直接自动执行DOM操作的代码请小心使用。

第 二个就是,我刚刚开始把切换表头的代码写在插件文件一起,发现bodyTop的值一直没有变过,只有刷新一下才能实现功能,原来是要加入滚动条事件来不断 触发函数保证动态获取滚动条鼓励顶部的值bodyTop。但是,一定要将这个函数分离出来,如果写在一起,就会让整个固定表头的脚本也随着滚动条的拖动而 不断运行。

最后,将上面的三个例子全部都共享出来给大家下载。

DEMO下载地址>>(说明:demo1:表头固定插件,demo2:切换和固定div,demo3:切换和固定表头。)

转载于:https://www.cnblogs.com/piuba/p/3414788.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值