我有一个大约500个项目的HTML列表,上面有一个“过滤器”框。当我输入一个字母时,我开始使用jQuery来过滤列表(稍后添加的时间码):
$('#filter').keyup( function() {
var jqStart = (new Date).getTime();
var search = $(this).val().toLowerCase();
var $list = $('ul.ablist > li');
$list.each( function() {
if ( $(this).text().toLowerCase().indexOf(search) === -1 )
$(this).hide();
else
$(this).show();
} );
console.log('Time: ' + ((new Date).getTime() - jqStart));
} );
然而,在输入每个字母后(特别是第一个字母),有几秒钟的延迟。所以我认为如果我使用普通的Javascript(我最近读到jQuery的each
函数特别慢)可能会稍快一点。这是我的JS等价物:
document.getElementById('filter').addEventListener( 'keyup', function () {
var jsStart = (new Date).getTime();
var search = this.value.toLowerCase();
var list = document.querySelectorAll('ul.ablist > li');
for ( var i = 0; i < list.length; i++ )
{
if ( list[i].innerText.toLowerCase().indexOf(search) === -1 )
list[i].style.display = 'none';
else
list[i].style.display = 'block';
}
console.log('Time: ' + ((new Date).getTime() - jsStart));
}, false );
令我惊讶的是,普通的Javascript比
这不是真正重要的事情,因此不需要超级高效。但是我在这里使用Javascript做了一些非常愚蠢的事情吗?
答案 0 :(得分:28)
您可以尝试使用textContent
代替innerText
,我认为它应该更快。同时对列表生成和循环进行单独计时也可以判断列表生成是否存在问题。
答案 1 :(得分:4)
javascript速度的另一个最佳实践是在变量中缓存list.length
并调用变量,如:
l = list.length;
for (var i=0;i<l;i++):{ code here}
也许jsperf的时机会更好。
答案 2 :(得分:2)
在这里,我稍微重构了一下你的代码:
var filter = document.getElementById( 'filter' ),
ablist = document.querySelector( '.ablist' );
filter.addEventListener( 'keyup', function () {
var re, elems, i, len, elem;
re = RegExp( this.value, 'i' );
elems = ablist.children;
for ( i = 0, len = elems.length; i < len; i += 1 ) {
elem = elems[i];
elem.style.display =
elem.textContent.search( re ) > -1 ? 'list-item' : 'none';
}
}, false );
现场演示: http://jsfiddle.net/MVFxn/
的变化:
i
标记,不需要toLowerCase
,'.ablist'
元素,querySelector
应该是获取它的最快方法(因为它一旦找到第一个这样的元素就会中止查询),children
属性已经方便地引用它们。我想知道此代码在您的网页上的效果......
答案 3 :(得分:0)
我使用while
代替for
并进行了一些小改进。 Here是最终代码。
var list = list = document.querySelectorAll('ul.ablist > li');
document.getElementById('javascriptFilter').addEventListener( 'keyup', function () {
var jsStart = (new Date).getTime(),
search = this.value.toLowerCase(),
i = list.length - 1,
listItem,
result;
while( i >= 0 )
{
listItem = list[i];
if ( listItem.textContent.toLowerCase().indexOf(search) === -1 )
listItem.style.display = 'none';
else
listItem.style.display = 'block';
i--;
}
result = ((new Date).getTime() - jsStart);
console.log(['Time: ', result, '<br />'].join(''));
}, false );