Проект: собственный поиск по странице на jQuery

Недав­но мы гово­ри­ли о биб­лио­те­ках и фрейм­вор­ках — и обе­ща­ли, что попро­бу­ем что-нибудь на них собрать. Наста­ло время.

Сего­дня мы возь­мём попу­ляр­ную биб­лио­те­ку jQuery и сде­ла­ем на её осно­ве поиск по стра­ни­це. Бра­у­зе­ры это уме­ют делать встро­ен­ны­ми инстру­мен­та­ми, но с помо­щью наше­го мето­да мож­но будет более тон­ко всё настро­ить и сде­лать поле поис­ка види­мым и удобным.

Нам пона­до­бят­ся:

  • биб­лио­те­ка jQuery — она обес­пе­чит рабо­ту наше­го поис­ко­во­го пла­ги­на, пото­му что пла­гин сде­лан тоже для jQuery.
  • пла­гин highlight — помо­жет нам най­ти нуж­ные сло­ва в тек­сте и под­све­тить их при­ят­ным цве­том (каким захотим)
  • поле вво­да и кноп­ка — отве­ча­ют за сам интер­фейс поиска.

Общая идея

У нас есть сайт с неким тек­стом, и нам нуж­но быст­ро нахо­дить в нём нуж­ные сло­ва или части слов. Для это­го мы в самом нача­ле стра­ни­цы дела­ем поле вво­да, куда будем писать наши сло­ва для поис­ка, и кноп­ку, кото­рая этот поиск запускает.

Даль­ше скрипт берёт весь текст, нахо­дит в нём нуж­ные фраг­мен­ты и под­све­чи­ва­ет их. Если он ниче­го не нахо­дит — пишет сооб­ще­ние о том, что таких слов в тек­сте нет.

Готовим каркас

Сде­ла­ем как обыч­но — возь­мём наш стан­дарт­ный шаб­лон из преды­ду­щих задач и немно­го попра­вим опи­са­ния раз­де­лов. Сохра­ним его как .html-файл и откры­вать в бра­у­зе­ре пока не будем — всё рав­но мы ниче­го не уви­дим на стра­ни­це, кро­ме назва­ния вкладки.

<html>
<!-- служебная часть -->

<head>
  <!-- заголовок страницы -->
  <title>Поиск на странице</title>
  <!-- настраиваем служебную информацию для браузеров -->
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <!-- задаём CSS-стили прямо здесь же, чтобы всё было в одном файле -->
  <style type="text/css">
  </style>
  <!-- закрываем служебную часть страницы -->
</head>
<!-- началось содержимое страницы -->

<body>
  <!-- пишем скрипт, который поможет нам с поиском -->
  <script>
  </script>
  <!-- Здесь будет текст, в котором нам нужно что-то найти -->
  <!-- закончилось содержимое страницы -->
</body>
<!-- конец всего HTML-документа -->

</html>

Добавляем форму поиска и текст

Наша фор­ма поис­ка — это поле вво­да и кноп­ка, кото­рая запус­ка­ет скрипт. Мы не будем силь­но настра­и­вать внеш­ний вид фор­мы, при жела­нии вы може­те сде­лать это сами — все нуж­ные зна­ния для это­го у вас уже есть. Если что-то забы­ли — посмот­ри­те, как мы настра­и­ва­ли вид поля вво­да в ста­тье про пла­ни­ров­щик задач.

Доба­вим код фор­мы сра­зу после тега <body>:

<!-- говорим браузеру, что мы хотим разместить форму -->
<form id="search-highlight" method="post" action="#">
  <!-- добавляем текстовое поле ввода, где будем писать наш поисковый запрос -->
  <input type="text" name="term" id="term" />
  <!-- добавляем кнопку, которая запускает поиск -->
  <input type="submit" name="submit" id="submit" value="Найти" />
  <!-- конец формы -->
</form>
<!-- сразу после формы будем писать, сколько совпадений мы нашли -->
<p class="results"></p>
<!-- а в этом блоке разместим наш основной текст -->
<div class="content">
  Сюда вставим наш текст
</div>

Оста­лось доба­вить сам текст в блок <div class="content">. Для про­сто­ты мы ско­пи­ру­ем пер­вые абза­цы этой ста­тьи и обер­нём их в HTML-теги. Вы може­те вста­вить какой угод­но текст, на рабо­ту скрип­та это никак не повлияет.

<h2>Общая идея</h2> <p> У нас есть сайт с неким текстом, и нам нужно быстро находить в нём нужные слова или части слов. Для этого мы в самом начале страницы делаем поле ввода, куда будем писать наши слова для поиска, и кнопку, которая этот поиск запускает. </p> <p> Дальше скрипт берёт весь текст, находит в нём нужные фрагменты и подсвечивает их. Если он ничего не находит — пишет сообщение, что таких слов в тексте нет. </p>

