我正在做的一个项目需要对用户选择器进行排序,按网络分组。目前我的做法是创建用户:
clone += '<li class="'+ this.gender +'" data-id="'+ this._id +'">';
clone += '<img src="'+ this.image +'" />';
clone += '<span>'+ this.name +'</span>';
clone += '</li>';
然后,拥有一个以网络名称为键,以用户ID数组为值的jQuery对象,例如:
{
Network 1: [1,2,3,4]
Network 2: [5,6,7,8]
}
然后,当选择一个网络时,我会遍历所有的li元素并将它们与id数组匹配,如果不包含该id,则隐藏li元素,像这样:
for(var i = 0, n = education_ids[network].length;i < n;i++){
$('.friends-list li[data-id='+ education_ids[network][i]+']').removeClass('chosen_network');
}
很不幸,这种方法非常低效,因为对于循环的每一个迭代,jQuery选择器都会遍历所有的 li 元素,因此如果有 1000 个朋友和 100 个网络 id,则需要进行 100 x 1000 步迭代。
为了解决这个问题,我的解决方案是将 jQuery 对象添加到数组中而不是添加它们的 id,这样我就可以迭代它们并添加类(减少了 1000 倍的迭代)。以下是我目前尝试这样做的方式:
clone += '<li class="'+ this.gender +'" data-id="'+ this._id +'">';
clone += '<img src="'+ this.image +'" />';
clone += '<span>'+ this.name +'</span>';
clone += '</li>';
if(this.education){
for(var i = 0, n = this.education.length; i < n ; i++){
if(education[this.education[i].school.name]){
education[this.education[i].school.name]++;
education_ids[this.education[i].school.name].push($(clone));
} else {
education[this.education[i].school.name] = 1;
education_ids[this.education[i].school.name] = [$(clone)];
}
}
}
相关部分是当我:
.push($(clone)
或通过以下方式初始化数组:
[$(clone)]
很遗憾,这种技术行不通,因为在程序的这一点上,元素实际上还没有添加到DOM中。所以,我的问题是:
是否有可能在它们被放入DOM之前初始化这些jQuery引用,如果可以,我该如何做呢?
如果我做不到这一点,你能否想到更有效的方法来解决这个问题。
仅供参考,我试图让这个过程更快,因为目前的策略会使循环在1到2秒之间冻结DOM,这对用户来说并不是理想的体验。
非常感谢您能提供的任何帮助!
编辑:取得进展,但出现错误!
好的,所以我已经取得了一些进展。使用jQuery选择器确实有效,所以现在我正在进行以下操作:
clone += '<li class="'+ this.gender +'" data-id="'+ this._id +'">';
clone += '<img src="'+ this.image +'" />';
clone += '<span>'+ this.name +'</span>';
clone += '</li>';
clone = $(clone)
if(this.education){
for(var i = 0, n = this.education.length; i < n ; i++){
if(education[this.education[i].school.name]){
education[this.education[i].school.name]++;
education_ids[this.education[i].school.name].push(clone);
} else {
education[this.education[i].school.name] = 1;
education_ids[this.education[i].school.name] = [clone];
}
}
}
placeholder.push(clone);
然后循环遍历所有的朋友之后,
$('.friends-list').append(placeholder).fadeIn();
我认为那应该是可以工作的,但现在我收到了以下信息:
Uncaught Error: NOT_FOUND_ERR: DOM Exception 8
您的想法如何?
编辑:更多进展,已解决错误,但排序无效。
好的,我像 @Artimuz 一样将占位符切换为空 div 来修复错误,但现在排序不起作用了。所以,基本上我是这样排序的:
if("network is clicked and it was already selected") {
for(var person in education_ids[network]){
person.removeClass('chosen_network');
}
} else //if it wasn't already selected {
for(var person in education_ids[network]){
person.addClass('chosen_network').removeClass('disabled');
}
}
很遗憾,这并不起作用。我得到了以下信息:
Uncaught TypeError: Object 0 has no method 'addClass'
所以,我再次问:你的想法是什么?
o = $('<div>').addClass('test')
),将其存储在数组中(a = [o]
),然后将其添加到DOM中($('body').append(a[0])
)没有任何问题。因此,我认为这不是“相关部分”。 - Thomas Guilloryfor
循环 (for (i;i<count;i++)
)。http://jsfiddle.net/3xqx5/2/ - Thomas Guillory