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

Driver.js: подсказки в интерфейсе и 6 интерактивных туров

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

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

После создания рабочего экрана возникает следующая задача: как объяснить человеку, что с ним делать? Длинная инструкция в отдельной вкладке не всегда помогает. Здесь разберём другой подход: подсказка появляется рядом с нужным элементом, человек выполняет действие и сразу видит результат.

Driver.js выделяет элементы страницы, показывает пояснения и объединяет их в последовательность шагов. Библиотека предоставляет управление переходами, одиночную подсветку и обработчики событий, но полезный сценарий и проверку результата нужно написать в самом приложении. Это хорошо видно в официальных примерах интерактивных туров.

Что делает Driver.js, а что остаётся приложению

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

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

Эта мастерская использует настоящую библиотеку Driver.js и собственные учебные интерфейсы. Все данные вымышленные: приглашения не отправляют письма, загрузка не обращается к реальному API, настройки не записываются на сервер.

Живая мастерская: шесть маршрутов

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

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

Примеры применения в интерфейсах

Первая задача: обучение через действие

Человек вводит название, создаёт задачу и видит карточку в проекте. Кнопка «Далее» не выполняет работу вместо него: пока задача не создана, следующий шаг объясняет, какое действие осталось выполнить.

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

Создать первую задачу

Фильтр, список и настоящий экспорт

Выберите статус «Готово», проверьте изменившиеся строки и скачайте CSV. Файл формируется из текущего отфильтрованного набора. Дополнительный поиск позволяет проверить и пустое состояние: никаких выдуманных записей вместо нулевого результата.

В интерфейсах отчётов и каталогов такой пример объясняет связь нескольких элементов. Пользователь понимает не только назначение фильтра, но и то, как его выбор влияет на итоговый файл.

Проверить фильтры и экспорт

Проверка формы перед следующим шагом

Оставьте название пустым и попробуйте продолжить. Тур останется на поле и покажет пояснение. После корректного названия можно выбрать видимость, сохранить настройки и проверить результат.

Здесь важно разделение ответственности: Driver.js управляет подсказкой, а проверка значения выполняется кодом приложения. Переопределение onNextClick позволяет выполнить проверку перед вызовом moveNext(); этот механизм описан в конфигурации обработчиков Driver.js.

Пройти форму с проверкой

Новая панель: сначала открыть, потом подсветить

Панель приглашения изначально отсутствует в DOM. Сначала откройте её, затем введите вымышленный email и добавьте участника в учебный список. Неверный адрес не пропускает проверку.

Это сценарий для выпадающих меню, дополнительных панелей и содержимого, создаваемого по действию. В Driver.js есть waitForElement для ожидания цели; если цель так и не появилась, необходимо заранее решить, какой резервный сценарий увидит человек, а не считать ожидание успешным. Поведение ожидания и отсутствующих элементов описано в руководстве по интерактивным турам.

Открыть панель приглашения

Асинхронная загрузка, ошибка и повтор

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

Такой подход полезен в поиске, генерации отчётов и загрузке карточек. Нельзя переключать тур по условному таймеру, предполагая, что ответ уже пришёл. В мастерской готовность проверяется по состоянию приложения, а при смене сценария устаревший ответ игнорируется.

Проверить ошибку и повтор

Разные роли: разные маршруты

Читателю предлагается добавить материал в избранное, редактору — сохранить черновик. Выберите роль до запуска тура, пройдите маршрут, затем смените её и сравните действия и тексты.

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

Сравнить читателя и редактора

Быстрый старт и готовый минимальный пример

В этой мастерской зафиксирована версия driver.js@1.10.2. В ZIP находятся TypeScript-исходники, стили, lock-файл, лицензия и команды сборки; установка библиотеки и импорт её CSS соответствуют официальному базовому примеру.

npm install driver.js@1.10.2

Ниже короткий самостоятельный фрагмент для страницы с формой. Сначала добавьте разметку, затем подключите JavaScript через сборщик, который поддерживает импорт CSS. Переход зависит от заполненного значения, а не от простого клика по «Далее».

<label id="name-field">
  Название проекта
  <input id="project-name" maxlength="100">
</label>
<p id="form-help" role="status"></p>
<button id="start-guide">Как заполнить?</button>
<button id="save-project">Сохранить</button>
<p id="saved" role="status"></p>
import { driver } from "driver.js";
import "driver.js/dist/driver.css";

const name = document.querySelector("#project-name");
const help = document.querySelector("#form-help");
const result = document.querySelector("#saved");
let saved = false;

const valid = () => name.value.trim().length >= 3;
name.addEventListener("input", () => { saved = false; });

