我正在使用此代码搜索大约500个li标签。
$(function() {
$.expr[":"].containsInCaseSensitive = function(el, i, m){
var search = m[3];
if (!search) return false;
return eval("/" + search + "/i").test($(el).text());
};
$('#query').focus().keyup(function(e){
if(this.value.length > 0){
$('ul#abbreviations li').hide();
$('ul#abbreviations li:containsInCaseSensitive(' + this.value + ')').show();
} else {
$('ul#abbreviations li').show();
}
if(e.keyCode == 13) {
$(this).val('');
$('ul#abbreviations li').show();
}
});
});
这是HTML:
<input type="text" id="query" value=""/>
<ul id="abbreviations">
<li>ABC<span>description</span></li>
<li>BCA<span>description</span></li>
<li>ADC<span>description</span></li>
</ul>
使用这么多li标签,这个脚本非常慢。
如何让它更快,如何只搜索li中的ABC文本,而不是搜索span标签(不更改html)?
我知道现有的插件,但我需要一个像这样的小实现。
以下是感兴趣的人的完成代码
var abbrs = {};
$('ul#abbreviations li').each(function(i){
abbrs[this.firstChild.nodeValue] = i;
});
$('#query').focus().keyup(function(e){
if(this.value.length >= 2){
$('ul#abbreviations li').hide();
var filterBy = this.value.toUpperCase();
for (var abbr in abbrs) {
if (abbr.indexOf(filterBy) !== -1) {
var li = abbrs[abbr];
$('ul#abbreviations li:eq('+li+')').show();
}
}
} else {
$('ul#abbreviations li').show();
}
if(e.keyCode == 13) {
$(this).val('');
$('ul#abbreviations li').show();
}
});
答案 0 :(得分:7)
首先将所有项目缓存到对象中:
var abbrs = {};
$("ul#abbreviations li").each(function (i) {
abbrs[this.firstChild.nodeValue] = this;
});
然后在对象中查找键入的文本:
var li = abbrs[this.value.toUpperCase()];
// show li, hide others
更新:对于部分匹配,您必须遍历该集合:
var filterBy = this.value.toUpperCase();
for (var abbr in abbrs) {
if (abbr.indexOf(filterBy) !== -1) {
var li = abbrs[abbr];
// show li
}
}
答案 1 :(得分:2)
对于初学者,我会使用new RegExp
代替eval
,看看是否有提升的效果。
我假设您正在动态填充li标签。有没有办法搜索直接填充此列表的数据结构,而不是搜索DOM对象?如果我的假设不正确,你可以在开头循环遍历列表并构建一个字符串数组,然后可以搜索它吗?
编辑:以下是如何构建字符串列表
var listTerms = [];
$("ul#abbreviations li").each(function (li) {
listTerms.push({text : li.firstChild.nodeValue, elem : li});
});
以下是搜索方式(简单循环,没什么特别之处)
var exp = new RegExp(text, "i");
for(var i=0; i<listTerms.length; i++) {
if (exp.match(listTerms[i].text)) {
$(listTerms[i].elem).hide();
}
}
答案 2 :(得分:0)
我不是一个javascript编程人员或者熟悉jquery,但我之前遇到类似的问题,有一个项目规范提案的js eye-candy目录树。
正则表达式显然是你的瓶颈。 javascript是否具有高效的数组处理函数,而不是正则表达式的全部开销?在文档加载时解析HTML时,<li>
标记是否已经解析为DOM数组?在这些<li>
节点上遍历DOM树,将它们复制到数组中,然后在结果数组上使用'find_value'类型的函数来查找值应该很简单。
答案 3 :(得分:0)
我也发现此链接非常有用,您应该查看它。干得好: ” Live Search a HTML List using jQuery – No Plugin Needed“