Статьи

Легко реализовать эффект живого поиска

Эффект живого поиска не новость в настольных приложениях. В Mac OS X или Windows Vista / 7, просто введите несколько букв в поле поиска, почти мгновенно вы получите результат поиска на лету. Необходимость нажать кнопку отправки становится старой школой.

Из этого туториала вы узнаете, как сделать этот крутой эффект в мире Интернета с помощью jQuery. Код, используемый в этом руководстве, изменен в соответствии с подходом Джона Резига .


Эффект Livesearch в Windows 7


Эффект Livesearch в OS X



  • Представляет результат поиска на лету
  • Нечеткий Поиск
  • Супер быстрый, без AJAX звонков

Для начала нам понадобится несколько HTML-элементов, в том числе:

  • Текстовый ввод , в который мы вводим наши запросы.
  • Неупорядоченный список , чтобы показать результат поиска

… и две библиотеки javascript:

  • jQuery : вам нужно будет хотя бы знать это, чтобы пройти этот урок.
  • Quicksilver Score : Этот замечательный скрипт имитирует известный алгоритм Quicksilver livesearch на Mac. Он сообщает, актуальны ли две текстовые строки, и насколько они актуальны. Это как мини-гугл в одном файле js. Всем нравится нечеткий поиск, верно? И все они, как результаты поиска, отображаются от самых актуальных до наименее. Благодаря отличной работе Lachie Cox !

И последнее, но не менее важное: нам нужно искать элементы. В этом руководстве давайте использовать имена многих веб-фреймворков в качестве фиктивных данных, хорошо? (См. Список этих платформ )

Данные «из поиска» могут быть предоставлены в массивах, JSON или в любой форме, если они могут быть зациклены в javascript. Можно также использовать многомерные массивы. Но для простоты демонстрации и понимания данные, используемые в этом руководстве, представляют собой простой одномерный массив, называемый «элементы».

И, наконец, вот HTML. Обратите внимание на то, где включены две библиотеки JS. Примечание: CSS не является ключевой частью этого эффекта, поэтому мы не будем тратить ни секунды на стилизацию. Они минифицированы. Надеюсь, это не будет беспокоить или отвлекать вас. Давайте сосредоточимся на HTML и JS.

