为什么这个Javascript循环需要一分钟进行100次迭代?

时间:2011-04-18 11:57:36

标签: javascript jquery

我在我的程序中使用下面的代码,但似乎这几行代码花费了太多时间来执行。对于100次迭代,它消耗大约1分钟。对于200多次迭代,我的broser正在显示一条警告消息,脚本占用了太多时间。根据场景,可以将500+个ID推入阵列。

for (var i = 0; i < arrid.length; i++)
{
    $("#" + outerDiv + "> div[id=" + arr[i] + "]").attr("class", "selected");
}

arrid是一个div div数组。 Outerdiv是arrid中存在的所有这些div的父div。 arr ids不能直接访问,必须使用父div引用,即outerDiv。

7 个答案:

答案 0 :(得分:9)

你可以做的一件事就是缓存你的选择器,这样jQuery就不必查询dom 500次了。

var $div = $("#" + outerDiv);

for (var i = 0; i < arrid.length; i++)
{
    $div.children("div[id=" + arr[i] + "]").attr("class", "selected");
}

第二个想法,因为你有一个id的列表,你不应该需要任何这个,因为每个dom的id应该是唯一的。

for (var i = 0; i < arrid.length; i++)
{
    $("#" + arr[i]).attr("class", "selected");;
}

答案 1 :(得分:3)

如果outerDiv是一个元素,你可以写

for (var i = 0; i < arrid.length; i++)
{
    $("#" +arr[i], outerDiv).attr("class", "selected");
}

但假设id是唯一的,你根本不需要引用外部div。它甚至可能更快。

另外,如果这就是你正在做的事情并且你关注性能,为什么不使用普通的'javascript?

for (var i = 0; i < arrid.length; i++)
{
    document.getElementById(arr[i]).className = "selected";
}

答案 2 :(得分:1)

不要多次调用jQuery选择函数

而是选择您的元素一次,然后以不同的方式完成其余的工作。为了实现这一点,最好将arr ID数组转换为可以使搜索速度更快的协同数组。

// convert arr = ["idOne", "idTwo", ...]
// into an associative array/object
// a = { idOne: true, idTwo: true, ... }
var a = {};
$.each(arr, function(index, el){
    a[el] = true;
})

// do the rest
$("#" + outerDiv " > div[id]").each(function(){
    if (a[this.id] === true)
    {
        $(this).addClass("selected");
    }
})

最内在的呼叫也可以替换为:

this.className = "selected"

当你可以确定没有其他类将被添加到元素时。

但是当您想要在所有子div元素上设置选中(如果您的ID涵盖所有元素),那么简单:

$("#" + outerDiv " > div[id]").addClass("selected");

可以做到这一点。

答案 3 :(得分:1)

使用jQuery函数很昂贵 - 正如操纵DOM一样。

你可以减少一次对jQuery的调用:

var divSelector = [];
for (var i = 0; i < arrid.length; i++)
{   // add selector to array
    divSelector.push( "#" + outerDiv + "> div[id=" + arr[i] + "]" );
}
// execute jquery once with many selectors
$(divSelector.join(',')).attr("class", "selected");

此代码未经测试,但应该在原则上运行。

答案 4 :(得分:0)

将实例存储到变量($ div)中,并使用另一个变量来存储循环的最大长度。

var $div = $("#" + outerDiv);
for (var i = 0, max = arrid.length; i < max; i++)
{
    $div.children("div[id=" + arr[i] + "]").attr("class", "selected");
}

答案 5 :(得分:0)

如果您拥有试图更改课程的所有元素的ID,那该怎么做:

for (var i = 0; i < arrid.length; i++)
{
    $("#" + arr[i]).addClass("selected");
}

我知道使用选择器div [id = val]执行速度很慢是基于我跑的速度测试的某些浏览器,值得一看,因为它非常有趣:

http://mootools.net/slickspeed/

答案 6 :(得分:0)

我认为你可以直接将jQuery对象推送到数组,然后就可以arr[i].attr('class', 'selected')