代码之家  ›  专栏  ›  技术社区  ›  Chris B

javascript-显示和隐藏大量列表项的最快方法

  •  5
  • Chris B  · 技术社区  · 17 年前

    当用户在谷歌地图周围平移时,会更新当前可见标记的列表。这个列表最多包含1000个项目,当几百个li同时显示或隐藏时,它会变慢。还不到半秒钟,但这让人恼火。

    数组(newlilist)包含现在应该可见的项。另一个数组(currentlilist)具有以前可见的项。两个数组都包含作为索引的LI的ID。

    for (var i in newLiList) {
        if (currentLiList[i] != true) {
            $("ul#theList li#"+i).show();
        }
    }
    for (var i in currentLiList) {
        if (newLiList[i] != true) {
            $("ul#theList li#"+i).hide();
        }
    }
    

    有更快的方法吗?

    6 回复  |  直到 17 年前
        1
  •  5
  •   John Kugelman Michael Hodel    17 年前

    你可以储存 <li> 直接在数组中查找元素,这样就不必执行数百个CSS选择器查找。那么,而不是 $("ul#theList li#"+i) 你只要做 liArray[i] .

    FYI "ul#theList li#<i>" 相当于 "#<i>" 因为元素ID是(应该是)唯一的。你不需要额外的上下文。

        2
  •  5
  •   seanmonstar    17 年前

    对于每个.show()和.hide()函数调用,都会导致在浏览器中重新绘制。

    在更改列表项之前将整个列表设置为“不显示”,将阻止浏览器每次重新计算文档流,然后可以将列表设置回“阻止”。

    或者,如果不希望列表的闪烁消失,可以克隆列表,隐藏所有应隐藏的项,然后用新列表替换旧列表。

        3
  •  3
  •   Mike Robinson    17 年前

    您应该尝试缓存选择器并使用上下文:

    var targetList = $("ul#theList");
    

    替换:

    $("ul#theList li#"+i).show();
    

    具有

    $("#"+i, targetList).show();
    

    这将减少jquery在整个DOM中来回跳跃的次数。

        4
  •  0
  •   Gareth Simpson    17 年前

    您可以尝试在重置所有列表项时隐藏列表。它可能会阻止一些重画。

    另外,考虑使用

    $("ul#theList li#"+i).attr("display","none");
    
    $("ul#theList li#"+i).attr("display","block");
    

    而不是hide()和show(),因为它们可以接受一个速度参数来制作精美的动画。我不知道如果你不使用的话,它们是否会变慢,但值得检查一下。

        5
  •  0
  •   SolutionYogi Eric Lippert    17 年前

    您对您的代码进行了分析吗?

    不要假设代码的哪个部分运行缓慢,在Firebug中分析代码(假设您使用的是Firefox)并调整运行较慢的代码。

        6
  •  0
  •   googletorp    17 年前

    这很可能很慢,因为您要求jquery遍历DOM几百次。如果用逗号分隔的所有ID组成一个字符串,则可以选择并隐藏/显示所有ID。

    让我澄清一下我的意思,因为如果您只做$(string_elements),jquery将导致遍历每个元素的整个DOM。

    $("ul#theList").find(string_of_elements).show()
    

    使用这种语法,jquery将首先找到ul元素,然后只需遍历它就可以找到li元素。现在,如果您将两个列表都转换为一个字符串,则可以执行一些非常简单的操作:

    $("ul#theList")
        .find(string_of_elements_to_show).show().end()
        .find(string_of_elements_to_hide).hide();
    

    使用这种语法和链接两个事件还有另一个优势。实际的显示和隐藏将同时发生,而不是一个接一个的隐藏和显示。