我有一个网页,其中包含每个都有标签的项目列表。我希望按标签过滤它们,使用逻辑AND对它们进行排序:要显示项目必须包含所有选定的标记。
但我也有一个特殊的“null”排序属性。如果选中它,则无论什么都不能显示没有标签的元素。
我已经实现了它,但出于好奇,我尝试做得更好,但不能。这可以只用一个条件来完成吗?或者这是好事吗?
var activeTags = getAllCurrentlyActiveTags();
$('#list>li').show();
$.each(activeTags, function(index, tag) {
$('#list>li').each(function() {
var myTags, keepForNull, notJustNull, currentFailCheck;
// Array of tags for the current item.
myTags = getMyTags(this);
keepForNull = activeTags.indexOf('null') !== -1 && myTags.length === 0;
notJustNull = tag === 'null' && !(activeTags.length === 1 && activeTags[0] === 'null');
currentFailCheck = myTags.indexOf(tag) === -1;
if (keepForNull) {
return;
}
if (notJustNull) {
return;
}
if (currentFailCheck) {
$(this).hide();
}
});
});
有更好的方法吗?
答案 0 :(得分:1)
这是一个小改进怎么样?
var activeTags = getAllCurrentlyActiveTags();
//// no need to search the active tags array for 'null' repeatedly
var hasNull = activeTags.indexOf('null') !== -1;
//// only fetch the list items from the DOM once
$('#list>li').each(function() {
//// keep a flag so we don't hide and/or show the same item more than once
var show = true;
//// only fetch tags for each list item once
// Array of tags for the current item.
var myTags = getMyTags(this);
//// if we're keeping it, skip the loop over tags
var keepForNull = hasNull && myTags.length === 0;
if (!keepForNull) {
//// use a for loop so the the early 'break' is clear
for(var index = 0; index < activeTags.length; index++) {
var tag = activeTags[index];
//// simplified but equivalent condition
var notJustNull = tag === 'null' && activeTags.length !== 1;
if (notJustNull) {
continue;
}
//// only search myTags array when all other checks pass
var currentFailCheck = myTags.indexOf(tag) === -1;
if (currentFailCheck) {
show = false;
//// don't need to look at any more tags
break;
}
}
}
//// only show/hide once as appropriate
show ? $(this).show() : $(this).hide();
});
如果您可以修改更宽的逻辑,那么您可以进一步改进它,因为当用户激活(非空)标记或取消激活空标记时,您只需要查看可见的项目即可工作隐藏哪些。反之亦然。
(OT:我认为最好将var
与变量放在一起 - 这样可以更容易地扫描意外的全局变量。)