Сохра­ня­ем, откры­ва­ем в браузере:

Настраиваем стили

Сти­ли отве­ча­ют за внеш­ний вид всех эле­мен­тов на стра­ни­це. Глав­ное, что нам нуж­но сде­лать, — нор­маль­ный внеш­ний вид фор­мы поис­ка и выбрать под­свет­ку для най­ден­ных резуль­та­тов. Это мы настро­им в бло­ке <style> в нача­ле страницы:

/*поле ввода*/
.searchtext {
  font-size: 16px;
  font-weight: bold;
  height: 27px;
  padding: 0 6px 0;
  width: 250px;
  /*делаем стильную границу вокруг поля*/
  border: 1px solid rgba(0, 0, 0, 0.1);
}
/* выбираем цвет подсветки — светло-зелёный*/
.highlight {
  background: #4cff00;
}
/*кнопка поиска*/
.search-button {
  background-color: #0b2f3f;
  font-weight: bold;
  font-size: 12px;
  /*устанавливаем высоту кнопки*/
  height: 28px;
  margin: 0;
  color: #ffffff;
  padding: 6px;
  /*тоже делаем стильную границу у кнопки*/
  border: 1px solid rgba(0, 0, 0, 0.1);
}

Сохра­ня­ем и обнов­ля­ем стра­ни­цу — теперь фор­ма выгля­дит лучше:

Пишем скрипт

Зада­ча скрип­та — про­бе­жать­ся по все­му содер­жи­мо­му тек­ста и срав­нить все сло­ва с тем, что мы вве­ли в стро­ке поис­ка. Всю рабо­ту за нас сде­ла­ет пла­гин highlight, нам оста­ёт­ся толь­ко выве­сти коли­че­ство най­ден­ных сов­па­де­ний и очи­стить стра­ни­цу от преды­ду­щих резуль­та­тов поиска.

<!-- подключаем библиотеку jQuery -->
<script src="http://thecode.local/wp-content/uploads/2019/06/jquery.js" type="text/javascript"></script>
<!--подключаем к ней плагин highlight.js -->
<script src='http://thecode.local/wp-content/uploads/2019/06/jqueryhighlight.js' />
</script>
<!-- говорим браузеру, что сейчас начнётся скрипт -->
<script type="text/javascript">
  $(document).ready(function () {
    // обрабатываем нажатие на кнопку
    $("#submit").click(function () {
      // очищаем переменную, в которой будет наш поисковый запрос
      var term = "";
      // и переменную, которая отвечает за количество найденных совпадений
      var n = "0";
      // убираем всю подсветку из прошлого поиска, если она была
      $('body').removeHighlight();
      // скрываем блок с текстом о количестве найденных результатов
      $("p.results").hide().empty();
      // с помощью магии jQuery берём текст из строки поиска и кладём его в переменную term
      term = $('#term').attr('value');
      // если строка поиска пустая — выводим сообщение
      if ($('#term').val() == "") {
        $("p.results").fadeIn().append("Вы ничего не ввели :(");
        return false;
        // иначе, если в строке поиска что-то было…
      } else {
        // в блоке content, где у нас находится весь текст, плагином подсвечиваем все найденные совпадения (если совпадений не будет — не будет и подсветки)
        $('.content').highlight(term);
        // берём количество совпадений
        n = $("span.highlight").length;
        // если совпадений нет — в разделе results пишем, что ничего не нашли
        if (n == 0) {
          $("p.results").fadeIn().append("Ничего такого в тексте нет");
          // иначе в том же разделе пишем число совпадений  
        } else {
          $("p.results").fadeIn().append('Найдено совпадений:' + n);
        }
        return false;
      }
    });
  });

Встав­ля­ем скрипт в HTML-файл, сохра­ня­ем и смот­рим, что полу­чи­лось в итоге:

А вот как всё будет работать: 

Общий код страницы

<html>
<!-- служебная часть -->

