5

我想做的事:将页面上的所有类似元素(某种类型)分组到一个对象中,我以后可以对其进行迭代——或者对其中的每个元素应用彻底的更改。

我的代码成功地完成了给定的任务,但是当元素数量增加到 200-300+ 时,性能急剧下降并且用户已经注意到了。我已经隔离了有问题的代码行,并想知道是否有另一种方法可以解决同样的问题。

根据我在它们周围放置的计时器,add() 函数似乎是有问题的操作。起初,执行该操作所需的时间是 0.001,但会一直增长,直到元素数量达到 300 个,并且每个附加元素需要大约 0.1 秒,并且继续减慢。

我已经研究了(以及更多)jQuery 性能增强能力,并实现了其中的一些(即 3 个),但它们并没有给我带来任何有意义的性能提升。令人惊讶的是,对于 Firefox(300 多次 add() 调用),此代码在 1 秒内 (!) 执行,而 Chrome 和 IE 大约需要 10-20 倍或更长时间......

这是我的代码:

rowsToChange = $([]);
// Grab all the ids greater than whichever one I'm currently looking at:
var arr = $.makeArray($("[id^=stackLocatorLinkFillUp]:gt("+(uniqueID-1)+")"));
for (var i=0; i<arr.length; i++) {
    $this = arr[i];
    // <<< VARIOUS CONDITIONALS that make this as selective as possible REMOVED >>>
    startTimer = new Date().getTime();
    // **************************
    // PROBLEMATIC LINE FOLLOWS when 200+ records:
    rowsToChange = rowsToChange.add($this);
    // Grows from .001 to .1xx after 300 iterations
    console.log("innertiming:"+(new Date().getTime() - startTimer)/1000);
    // **************************
}

最终结果如下所示(通过 Chrome Inspector):

[<div style=​"display:​none" id=​"stackLocatorLinkFillUp1">​itemType=BOUND&ccLocale=PERIODICAL​&lt;/div>​, 
<div style=​"display:​none" id=​"stackLocatorLinkFillUp2">​itemType=BOUND&amp;ccLocale=PERIODICAL​&lt;/div>​,
...
]

最终我按如下方式处理所有这些(我喜欢它的简单性!):

var superlink = "...new <a> goodness to display for all elements...";
rowsToChange.html(superlink).css("display","block");

这看起来可能是一个有效的解决方案(不同的添加方法?)但我更愿意继续收集对象列表,以便最后一行可以发挥其魔力。

我不是被指出以下不正确 - 关于串联;谢谢'我不是')

似乎 add() 操作必须连接字符串,因为这似乎是其他人面临的主要问题之一。但是将我的 add() 语句转换为 += 看起来不起作用。

感谢您检查这一点;

铬:18.0.1025.142 m 火狐:11.0 IE:8.0.7600.16385

4

2 回答 2

5

第一次观察:add保存前一个元素集。试试rowsToChange = jQuery.merge(rowsToChange, [$this]);吧。

第二个观察:似乎rowsToChange最终将成为与您调用的元素完全相同的元素集$.makeArray。为什么不直接保存原始集?

于 2012-04-05T19:42:20.960 回答
0

DCoder 展示了如果您使用for循环,如何将信息适当地合并在一起。但是,如果您来到这里并使用.each()循环,请使用以下内容。

主要区别在于括号是不必要/必要的,具体取决于'this'. 它似乎也被普遍接受,.each()至少原生 javascriptfor循环慢一些。(来自 2009 年的证据)(时间 test_copied 从上面的问题

var $this, rowsToChange = $([]);
// slower than a for loop
$("[id^=stackLocatorLinkFillUp]:gt("+(uniqueID-1)+")").each( function() {
    // If statements <removed> that decide whether or not to include in the new container
    $this = $(this); // probably unnecessary under most situations
    rowsToChange = jQuery.merge(rowsToChange, $this);
});

对删除的 if 语句决定的新子组的每一部分进行操作!

rowsToChange.html("...");

感谢所有查看问题、花时间回答、投票等的人!

于 2012-04-06T18:14:22.957 回答