document.querySelector("#save-project").onclick = () => {
  if (!valid()) {
    help.textContent = "Введите минимум 3 символа.";
    return;
  }
  saved = true;
  result.textContent = `Проект «${name.value.trim()}» сохранён локально.`;
  if (guide.isActive() && guide.getActiveIndex() === 1) {
    guide.moveNext();
  }
};

const guide = driver({
  showProgress: true,
  nextBtnText: "Далее",
  prevBtnText: "Назад",
  doneBtnText: "Готово",
  closeBtnLabel: "Закрыть",
  overlayClickBehavior: "none",
  animate: !matchMedia("(prefers-reduced-motion: reduce)").matches,
  steps: [
    {
      element: "#name-field",
      popover: {
        title: "Назовите проект",
        description: "Минимум 3 символа.",
        onNextClick: () => {
          if (!valid()) {
            help.textContent = "Сначала заполните название.";
            return;
          }
          guide.moveNext();
        }
      }
    },
    {
      element: "#save-project",
      popover: {
        title: "Сохраните",
        description: "Нажмите кнопку в самой форме.",
        onNextClick: () => {
          if (saved) guide.moveNext();
          else help.textContent = "Сначала сохраните проект.";
        }
      }
    },
    {
      element: "#saved",
      popover: { title: "Результат", description: "Проверьте название." }
    }
  ]
});

document.querySelector("#start-guide").onclick = () => guide.drive();

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

Три полезных приёма для собственного интерфейса

Одиночная подсказка вместо длинного тура

Если нужно объяснить один фильтр или новую кнопку, длинный маршрут избыточен. Метод highlight() позволяет выделить один элемент без последовательности шагов; возможности подсветки описаны в документации Driver.js.

const help = driver({
  showButtons: ["close"],
  closeBtnLabel: "Закрыть подсказку"
});
help.highlight({
  element: "#export-button",
  popover: {
    title: "Экспорт текущего списка",
    description: "В файл попадут строки после применения фильтров."
  }
});

Динамический элемент без угадывания времени

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

// Фрагмент: openPanel() — ваша функция отрисовки.
{
  element: "#open-panel",
  popover: {
    title: "Откройте панель",
    onNextClick: () => {
      openPanel();
      guide.moveNext();
    }
  }
},
{
  element: "#panel-content",
  waitForElement: 1500,
  popover: { title: "Панель готова" }
}

Завершение не равно закрытию

Посетитель может закрыть подсказки, отвлечься или уйти. В версии библиотеки, использованной здесь, обработчик завершения получает причину reason: среди значений есть done, close и escape. Это позволяет не смешивать разные события; полный перечень приведён в описании lifecycle-хуков.

onDestroyed: (_element, _step, { reason }) => {
  if (reason === "done") {
    // Все шаги пройдены. Отдельно проверьте результат задачи.
  } else {
    // Подсказки закрыты, но обучение не засчитываем завершённым.
  }
}

Мобильные экраны и доступность

Проверять нужно не только ширину страницы. Важны одновременно три области: подсвеченный элемент, окно пояснения и кнопка, которую нужно нажать. Если подсказка закрывает поле или уезжает за экран, корректный JavaScript не делает пример удобным.

  • Размер цели: подсвечивайте конкретную группу управления, а не весь длинный экран.
  • Выход: оставляйте доступные крестик и Escape. В мастерской первое нажатие закрывает тур, повторное позволяет выйти из развёрнутого режима.
  • Клавиатура: проверяйте Tab, обратный переход, ввод в поле и возвращение фокуса после закрытия.
  • Движение: учитывайте системное предпочтение reduced motion и не делайте анимацию обязательной для понимания.
  • Основной интерфейс: подписи полей и сообщения об ошибках должны работать без подсказок. Тур не заменяет доступную форму.

Автоматическая проверка размеров не заменяет проверку скринридером и на реальном телефоне с открытой клавиатурой. Встроенная мастерская предназначена для изучения поведения; перед внедрением проверяйте её подходы в своём окружении.

Состояние, безопасность и аналитика

В демонстрации данные живут только в памяти вкладки. Кнопка продолжения работает до смены сценария или перезагрузки. JSON выгружает описание маршрута и настройки, но не функции JavaScript и не прогресс пользователя.

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

Не подставляйте непроверенный пользовательский HTML в заголовки и описания подсказок. Driver.js допускает HTML в этих полях, поэтому доверие к контенту и его очистка остаются обязанностью приложения. Формат полей описан в настройках popover.

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

Когда использовать, а когда обойтись без тура

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

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

Полный проект можно скачать в мастерской: выполните npm ci, затем npm run dev; для production-сборки используйте npm run build. Исходная библиотека распространяется по MIT, что указано в её репозитории и лицензии.

Для дальнейших экспериментов соедините этот подход с конструктором дашбордов на GridStack.js: сначала человек собирает удобный экран, затем короткий маршрут помогает выполнить на нём первую задачу.