Быстрый поиск по большому списку с помощью jQuery - PullRequest
4 голосов
/ 15 сентября 2009

Я использую этот код для поиска около 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.

Как я могу сделать это быстрее, и как я могу искать только текст ABC в li, а не теги 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();
    }   
});

Ответы [ 4 ]

7 голосов
/ 15 сентября 2009

Сначала кэшируйте все элементы в объекте:

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
    }
}
2 голосов
/ 15 сентября 2009

Для начала я бы использовал 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();
    }
}
0 голосов
/ 06 июля 2016

Я также нашел эту ссылку очень полезной, вы должны проверить это. Ну вот: " Поиск в реальном времени по списку HTML с использованием jQuery - плагин не требуется"

0 голосов
/ 15 сентября 2009

Я не являюсь javascript-кодером или знакомым с jquery, но недавно у меня была похожая проблема с деревом каталогов js eye-candy для предложения спецификации проекта.

Регулярное выражение, очевидно, является вашим узким местом. Разве в javascript не предусмотрены эффективные функции обработки массивов вместо полных издержек регулярного выражения? Разве тег <li> уже анализируется в массиве DOM при анализе HTML при загрузке документа? Должно быть просто пройтись по дереву DOM по этим <li> узлам, скопировав их в массив, а затем использовать функцию «find_value» в результирующем массиве для поиска значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...