zoukankan      html  css  js  c++  java
  • 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:切换和固定表头。)

  • 相关阅读:
    25-javaweb接入支付宝支付接口
    4-js 函数
    24-filter-拦截器
    23-新建maven 项目
    22-maven-安装与配置
    15-matlab矩阵运用
    2018.7.18 div,section,article的区别和使用
    2018.7.17 牛客网训练
    2018.7.16常用推荐算法
    2018.7.15 解决css中input输入框点击时去掉外边框方法
  • 原文地址:https://www.cnblogs.com/piuba/p/3414788.html
Copyright © 2011-2022 走看看