JavaScript Table行定位效果(6)

只要用到了定位,就不得不面对一个老对手“ie6的select”。
我在之前的文章也介绍过一些解决方法(参考这里的覆盖select),这里不能直接隐藏select,那看来只能用iframe了。
但用iframe有一个很大的问题,在ie6测试下面的代码,并拖动滚动条:


[Ctrl+A 全选 注:引入外部Js需再刷新一下页面才能执行]


可以看到,即使是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,测试下面代码:


[Ctrl+A 全选 注:引入外部Js需再刷新一下页面才能执行]


一个毫不相干的操作居然令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 全选 注:引入外部Js需再刷新一下页面才能执行]


下载完成测试代码
转载请注明出处:

您可能感兴趣的文章:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wjwjsp.html