Javascript 性能:大表鼠标悬停效果

Javascript 性能:大表鼠标悬停效果,javascript,jquery,html,performance,Javascript,Jquery,Html,Performance,HTML <table> <tr data-parent="0" data-id="1"> <td></td> </tr> <tr data-parent="1" data-id="2"> <td></td> </tr> <tr data-parent="1" data-id="3"> &l

HTML

<table>
    <tr data-parent="0" data-id="1">
        <td></td>
    </tr>
    <tr data-parent="1" data-id="2">
        <td></td>
    </tr>
    <tr data-parent="1" data-id="3">
        <td></td>
    </tr>
    <tr data-parent="3" data-id="4">
        <td></td>
    </tr>
</table>
(我知道我也可以编写一个递归函数,这不是现在的重点)

当有人将鼠标移到TR上时,我希望该行是一种颜色,所有将悬停行作为父行的行是另一种颜色,子行是另一种颜色,等等(对于几个级别)

现在,对于100行,这不是问题,但是我的数据包含大约30000行,这就是它开始出错的地方,几秒钟的冻结错误

如何优化此代码


为了您和我的方便:一个JSFIDLE

首先,单个表中的30000行是一个可用性问题;有些浏览器甚至无法很好地处理这样一个怪物。试着找到一种方法来缩小尺寸

现在有一些解决办法

您可以使用
id
而不是
数据id
。浏览器为具有ID的元素保留一个高效的查找表。在jQuery中,您可以使用
$('#'+id)
查找DOM节点,这非常快(如果有30K行,则不会扫描整个树,这将是巨大的)

如果不能这样做,则将引用保留在JavaScript对象中,通过简单的键查找可以获得父/子对象,即
lookup[parentId]
应返回带有此
parentId
的TR节点。这意味着只解析一次表,或者根本不使用
data
属性

另一种方法是使用jQuery的
data()
函数,它允许您将任意值附加到DOM节点。这样,您就可以在DOM节点中查找相关节点,并保留引用,而不是每次都搜索整个文档


最后,级别的数量和每个级别的节点数量对性能有很大的影响。您的算法是O(N1*N2*N3*N4*…*NM)(其中M是级别数)。所以如果你有N2=5,N2=3,N3=4,那么你已经需要处理5*3*4*。。。节点。无论您如何查找,在一个巨大的文档中更改1000个节点都是昂贵的。

我建议,如果您有30000行,您应该将其作为可搜索/可分页列表进行查找。将这么多数据呈现给用户会适得其反。您是否可以预处理数据,使每行都具有属性
数据祖先-
,其中
n
标记相对于当前节点的代数?因此,您可以避免显式迭代(例如,使用
$(“tr[data-祖先-2=”+$(this).attr(“data-id”)+“']”])).css(“background color”),“98E8E3”);
this
的后代着色。)@Rorymcrossan我知道数据太多的问题,我们正在积极寻找更好的方法来缩小数据池,但目前,恐怕我们必须处理所给予的。谢谢,这一点,再加上codereview的人告诉我的,应该会给我足够的改进来解决问题。我们也在寻找减少行数的方法。
$("tr[data-parent='" + id + "']").css("background-color", "#1ba1e2").each(function () {
    $("tr[data-parent='" + $(this).attr("data-id") + "']").css("background-color", "#75F7FF").each(function () {
        $("tr[data-parent='" + $(this).attr("data-id") + "']").css("background-color", "#98E8E3").each(function () {
            $("tr[data-parent='" + $(this).attr("data-id") + "']").css("background-color", "#B6DCE8")
    });});});