网络编程
位置:首页>> 网络编程>> JavaScript>> JavaScript Table行定位效果(8)

JavaScript Table行定位效果(8)

作者:cloudgamer 来源:cloudgamer博客 发布时间:2009-05-25 10:47:00 

标签:JavaScript,表格,定位,table

【覆盖select】

只要用到了定位,就不得不面对一个老对手“ie6的select”。
我在之前的文章也介绍过一些解决方法(参考这里的覆盖select),这里不能直接隐藏select,那看来只能用iframe了。

但用iframe有一个很大的问题,在ie6测试下面的代码,并拖动滚动条:

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

一个毫不相干的操作居然令table没有自动撑开,加上前面的问题,看来Chrome的路还很长啊。

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com