【覆盖select】
只要用到了定位,就不得不面对一个老对手“ie6的select”。 我在之前的文章也介绍过一些解决方法(参考这里的覆盖select),这里不能直接隐藏select,那看来只能用iframe了。 但用iframe有一个很大的问题,在ie6测试下面的代码,并拖动滚动条:
<!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"> <body> <style type="text/css"> body{height:1000px;} .t{height:300px;width:200px; border:1px solid; position:absolute; background:#FFF;top:0;left:0;} </style> <iframe class="t" id="t"></iframe> <select></select><br /> <select></select><br /> <select></select><br /> <select></select><br /> <select></select><br /> <select></select><br /> <select></select><br /> <select></select><br /> <select></select><br /> <select></select><br /> </body> </html>
可以看到,即使是iframe,在拖动滚动条的时候,select仍然在后面闪啊闪,在本程序中这个现象会尤其明显。 看来还得用隐藏select的方法,最好的做法是只隐藏在新table后面的select,而不影响其他select的正常显示。 那关键就是如何判断select是否在新table后面,这个可以通过位置坐标判断,刚好可以用到上面的getBoundingClientRect。 一般的思路是判断新table和select的坐标,根据位置判断select的显示和隐藏。 但如果有多个实例,可能会导致select在一个实例中要隐藏,却在另一个要显示的情况。
为了解决冲突,程序给select加了一个_count属性作为计数器,用来记录有多少实例把该select隐藏了。 如果当前实例判断该select要隐藏,就给其_count加1,隐藏后存放到实例的_selects集合中。 在恢复显示_selects中的select时,先给select的_count减1,如果得到的_count是0,那说明没有其他实例要隐藏它,就可以设置显示了,最后清空_selects集合。 在判断是否隐藏select前还必须恢复一次该实例_selects里面的select,否则就会造成_count只加不减的情况。
程序中的SetSelect方法就是用来判断和设置select的:
this.ResetSelect(); var rect = this._nTable.getBoundingClientRect(); //把需要隐藏的放到_selects集合 this._selects = Filter(this._oTable.getElementsByTagName("select"), Bind(this, function(o){ var r = o.getBoundingClientRect(); if(r.top <= rect.bottom && r.bottom >= rect.top){ o._count ? o._count++ : (o._count = 1);//防止多个实例冲突 //设置隐藏 var visi = o.style.visibility; if(visi != "hidden"){ o._css = visi; o.style.visibility = "hidden"; } return true; } }))
其中ResetSelect方法是用来恢复显示select的:
forEach(this._selects, function(o){ !--o._count && (o.style.visibility = o._css); }); this._selects = [];
但这个方法在快速滚屏时还是无能为力,而且select越多效率也随之下降,各位有更好方法的话欢迎交流。
【Chrome一个bug】
在测试的时候发现Chrome一个bug,测试下面代码:
<!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"> <body> <table border="1"> <tr> <td id="tt"></td> </tr> </table> <div id="t"></div> <script> document.getElementById("t").offsetWidth; document.getElementById("tt").innerHTML = "<select><option>test</option></select>"; </script> </body> </html>
一个毫不相干的操作居然令table没有自动撑开,加上前面的问题,看来Chrome的路还很长啊。
使用说明
实例化一个TableFixed对象只需要一个参数table的id:
new TableFixed("idTable");
实例化时有4个可选属性: Index: 0,//tr索引 Auto: true,//是否自动定位 Pos: 0,//自定义定位位置百分比(0到1) Hide: false//是否隐藏(不显示)
其中Index和Pos在实例化之后就不能使用。 要修改克隆行可以用Clone方法,其参数是要克隆tr的索引。 要修改自定义定位位置可以用SetPos方法,其参数是要定位的位置百分比。
具体使用请参考实例。
程序源码
代码拷贝框
[Ctrl+A 全部选择 然后拷贝]
下载完成测试代码
原文:http://www.cnblogs.com/cloudgamer/archive/2009/05/18/TableFixed.html
本文链接:http://www.blueidea.com/tech/web/2009/7012.asp
出处:蓝色理想
责任编辑:bluehearts
上一页 JavaScript Table行定位效果 [7] 下一页
◎进入论坛网页制作、WEB标准化版块参加讨论,我还想发表评论。
|