js表头固定实现思路汇总
2015-09-11 17:39
726 查看
表头固定,表身滚动的特效,被广泛运用于各种大数据量展示的页面,本人在实践开发过程中总结了3中实现方式,现在,分享给大家。
思路一
当发生滚动事件后,动态复制一份表头,将其放置在原表头的位置,为滚动的容器添加scroll事件,时刻保持复制表头的top=滚动条的垂直位置($(obj).scrollTop())
以下为demo代码实现:
-CSS 实现
-HEML实现
-JS实现
分析
以上实现的是基于某个父容器进行滚动的,如果有朋友想要实现基于浏览器进行滚动,只需要将fixTabHeader方法中scrollDiv 申明为当前文档对象就可以了,即scrollDiv=$(window).
此种方法适合比较简单的表格,如果你的表格应用了很多外部样式,比如许多朋友为了效果好实用bootstrap框架做特效,这时候会发现该种方法实现的固头,会有表头的数据行和表内容无法对齐的现象,而且这个问题及其难调,本人花了好几天也没有搞定,如果有看文章的朋友解决了,欢迎和我交流。
思路二
实现思路同上面的demo相似,都是复制一份表头来做固定,不同的是上面例子是复制了一份表头直接放置到滚动容器中固定,而本例子是将复制的表头放在了tbody中,然后做固定。位置不同。
css
分析
demo1 和demo2的思路都是复制一份表头做固定。不同的是demo1有点粗糙直接放到了滚动容器中,做位置固定。而demo2是将它放到了自己table的tbody中。而且demo2还将表格固定的这个例子做成了一个比较通用的插件,方便在其他项目中通用。但是,令人遗憾的是,对于较复杂的例子,demo2也存在表头和表内容无法完全垂直的问题。而且不太好调试。
思路三
写两个表格,一个为表头,另一个为表内容。当表内容数据量比较大时,可以直接在表内容所在的父容器进行滚动。以下为demo代码实现:
分析
这种方式应该是最简单,最明了的实现方式,表头和表内容分家,各管各家,对于表头来说,不管表内容滚或者不滚,它都在哪里不离不弃。但是存在一个问题,在表内容没有滚动时,表头和表身是垂直对齐的,一旦表身出现滚动,新出现的滚动条会占用表身的部分宽度,这就导致表身和表头又不对齐。所以,我们需要在给两个表格应用同样样式的基础上,再用js函数控制两个的宽度,使他们宽度一致,大体思路是获取滚动条的宽,然后设置表头的宽度减去滚动条的宽度。
补充介绍Jquery的几个参数:
offsetWidth :当前对象的的宽度包括滚动条在内
scrollWidth :当前对象的滚动宽度不包括滚动条在内
在css的盒子模型中,最内部是content,然后是padding、border、margin
width=content
innerWidth = width + padding
outerWidth = innerWidth + border
outerWidth(true) = outerWidth + margin
关于outerWidth属性有一个传入参数可以控制它包不包含外部的margin 为true的话包含,默认不包含。
注意:要想表格相对于某个父容器做数据滚动,则该父容器必须做如下设置:
(1)设置固定高度,不设置高度或者用百分比设置高度,滚动不起作用
(2)设置属性overflow-y:auto
必选项,否则当表格数据过多时,不会产生滚动条,而是自动延长该父容器的高度
(3)设置 position:relative,这个主要是针对前连个例子而言
若不设置,拷贝得来的表头将相对于其设置该属性为该值的父节点(或间接父节点)定位,如果没有,则相对于body
思路一
当发生滚动事件后,动态复制一份表头,将其放置在原表头的位置,为滚动的容器添加scroll事件,时刻保持复制表头的top=滚动条的垂直位置($(obj).scrollTop())
以下为demo代码实现:
-CSS 实现
<style type="text/css"> .table { width:240px; } .table tr >td,.table >thead>tr>th { border:1px solid green; width:50px; } .header-copy{ background:red; } #scrollContainer{ width:260px; position:fixed; height:200px; overflow-y:auto; } </style
-HEML实现
<div id='scrollContainer' > <table class="table" cellspacing=0 cellpadding=0 id="mytab"> <thead > <tr> <th>姓名</th><th>爱好</th> </tr> </thead> <tbody> <tr> <td>码妞一</td><td>吉他</td> </tr> </tbody> </table> </div> <!-- 以下的js只是为了批量生成数据,真正固定表头的方法是fixTabHeader --> <script type="text/javascript"> $(document).ready(function(){ var row=$("#mytab >tbody>tr:first"); for(i=0;i<30;i++){ $('table#mytab > tbody').append(row.clone()); } fixTabHe f870 ader("mytab","scrollContainer"); }); </script>
-JS实现
<script language="javascript" type="text/javascript" > function fixTabHeader(tabid,scrollid){ // 获取滚动条容器 var scrollDiv =$("#"+scrollid); // 将表格拷贝一份 var tb2 =$("#"+tabid).clone(true); // 将拷贝得到的表格中非表头行删除 if(tb2.size()>0) { tb2.find("tr:not(:first)").remove(); } // 创建一个div ,并添加到滚动容器中 var bakDiv =$("<div style='position:absolute;display:none;width:100%;'></div>"); bakDiv.css("top",scrollDiv.scrollTop()); bakDiv.appendTo(scrollDiv); // 将拷贝得到的表格在删除数据行后添加到创建的div中 tb2.addClass("header-copy"); tb2.appendTo(bakDiv); scrollDiv.scroll(function(){ // 设置div的top值为滚动条距离滚动条容器顶部的距离值 bakDiv.css({top:$(this).scrollTop()+"px",background:"#e8eaeb",display:"block"}); }); } </script>
分析
以上实现的是基于某个父容器进行滚动的,如果有朋友想要实现基于浏览器进行滚动,只需要将fixTabHeader方法中scrollDiv 申明为当前文档对象就可以了,即scrollDiv=$(window).
此种方法适合比较简单的表格,如果你的表格应用了很多外部样式,比如许多朋友为了效果好实用bootstrap框架做特效,这时候会发现该种方法实现的固头,会有表头的数据行和表内容无法对齐的现象,而且这个问题及其难调,本人花了好几天也没有搞定,如果有看文章的朋友解决了,欢迎和我交流。
思路二
实现思路同上面的demo相似,都是复制一份表头来做固定,不同的是上面例子是复制了一份表头直接放置到滚动容器中固定,而本例子是将复制的表头放在了tbody中,然后做固定。位置不同。
css
table { width:98%; text-align:center; color:blue } table .header{ background:green; } table .header-fixed { position: fixed; } #scrollContainer{ height:200px; overflow-y:auto; }
<div id='scrollContainer' > <table class="table" cellspacing=0 cellpadding=0 id="mytable"> <thead class="header"> <tr> <th>姓名</th><th>爱好</th> </tr> </thead> <tbody> <tr> <td>一介码妞</td><td>吉他</td> </tr> </tbody> </table> </div> <!-- 以下的js只是为了批量生成数据,真正固定表头的方法是fixTabHeader --> <script type="text/javascript"> $(document).ready(function(){ var row=$("#mytable >tbody>tr:first"); for(i=0;i<80;i++){ $('table#mytable > tbody').append(row.clone()); } $("#mytable").fixedHeader(); }); </script>
<script type="text/javascript"> (function () { (function ($) { return $.fn.fixedHeader = function (options) { var config; config = { bgColor: '#ff82ab' }; if (options) { $.extend(config, options); } return this.each(function () { var $head, $parent, headTop, isFixed, o, ww; processScroll = function () { var headTop, i, isFixed, scrollTop, t; if (!o.is(':visible')) { return; } i = void 0; scrollTop = $parent.scrollTop(); t= $head.length && $head.offset().top; if (!isFixed && headTop !== t) { headTop = t; } if (scrollTop >= headTop && !isFixed) { isFixed = 1; } else { if (scrollTop <= headTop && isFixed) { isFixed = 0; } } if (isFixed) { return $('thead.header-copy', o).show(); } else { return $('thead.header-copy', o).hide(); } }; o = $(this); $parent=$("#scrollContainer");//$($(this).parent()); $head = $('thead.header', o); isFixed = 0; headTop = ($head.length) && ($head.offset().top); $parent.on('scroll',processScroll); $head.on('click', function () { if (!isFixed) { return setTimeout(function () { return $parent.scrollTop($head.scrollTop()); }, 10); } }); $head.clone().removeClass('header').addClass('header-copy header-fixed').appendTo(o); ww = []; o.find('thead.header > tr:first > th').each(function (i, h) { return ww.push($(h).outerWidth(false)); }); $.each(ww, function (i, w) { return o.find('thead.header > tr > th:eq(' + i + '), thead.header-copy > tr > th:eq(' + i + ')').css({ width: w }); }); o.find('thead.header-copy').css({ margin: '0 auto', width: o.outerWidth(), top:headTop-2, 'background-color': config.bgColor }); return processScroll(); }); }; }(jQuery)); }.call(this)); </script>
分析
demo1 和demo2的思路都是复制一份表头做固定。不同的是demo1有点粗糙直接放到了滚动容器中,做位置固定。而demo2是将它放到了自己table的tbody中。而且demo2还将表格固定的这个例子做成了一个比较通用的插件,方便在其他项目中通用。但是,令人遗憾的是,对于较复杂的例子,demo2也存在表头和表内容无法完全垂直的问题。而且不太好调试。
思路三
写两个表格,一个为表头,另一个为表内容。当表内容数据量比较大时,可以直接在表内容所在的父容器进行滚动。以下为demo代码实现:
<table> <thead class="header"> <tr> <th>姓名</th><th>爱好</th> </tr> </thead> </table> <div id='scrollContainer' style="height:300px;overflow-y:auto;" > <table class="table" cellspacing=0 cellpadding=0 id="mytable"> <tbody> <tr> <td>一介码妞</td><td>吉他</td> </tr> </tbody> </table> </div> <!-- 以下的js只是为了批量生成数据,真正固定表头的方法是fixTabHeader --> <script type="text/javascript"> $(document).ready(function(){ var row=$("#mytable >tbody>tr:first"); for(i=0;i<80;i++){ $('table#mytable > tbody').append(row.clone()); } $("#mytable").fixedHeader(); }); </script>
<script type="text/javascript"> function fixTabHeaderScroll(tabid){ var $parent,$head,pTop,oTop,headTop,o; o=$("#"+tabid); oTop=o.height(); $parent=o.parent(); pTop=$parent.height(); $head=$parent.prev(); if (pTop <=oTop) { $head.css({width:$head.outerWidth(true)-scrollBarWidth+"px"}); }else{ $head.css({width:100+"%"}); } } </script>
分析
这种方式应该是最简单,最明了的实现方式,表头和表内容分家,各管各家,对于表头来说,不管表内容滚或者不滚,它都在哪里不离不弃。但是存在一个问题,在表内容没有滚动时,表头和表身是垂直对齐的,一旦表身出现滚动,新出现的滚动条会占用表身的部分宽度,这就导致表身和表头又不对齐。所以,我们需要在给两个表格应用同样样式的基础上,再用js函数控制两个的宽度,使他们宽度一致,大体思路是获取滚动条的宽,然后设置表头的宽度减去滚动条的宽度。
补充介绍Jquery的几个参数:
offsetWidth :当前对象的的宽度包括滚动条在内
scrollWidth :当前对象的滚动宽度不包括滚动条在内
在css的盒子模型中,最内部是content,然后是padding、border、margin
width=content
innerWidth = width + padding
outerWidth = innerWidth + border
outerWidth(true) = outerWidth + margin
关于outerWidth属性有一个传入参数可以控制它包不包含外部的margin 为true的话包含,默认不包含。
注意:要想表格相对于某个父容器做数据滚动,则该父容器必须做如下设置:
(1)设置固定高度,不设置高度或者用百分比设置高度,滚动不起作用
(2)设置属性overflow-y:auto
必选项,否则当表格数据过多时,不会产生滚动条,而是自动延长该父容器的高度
(3)设置 position:relative,这个主要是针对前连个例子而言
若不设置,拷贝得来的表头将相对于其设置该属性为该值的父节点(或间接父节点)定位,如果没有,则相对于body
相关文章推荐
- ajaxfileupload.js的简单使用
- JavaScript - 知识点总结
- jsp导出excel浏览器兼容
- js cheatsheet
- 什么是jsp?什么是servlet?
- js
- JS 只能输入数字和两位小数的JS
- JavaScript HTML DOM 事件
- X-stream完美转换XML、JSON
- js re cheatsheet
- JavaScript HTML DOM - 改变CSS
- js糟粕
- Javascript 中 String.replace( ) 多种用法
- JavaScript日期格式化函数
- javascript html DOM 改变html
- JS实现动画原理一(闭包方式)
- extjs
- javascript html DOM
- javascript的继承种类
- JS-JQ实现TAB选项卡