Сохраните следующий код в HTML-файл, и начнем!

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN” “http://www.w3.org/TR/html4/strict.dtd”>
<html>
    <head>
        <meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″>
        <title>jQuery Livesearch Effect</title>
        <style>
            *{font-family:Tahoma,Geneva,sans-serif}body{background:#175082}h1{color:#069;font-size:40px;font-family:Georgia,”Times New Roman”,Times,serif;line-height:50px;padding-bottom:10px;vertical-align:top;border-bottom:1px dashed#09F}h4{color:#000;font-size:20px;font-weight:normal}div#all{width:700px;position:relative;margin:40px auto;border:5px solid#09F;background:#DDF2FF;padding:0px 25px 50px 25px}input#q{width:300px;height:30px;line-height:30px;font-size:26px;border:2px solid#CCC;padding-left:5px}span#tip{font-size:12px;line-height:30px;margin-left:15px;color:#F30;font-weight:bold;margin-bottom:10px}ul#results li{color:#666;line-height:1.7em}
        </style>
    </head>
    <body>
        <div id=”all”>
            <h1>jQuery Livesearch Demo</h1>
            <h4>Find Your Favourite Web Framework</h4>
            <input id=”q” />
            <span id=”tip”><– Type in here and get search results LIVE!
            <ul id=”results”></ul>
        </div>
          
<script type=”text/javascript” src=”http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js”></script>
<script type=”text/javascript” src=”http://rails-oceania.googlecode.com/svn/lachiecox/qs_score/trunk/qs_score.js”></script>
<script>
// A placeholder for the real code
</script>
<script>
    var items = [“Agavi”,”AIDA Web”,”Akelos”,”Apache Click”,”Apache Cocoon”,”Apache Struts”,”Apache Wicket”,”AppFuse”,”Aranea”,”ASP.NET MVC”,”Axiom Stack”,”BFC”,”CakePHP”,”DooPHP”,”Camping”,”Catalyst”,”CherryPy”,”CodeIgniter”,”ColdSpring”,”Csla”,”CppCMS”,”CubicWeb”,”Django”,”Drupal”,”DotNetNuke”,”eZ Components”,”Flex”,”FUSE”,”Fusebox”,”Google Web Toolkit”,”Grok”,”Grails”,”Hamlets”,”Helix”,”Horde”,”Interchange”,”ItsNat”,”IT Mill Toolkit”,”JavaServer Faces”,”JBoss Seam”,”Kepler”,”Kohana”,”KumbiaPHP”,”Lift”,”LISA”,”ManyDesigns Portofino”,”Mason”,”Maypole”,”Mach-II”,”Merb”,”Midgard”,”Model-Glue”,”MonoRail”,”Morfik”,”Nitro”,”onTap”,”OpenACS”,”OpenLaszlo”,”OpenXava”,”Orbit”,”Orinoco”,”PEAR”,”PHP For Applications”,”PHP Work”,”Pyjamas”,”Pylons”,”Qcodo”,”RIFE”,”Ruby on Rails”,”Samstyle”,”Seaside”,”Shale”,”SilverStripe (Sapphire)”,”Simplicity”,”Sinatra”,”SmartClient”,”Sofia”,”SPIP”,”Spring”,”Stripes”,”Symfony”,”Tapestry”,”ThinWire”,”Tigermouse”,”Vaadin”,”TurboGears”,”Wavemaker”,”web2py”,”WebObjects”
</script>
    </body>
</html>

Как парень из JavaScript, вы не можете жить без Firebug сегодня. Это определенно необходимо для любого, кто работает с jQuery. Вы можете пройти этот урок без установленного firebug. Но с помощью firebug мы можем видеть много закулисных вещей, что очень важно для понимания поиска в этом эффекте.

Помните фиктивные предметы для поиска? Да, рамки имен. Давайте проверим, находятся ли они в нужном месте с Firebug:

  1. Откройте файл HTML с помощью Firefox.
  2. Откройте Firebug и переключитесь на панель «Консоль» (ctrl + shift + c).
  3. Введите «элементы» (без кавычек) в поле справа и нажмите «Выполнить».

Вы должны увидеть что-то, показанное на изображении ниже. Firebug выводит переменную “items”, которая является массивом. Да, наши каркасные имена прямо на месте. Продолжим!



Теперь поговорим о логике. Чтобы этот эффект заработал, необходимо выполнить последовательность действий:

  1. Пользователь нажимает клавишу.
  2. Мы получаем текст окна поиска. Давайте назовем этот «запрос».
  3. Для каждого имени фреймворка мы проверяем, уместен ли запрос и насколько он актуален.
  4. Мы отфильтровываем соответствующие имена фреймворков и сортируем их по релевантности.
  5. Мы представляем результат пользователю.

Полегче, а? За исключением одного. Если я ищу структуру, называемую «торт», логика выше, один цикл на букву, всего 4 цикла, верно? Но первые 3 цикла совершенно не нужны, только для значительного снижения производительности. Чтобы смягчить это, мы подождем, пока пользователь перестанет набирать текст, прежде чем использовать нашу логику. И если пользователь перестает набирать на 0,2 секунды, мы предполагаем, что он заканчивает. На данный момент наша логика достаточно тонкая. Пришло время запачкать руки и начать кодировать!


В реальной жизни слушание может быть чрезвычайно важным. Это также верно в мире jQuery, где все начинается с прослушивания события.

Ищите «заполнитель» в файле HTML. Поместите следующий код в это место.

Следующий код прослушивает событие keyup. Добавьте их между тегом <script>, и мы пройдем через несколько ключевых точек.

01
02
03
04
05
06
07
08
09
10
11
12
13
$(function(){
    var t = null;
    $(“#q”).keyup(function(){
        if (t) {
            clearTimeout(t);
        }
        t = setTimeout(“filter()”, 200);
    });
});
  
function filter(){
// Filter logic comes here
}
  1. Код выполняется, когда документ готов.
  2. Все наши логики начинаются с события keyup.
  3. Помните, мы подождем 0,2 с, чтобы узнать, завершит ли пользователь ввод? Здесь мы используем две функции для реализации этой функции: setTimeout () и clearTimeout (). Что setTimeout () делает, это ждет 200 мс (второй параметр) перед выполнением функции (первый параметр). clearTimeout () просто говорит setTimeout (), эй, больше не нужно ждать, просто отмени себя. Если вы не знакомы с этими функциями, эти учебники хороши. Если эта часть не имеет смысла для вас, не волнуйтесь. Пройдите эти уроки и найдите время здесь.
  4. Функция «filter ()» рассчитывает и сортирует результаты поиска для нас. Мы закодируем это на следующем шаге.

Примечание: setTimeout () является нативной функцией js. Его первый параметр должен иметь кавычки, обернутые вокруг имени функции, значительно отличающиеся от соглашений jQuery.

Итак, функция filter () срабатывает, когда пользователь прекращает набирать текст на 0,2 секунды. Теперь мы готовы пойти еще дальше с функцией filter ().


Теперь мы подошли к сути этого эффекта: логике поиска, которая перебирает все имена фреймворков и вычисляет релевантность.

Поместите следующий код вместо функции filter (). И мы сделаем некоторые объяснения.

1
function filter(){ var q = $(“#q”).val().toLowerCase();
  1. Строка 2 не должна беспокоить вас слишком сильно. Просто получите текст в поле поиска и преобразуйте его в нижний регистр.
  2. В строке 4 создается пустой массив с именем «Score», который используется для хранения результатов поиска и релевантности (или оценки между запросом и именем платформы).
  3. Строка 6-8 проверяет, является ли запрос пустым (длина = 0). Если запрос пуст, нам даже не нужно ничего вычислять. Просто очистите область результатов поиска.
  4. Из строки 9 мы видим некоторые реальные вещи. Массив “items” содержит все имена каркасов. Это то, что пользователи ищут.
  5. Строка 9 зацикливает «элементы» с функцией $ .each . Если вы парень из PHP, это похоже на foreach ().
  6. Линия 10 находится в цикле. «Score» (не «Score») хранит соответствие между запросом и текущим элементом (именем платформы). «this» здесь относится к текущему элементу цикла, другими словами, к имени платформы. Мы включаем его в нижний регистр. И посмотрите на функцию Score () . Он определяется в скрипте Quicksilver Score и рассчитывается для нас.
  7. Строка 12 проверяет, равна ли оценка (релевантность) нулю. Нулевая релевантность означает, что два термина вообще не актуальны. Поэтому мы просто игнорируем их и сохраняем только соответствующие результаты.
  8. Строка 13 добавляет имя каркаса вместе с его оценкой релевантности к массиву «показателей».

Алгоритм Quicksilver Score чувствителен к регистру и, похоже, не верит, что «A» имеет какое-либо отношение к «a». Обязательно переводите тексты в нижний регистр, если вы этого хотите.

К этому моменту, если вы введете «php» в поле поиска и запустите переменную «scores» в Firebug, вы получите результат, показанный на этом изображении.


Ну, я знаю, что это не самый привлекательный формат в мире, но давайте попробуем его прочитать. Посмотрите на десятичные числа. Это оценка релевантности, за которой следует название элемента.

Невероятно, а? Но есть еще одна проблема. Посмотрите поближе: CakePHP, получивший 0,42, предшествует DooPHP (0,5) и даже PHP Work (0,93)! Это не правильный порядок! Мы должны исправить это на следующем шаге.


Наконец, вот последняя функция filter (). Давайте внимательнее посмотрим.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function filter(){
    var q = $(“#q”).val().toLowerCase();
      
    scores = [];
      
    if (q.length == 0) {
        $(“#results”).html(“”);
    } else {
        $.each(items, function(){
            var score = this.toLowerCase().score(q);
              
            if (score > 0) {
                scores.push([score, this+””]);
            }
        });
        if (scores.length) {
            $(“#results”).html(“”);
            $.each(scores.sort(function(a, b){return b[0] – a[0];}), function(i){
                var entry = “<li>” + this[1] +”</li>”;
                $(“#results”).append(entry);
            });
        } else {
            $(“#results”).html(“”);
        }
    }
}

Пришло время отсортировать результаты поиска и представить их нашим пользователям!

  1. В строке 16 проверяется, не является ли «партитура», наш контейнер результатов поиска, пустой. Если результат пустой, мы просто очищаем результаты DOM в HTML, или, если хотите, выведите пользователю некоторые извинения.
  2. Мы определенно счастливее, если результат поиска не пустой. В этом случае очистим DOM результатов в строке 17, чтобы освободить место для распечатки результатов.
  3. В строке 18 мы видим старого друга $ .each, итератор. А с помощью встроенной функции js sort () мы можем сортировать результаты поиска по их значимости. Если вам интересно, как это работает, посмотрите этот документ .
  4. Строка 19 генерирует HTML-код, который будет добавлен в DOM результатов. Чтобы сделать это просто, я просто добавляю LI здесь. В реальных проектах вы можете написать более сложный HTML здесь.
  5. Наконец, линия 20 переносит то, что было за сценой, на передний план

Если вы снова запустите переменную «оценки» в Firebug, вы увидите, что она была отсортирована на основе оценки релевантности.



Код, используемый в этом руководстве, упрощен для упрощения демонстрации. Чтобы реализовать это в реальном проекте, учтите следующее:

  • Добавьте начальные и не найденные наценки для результатов DOM
  • Использовать многомерный массив в качестве пула поиска
  • Реализовать более сложный HTML для вывода результатов поиска

Подход, представленный в этом руководстве, основан на плагине Livesearch Джона Резига , который принимает набор HTML LI в качестве входных данных. (Мы принимаем в качестве входных данных массивы и JSON, что делает этот подход гораздо более гибким.) А также благодаря алгоритму ранжирования текстовых релевантностей Lachie Cox .