这两天接了一个需求,页面是这样的
然后需求是页面中的这个表格当页面向上滚动,且表格的表头到达窗口上方时,表头悬浮在页面的上方,表格正常滚动,这样表格内的数据可以随时看到表头内容。
一开始我认为这是极简单的,就当页面滚动,判断表头到窗口的距离,当=0的时候触发事件然后让表头position:fixed不就万事大吉了吗?于是我对漂亮又萌萌哒的产品妹子说,放心吧,这个简单的很一会就能完事,当时我的表情是这样的
但是当我开始写(首先你要知道,我是个js小白,表问我为什么。。。),问题就来了。首先,这个页面滚动应该用$(window).scroll,那么我怎么去判断表头到窗口的距离呢?我立马想到了offset,这里正好温习一下offset()和position()的区别,首先呢他们确实都代表位置,不过呢 ,offset().top是元素到文档顶部的距离,意思就是这个值呢如果你没操作dom正常来说,是不会发生变化滴,position是元素相对于父元素的距离就更别想了。。。没有一个对劲。。。然后我又想到了scrollTop(),你看这个跟scroll长得那么像肯定没问题!不过等我仔细看了一下API就傻了,"获取匹配的元素集合中第一个元素的当前垂直滚动条的位置或设置每个匹配元素的垂直滚动条位置",读了一遍没读明白,但是我理解的是元素在该区域内的滚动条的滚动距离,比如说你写了一个div,高度固定,然后overflow:scroll,那么该div的scrollTop就是这个内容超出后出现的滚动条的垂直距离,说了一堆感觉好像也没啥用。。。。总之就是不能单纯用scrollTop()来获取这个表头到窗口顶部的距离了。
一时间陷入了僵局。。。怎么办呢,我去厕所思考人生了。。。
嗯,经过在马桶上的思想斗争,我的思路无比开朗。既然单个不行就组合吧,使用$(‘body‘).scrollTop()与表头的offset().top差值,因为页面打开默认滚动条是在顶部的,如果要将表头滚到窗口的顶部那么,滚动条就要滚动表头的offset().top的距离,当大于这个值那么表头肯定就已经在顶部的负值区域看不到了,嗯。。。
解决了这个问题之后,我为自己欢欣鼓舞,然而,还有一个问题在等着我。那就是表头直接position:fixed的话,实际上此时表头已经脱离了正常的文档流。除了里面的内容样式都已经没了啊,我摔!就算勉强加上了样式,因为表格的内容是自由扩展的,所以每一列的列宽是由表头和表内的元素共同决定的,单独把表头拿出来是不行不行滴啊!!
然后,嗯,我动态生成了一个div,clone了整个表,获取表头的高给这个div,然后让这个div overflow:hidden了!天阿鲁,我简直就是个天才。不再废话了,献上源码~
<script src="js/jquery-latest.js"></script> <script> $(function(){ var scroll_bar = $("#scroll_bar");//表格的id var bar_head = $("#bar_head");//表头 var bar_height = bar_head.height();//表头高 var sroll_header= scroll_bar.clone().attr(‘id‘,‘bb‘);//更改复制的表格id $(window).scroll(function(){ var scroll_top = $(‘body‘).scrollTop() - scroll_bar.offset().top;//判断是否到达窗口顶部 if (scroll_top > 0) { $(‘body‘).append(‘<div id="shelter"></div>‘);//复制的表格所在的容器 $("#shelter").css({‘height‘:bar_height,‘position‘:‘fixed‘,‘top‘:‘0‘,‘overflow‘:‘hidden‘,‘width‘:‘1200px‘,‘margin‘: ‘0 auto‘,‘left‘:‘0‘,‘right‘:‘0‘,‘border-bottom‘:‘1px solid #c8c8c8‘}); sroll_header.appendTo(‘#shelter‘); $(‘#shelter table‘).removeClass(); //删除table原来有的默认class,防止margin,padding等值影响样式 $(‘#shelter table‘).css({‘width‘:‘100%‘,‘background-color‘:‘#f0f0f0‘}); $(‘#shelter table tr th‘).css({‘height‘: bar_height,‘width‘:‘140px‘,‘border‘:‘1px solid #c8c8c8‘});//此处可以自行发挥 $(‘#shelter table tr td‘).css({‘padding‘:‘10px‘,‘text-align‘:‘center‘}); $(‘#shelter‘).show(); }else { $(‘#shelter‘).hide(); } }); }); </script>
另外附上一个我找的其他实现方法,但是我觉得太重,所以放弃了,还是把链接放下大家自己参考吧
http://www.uedsc.com/sticky-table-headers-columns.html
就这么多吧,欢迎各位童鞋批评质疑~