<head>
  <!-- заголовок страницы -->
  <title>Поиск на странице</title>
  <!-- настраиваем служебную информацию для браузеров -->
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <!-- задаём CSS-стили прямо здесь же, чтобы всё было в одном файле -->
  <style type="text/css">
    /*поле ввода*/
    .searchtext {
      font-size: 16px;
      font-weight: bold;
      height: 27px;
      padding: 0 6px 0;
      width: 250px;
      /*делаем стильную границу вокруг поля*/
      border: 1px solid rgba(0, 0, 0, 0.1);
    }

    /* выбираем цвет подсветки — светло-зелёный*/
    .highlight {
      background: #4CFF00;
    }

    /*кнопка поиска*/
    .search-button {
      background-color: #0B2F3F;
      font-weight: bold;
      font-size: 12px;
      /*устанавливаем высоту кнопки*/
      height: 28px;
      margin: 0;
      color: #ffffff;
      padding: 6px;
      /*тоже делаем стильную границу у кнопки*/
      border: 1px solid rgba(0, 0, 0, 0.1);
    }
  </style>
  <!-- закрываем служебную часть страницы -->
</head>
<!-- началось содержимое страницы -->

<body>
  <!-- говорим браузеру, что мы хотим разместить форму -->
  <form id="search-highlight" method="post" action="#">
    <!-- добавляем текстовое поле ввода, где будем писать наш поисковый запрос -->
    <input type="text" name="term" id="term" class="searchtext" />
    <!-- добавляем кнопку, которая запускает поиск -->
    <input type="submit" name="submit" id="submit" value="Найти" class="search-button" />
    <!-- конец формы -->
  </form>
  <!-- подключаем библиотеку jQuery -->
  <script src="http://thecode.local/wp-content/uploads/2019/06/jquery.js" type="text/javascript"></script>
  <!-- подключаем к ней плагин highlight.js -->
  <script src='http://thecode.local/wp-content/uploads/2019/06/jqueryhighlight.js' />
  </script>
  <!-- говорим браузеру, что сейчас начнётся скрипт -->
  <script type="text/javascript">
    $(document).ready(function () {
      // обрабатываем нажатие на кнопку
      $("#submit").click(function () {
        // очищаем переменную, в которой будет наш поисковый запрос
        var term = "";
        // и переменную, которая отвечает за количество найденных совпадений
        var n = "0";
        // убираем всю подсветку из прошлого поиска, если она была
        $('body').removeHighlight();
        // скрываем блок с текстом о количестве найденных результатов
        $("p.results").hide().empty();
        // с помощью магии jQuery берём текст из строки поиска и кладём его в переменную term
        term = $('#term').attr('value');
        // если строка поиска пустая — выводим сообщение
        if ($('#term').val() == "") {
          $("p.results").fadeIn().append("Вы ничего не ввели :(");
          return false;
          // иначе, если в строке поиска что-то было…
        } else {
          // в блоке content, где у нас находится весь текст, плагином подсвечиваем все найденные совпадения (если совпадений не будет — не будет и подсветки)
          $('.content').highlight(term);
          // берём количество совпадений
          n = $("span.highlight").length;
          // если совпадений нет — в разделе results пишем, что ничего не нашли
          if (n == 0) {
            $("p.results").fadeIn().append("Ничего такого в тексте нет");
            // иначе в том же разделе пишем число совпадений  
          } else {
            $("p.results").fadeIn().append('Найдено совпадений:' + n);
          }
          return false;
        }
      });
    });
  </script>
  <!-- сразу после формы будем писать, сколько совпадений мы нашли -->
  <p class="results"></p>
  <!-- а в этом блоке разместим наш основной текст -->
  <div class="content">
    <p>
      Чтобы лучше понять, как работают библиотеки и плагины в веб-программировании, давайте с их помощью сделаем удобный
      поиск по странице. Мы знаем, что современные браузеры тоже умеют это делать, но мы сделаем свою версию, которая
      работает не хуже, чем в Хроме или Сафари.
    <p>
    <h2>Общая идея</h2>
    <p>
      У нас есть сайт с неким текстом, и нам нужно быстро находить в нём нужные слова или части слов. Для этого мы в
      самом начале страницы делаем поле ввода, куда будем писать наши слова для поиска, и кнопку, которая этот поиск
      запускает.
    </p>
    <p>
      Дальше скрипт берёт весь текст, находит в нём нужные фрагменты и подсвечивает их. Если он ничего не находит —
      пишет сообщение о том, что таких слов в тексте нет.
    </p>
  </div>
  <!-- закончилось содержимое страницы -->
</body>
<!-- конец всего HTML-документа -->

</html>

Как можно улучшить

Мож­но убрать кноп­ку «Най­ти» и запус­кать поиск при вво­де тек­ста в поле.

Мож­но сде­лать два поля вво­да, под­све­чи­вая най­ден­ное по каж­до­му раз­ны­ми цве­та­ми. Это полез­но, напри­мер, если нуж­но про­ана­ли­зи­ро­вать, каких слов в тек­сте больше.

Регу­ляр­ные выра­же­ния! О них отдель­но напи­шем, это же про­сто празд­ник какой-то.