Перейти к содержимому
Поиск
Разработка

Fuse.js: поиск с опечатками и 6 интерактивных примеров

Поиск по публикациям, каталог с фильтрами, палитра команд, веса полей, операторы и свой JSON. Шесть работающих примеров Fuse.js с настройками и исходниками.

Александр Некрасов
Fuse.js: поиск с опечатками, поисковая строка, лупа и карточки результатов на тёмно-бирюзовом фоне

В каталоге уже есть нужный компонент, а поиск ничего не показывает: пользователь пропустил букву. Или материал находится, но точное совпадение в описании вытесняет более подходящий заголовок. Такие ситуации удобно исследовать не на скриншотах, а в рабочем интерфейсе: написать запрос, изменить настройки и сравнить результат.

Fuse.js выполняет нечёткое сопоставление строк, учитывает веса полей и возвращает оценку совпадения. Это JavaScript-библиотека, а не готовый поисковый интерфейс: карточки, фильтры, действия и подсветку мы строим сами. Принцип сопоставления и расчёта оценки описан в документации Fuse.js.

Что будем проверять

Мы подготовили шесть собственных сценариев. В первом используются реальные публикации нашего сайта, в остальных небольшие учебные наборы, специально подобранные для проверки поведения. Это не замена общему поиску WordPress: здесь отдельная мастерская со снимком данных.

  • Поиск по материалам: опечатка, сравнение с обычной подстрокой, переход к статье и список чтения.
  • Каталог: нечёткий запрос вместе с точным фильтром категории и подборкой выбранных компонентов.
  • Палитра команд: найденный пункт действительно создаёт заметку, меняет отображение или скачивает файл.
  • Веса полей: две выдачи рядом, один набор данных и разные приоритеты заголовка.
  • Расширенный поиск: начало строки, вхождение, исключение и объединение условий.
  • Свой JSON: загрузка данных, проверка формата и поиск по собственному набору.

Живая мастерская Fuse.js

Начните с готового запроса, затем замените его своим. «Допуск опечаток» меняет строгость сопоставления, «Вес заголовка» перераспределяет влияние названия и описания, а переключатель подсветки помогает увидеть найденные участки. Кнопка «Развернуть» увеличивает мастерскую до размеров окна без потери текущего состояния.

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

Шесть прикладных примеров

Поиск по публикациям с опечаткой

Оставьте запрос «дашбрдов»: в нём пропущена буква. Мастерская находит статью о GridStack, а счётчик обычного поиска подстроки показывает ноль. Затем попробуйте «подсказки», «сжатие» или «SVG», откройте найденный материал либо добавьте несколько записей в список чтения и скачайте его в JSON.

В этом примере 14 публикаций из публичного раздела «Разработка», сохранённых 5 ноября 2026 года. Набор не обновляется автоматически и не охватывает весь сайт. Такой подход можно использовать для небольшого справочника или каталога документации, но обновление индекса нужно организовать отдельно.

Попробовать поиск по нашим материалам

Каталог: запрос, категория и выбранный набор

Введите «таблца», а затем выберите категорию. Если сочетание запроса и фильтра не подходит ни одному компоненту, появится честное пустое состояние. Очистка запроса сохраняет выбранную категорию: удобно отдельно проверить, какие записи исключил поиск, а какие фильтр.

Кнопки «В мой список» собирают подборку независимо от текущей выдачи. «Скачать выбранное JSON» сохраняет эту подборку, а «Скачать результаты JSON» сохраняет найденные записи вместе с параметрами поиска. Это разные действия: список покупок или набор компонентов не должен незаметно меняться при каждом новом запросе.

Собрать набор компонентов

Палитра команд с настоящими действиями

Откройте пример и нажмите Enter: готовый запрос «создать» выбирает создание заметки. Измените её текст в рабочей области. Затем найдите «компакт», выполните переключение плотности, попробуйте скрыть описания и скачайте заметки командой экспорта.

Стрелки вверх и вниз меняют выбранный пункт, Enter выполняет его, Escape очищает запрос. В развёрнутой мастерской повторный Escape при пустом запросе возвращает обычный размер. Можно пользоваться и мышью. Команды ограничены этой учебной областью, не редактируют сайт и не отправляют сообщения.

Такую механику можно применить в редакторе или кабинете с большим количеством действий. Сам поиск не должен выполнять первое совпадение автоматически: пользователь видит название и выбирает действие явно. Для удаления, публикации и других существенных изменений в настоящем продукте потребуется отдельное подтверждение.

Создать заметку через поиск команд

Веса полей: почему результат оказался первым

Слева заголовок и описание имеют равные веса, справа действует ползунок «Вес заголовка». Запрос и записи одинаковые. Переместите ползунок от 10% к 90% и сравните порядок карточек, затем попробуйте «фильтр» и «экспорт».

Мы специально добавили записи с коротким описанием и более длинным заголовком, содержащими искомое слово. В итоговой оценке участвуют не только опечатки, но и вес ключа, а также нормализация длины поля, как объясняет раздел Scoring. Поэтому высокий вес заголовка не является универсальной гарантией «правильной» выдачи: настройку стоит проверять на реальных запросах вашего проекта.

Сравнить два ранжирования

Точные условия и расширенные запросы

