js实现表头悬浮

来源:互联网 发布:unity3d室内漫游 编辑:程序博客网 时间:2024/05/17 03:15

   在网上看到很多表头悬浮的代码,发现都无法使用。要么太冗长,要么不够通用。自己研究思路写了一个简洁的表头悬浮代码,放在哪里都可以运用。

   思路:

   表头悬浮指 当页面滚动条往下拉,当拉到看不到表头的那个阶段时,我们还需要让表头悬浮在页面的最上方,来表明表体中哪一列数据对应的是什么列名。既然表头就一直固定在页面上方,那么肯定脱离了正常的文档流,考虑到使用position:fixed来固定位置。但是,不可能对原有表格中的表头进行fixed,原来的表头如果脱离了文档流,整个表格肯定就乱套了啊。所以,我们要新写一个一毛一样的表头,然后通过position:fixed;top:0px;固定在顶部。

   那么问题就来了,由于表格中每一列的宽度是根据表格内容自适应的,我如果只写表头,我怎么知道每一列该设置多宽呢?现在就到了实现的关键了:我的思路就是动态地获取原有表格中表头的宽度,然后赋值给我的新表头,这样两者的宽度就做到同步了。何为动态呢?指我会监听界面拉伸事件,当界面大小变化时将两边宽度再次同步。

   代码:

<div id="fixedTableHeader" style="display: none; position: fixed;top: 0px;overflow:hidden;margin: 0 auto;z-index: 9999;">                    <table>                        <thead>                        <tr id="mytr1">                            <th>排期</th>                            <th>游戏</th>                            <th>时间</th>                            <th>总费用</th>                        </tr>                        </thead>                    </table>                </div>                <div>                    <table>                        <thead id="biaotou">                        <tr id="mytr2">                            <th>排期</th>                            <th>游戏</th>                            <th>时间</th>                            <th>总费用</th>                        </tr>                        </thead>                        <tbody></tbody>                    </table>                 </div>
$(function () {//        var num = $('#mytr1').children().length - 1;        $('#mytr1').children().each(function (i, n) {//            if (num == 0) {//                return;//            }//            else {//                num--;//            }            var obj = $(n);            obj.css("width", $('#mytr2').children().eq(i).css("width"));        });        window.onresize = function () {//            var num = $('#mytr1').children().length - 1;            $('#mytr1').children().each(function (i, n) {//                if (num == 0) {//                    return;//                }//                else {//                    num--;//                }                var obj = $(n);                obj.css("width", $('#mytr2').children().eq(i).css("width"));            });        }        window.onscroll = function () {            if ($(document).scrollTop() > $('#biaotou').offset().top) {//判断是否滚动到了表头显示不出来的位置                $('#fixedTableHeader').show();            }            else{                $('#fixedTableHeader').hide();            }        }});

有几点需要说明:

(1)可以看到有很多注释掉的部分。是因为我之前写的时候没有写if(...)show else hide,而是直接display:block(默认)展示在页面上,这时候我发现如果新表头每一列都限制跟原来表头一样宽度时,反而最后得到的每一列宽度跟原来的都有偏差(我这里是偏大2~4px),更奇怪的是,只有chrome出现这种偏差,其它浏览器如ie,firefox,搜狗,qq之类的都是两者宽度一致,查阅资料发现可能是:chrome渲染表格跟其他浏览器不一样,他更看重整体,比如整个表头的宽度是n1,而一个一个设置列的宽度加起来之后总宽度不为n1时,chrome会进行自动地调整,导致每一列都不会是我们设定的宽度。我是受这个启发:http://zhidao.baidu.com/link?url=UmPMCNIk3ZQcJri--ckNGHhy4YP-P1zeXMCSw9fx3rTx8c_l3UTaiwpTkcGeSuZ1DO2lb8zrEzKoI_fdRmXQpq,所以我最后的解决办法就是最后一列不设置宽度,让它能够自适应。果然,这样之后,chrome显示的就正常了:除最后一列以外,前面的列都是我们设置的宽度。

    但是我发现套上if(...)show else hide之后,这种情况又改变了,前面几列都正常,最后一列被缩得不正常。然后我就把最后一列的判断去掉,即 将文中那段注释掉,发现又能正常显示了。所以chrome也是可以一列一列地全部设置宽度的??这个很神奇,套了个show,hide就好了,我也是很懵逼的。总之,那就去掉吧,反正能正常显示。

(2)最初我是使用if ( $("body").scrollTop()  > $('#biaotou').offset().top )来判断页面滚动是否到表头之下,但是我发现其它浏览器都好好的,唯独firefox行不通,一直不能触发if条件内部的语句。为什么呢?然后我就发现firefox中无论怎么滚动,$("body").scrollTop()始终为0。去网上查了一下,发现别人是这么说的。见http://www.phpvar.com/archives/2837.html

“firefox下,带dtd文档申明:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
的页面不支持document.body.scrollTop,使用document.body.scrollTop来获取滚动值自然就会始终返回0,这就不难解释为什么 firefox下使用jq的方法:$("body").scrollTop()值始终为0啦。符合标准规范的标准写法是:document.documentElement.scrollTop 。
可以定义一函数来解决这个问题:

<script type=”text/javascript” >function getScrollXY(){var x,y;if(document.body.scrollTop){ //非标准写法,chrome能识别x=document.body.scrollLeft;y=document.body.scrollTop;}else{ //标准写法x=document.documentElement.scrollLeft;y=document.documentElement.scrollTop;}return {x:x,y:y};}
对应的getScrollXY().y就是scrollTop值了!

上面是原生js的处理方法,使用jq完全可以使用下面任一种变通写法:(原网页中下面第一种写法试过在chrome下无效,故删去)
$(document).scrollTop();
$(window).scrollTop();

(3)还需要注意的是我在$(function () {一开始就进行了原表头的宽度赋值给新表头,但是之后有可能有后续页面加载函数在表格中塞入某些元素导致宽度改变,所以建议把宽度赋值的函数放在$(function () {最后。如果还是不确定的话,干脆就放在window.onscroll的函数里得了,虽然影响加载速度,但是确保新表头能对应旧表头的宽度。

0 0
原创粉丝点击