В этом сценарии поиск работает только по заголовку и включён useExtendedSearch: true. В других сценариях этот режим выключен, чтобы специальные символы не становились неожиданными командами. Синтаксис и способы объединения условий приведены в документации расширенного поиска.

  • ^JavaScript: заголовок начинается с JavaScript; это оператор точного префикса из Extended Search.
  • 'формы: заголовок содержит указанную последовательность, согласно правилам include-match.
  • !React: исключаются заголовки, содержащие React, по правилам inverse matching.
  • ^CSS | ^SVG: заголовок начинается с CSS или SVG; вертикальная черта означает ИЛИ в синтаксисе объединения.

Для проверки наберите также ^CSS !анимации: останутся CSS-заголовки без слова «анимации». В интерфейсе для широкой аудитории такие условия часто удобнее представить отдельными фильтрами, а строковый синтаксис оставить опытным пользователям.

Проверить операторы на восьми заголовках

Свои данные: импорт без потери рабочего набора

Вставьте JSON в редактор или откройте файл. Мастерская принимает от 1 до 200 записей размером до 200 000 байт. Это ограничение нашего примера, а не заявленный предел Fuse.js. Обязательны непустые строковые поля id, title, description и category; идентификаторы должны быть уникальными.

[
  {
    "id": "search",
    "title": "Поиск по каталогу",
    "description": "Найти подходящий компонент",
    "category": "Навигация"
  },
  {
    "id": "form",
    "title": "Форма заявки",
    "description": "Проверить обязательные поля",
    "category": "Формы"
  }
]

Сначала проверяется весь набор, и только затем он заменяет текущие данные. Попробуйте удалить закрывающую скобку или повторить id: появится объяснение ошибки, а прежний индекс останется рабочим. Дополнительные поля отбрасываются, импортированные ссылки не открываются, текст выводится с экранированием.

Проверить собственный JSON

Как читать настройки и score

Значение threshold управляет допустимой нечёткостью: меньший порог делает сопоставление строже. В мастерской исходное значение 0.35 выбрано для этих наборов. Параметр ignoreLocation: true отключает штраф за положение совпадения внутри строки; оба параметра разобраны в документации нечёткого поиска.

score не означает вероятность или процент уверенности. Меньшее значение соответствует лучшему совпадению по правилам текущего индекса; итог объединяет нечёткость, веса и нормализацию длины поля. Поэтому итоговый score может оказаться больше указанного threshold, что следует из описания этапов расчёта оценки.

Пустой запрос в нашей мастерской показывает все записи. Это явное решение интерфейса, а не результат вызова fuse.search(''). Для подсветки мы используем диапазоны совпадений, но показываем только те участки, которые вернула библиотека: не обещаем выделение всех вхождений во всём тексте.

Готовые куски кода и исходники

Установите библиотеку командой npm install fuse.js@7.5.0. В мастерской закреплена эта версия, а полный ZIP содержит также lock-файл. Общий способ установки и создания индекса показан в руководстве Getting Started.

import Fuse from 'fuse.js';

const items = [
  {
    id: 'table',
    title: 'Таблица заказов',
    description: 'Сортировка и просмотр строк',
    category: 'Данные'
  },
  {
    id: 'form',
    title: 'Форма заявки',
    description: 'Проверка полей перед отправкой',
    category: 'Формы'
  }
];

const fuse = new Fuse(items, {
  keys: [
    { name: 'title', weight: 0.8 },
    { name: 'description', weight: 0.2 }
  ],
  threshold: 0.35,
  ignoreLocation: true,
  includeScore: true,
  includeMatches: true
});

function search(query, category = 'Все') {
  const q = query.trim();
  const results = q
    ? fuse.search(q)
    : items.map((item, refIndex) => ({ item, refIndex }));

  return results.filter(({ item }) =>
    category === 'Все' || item.category === category
  );
}

console.log(search('таблца', 'Данные'));

Этот фрагмент реализует поиск и фильтр, но не рисует интерфейс. Кнопка «Копировать код» в мастерской выдаёт аналогичное ядро уже с данными и настройками текущего сценария. Для готового интерфейса скачайте ZIP: в нём находятся TypeScript, CSS, данные, валидация, подсветка, экспорт и README с командами запуска.

Для безопасной простой выдачи можно создавать DOM-элементы и присваивать текст через textContent. В нашем варианте подсветка строится поверх заранее экранированного текста. Не вставляйте импортированные названия прямо в innerHTML: содержимое JSON не должно становиться исполняемой разметкой.

Где применять и что проверить перед внедрением

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

  • Набор запросов: подготовьте правильные названия, частые опечатки, короткие слова и запросы без результата. Проверьте не только наличие нужной записи, но и её место в выдаче.
  • Жизненный цикл индекса: в нашей мастерской индекс повторно используется при вводе и пересоздаётся при смене данных или параметров. Не выполняйте лишнюю работу при каждом нажатии клавиши.
  • Состояния интерфейса: определите поведение пустого запроса, нулевой выдачи, фильтра категории и выбранного набора. Экспорт должен соответствовать обещанию на кнопке.
  • Доступность: оставьте видимые подписи полей, управление клавиатурой и понятный выбранный пункт. Подсветка совпадений не должна быть единственным способом понять результат.
  • Обновление данных: для рабочего сайта понадобится собственный процесс актуализации. Снимок в этой статье остаётся учебным набором.

Fuse.js здесь решает одну конкретную задачу: сопоставляет запрос с данными и помогает упорядочить результат. Пользу создаёт следующий шаг интерфейса: открыть статью, собрать набор, выполнить команду или сохранить найденное. Сравните сценарии на своих данных, прежде чем переносить выбранную настройку в продукт.