Валидация действий пользователя

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

Использование beforeChange и onbeforechange

Основной инструмент для валидации — события onbeforechange и beforeChange. Они позволяют перехватывать момент перед переходом к следующему шагу. Если в этом событии возвращается false, переход блокируется.

const intro = introJs();

intro.setOptions({
  steps: [
    { 
      element: '#username', 
      intro: 'Введите имя пользователя' 
    },
    { 
      element: '#submit', 
      intro: 'Нажмите кнопку для продолжения' 
    }
  ]
});

intro.onbeforechange(function(targetElement) {
  if (targetElement.id === 'submit') {
    const username = document.querySelector('#username').value;
    if (!username) {
      alert('Имя пользователя обязательно для заполнения');
      return false; // блокируем переход
    }
  }
});

Ключевые моменты:

  • targetElement — DOM-элемент, на который будет совершён переход.
  • Проверка условий должна быть синхронной, иначе переход может произойти некорректно.
  • Можно комбинировать несколько условий для одного шага.

Асинхронная валидация

Для случаев, когда проверка требует асинхронных действий (например, запрос к серверу), используется метод nextStep в комбинации с временной блокировкой перехода через introJs().nextStep() вручную после завершения проверки.

intro.onbeforechange(async function(targetElement) {
  if (targetElement.id === 'submit') {
    const username = document.querySelector('#username').value;
    if (!username) {
      alert('Имя пользователя обязательно');
      return false;
    }
    // Асинхронная проверка на уникальность имени
    const response = await fetch(`/check-username?name=${username}`);
    const result = await response.json();
    if (!result.available) {
      alert('Имя уже занято');
      return false;
    }
    // Переход произойдёт автоматически после успешной проверки
  }
});

Настройка пользовательских кнопок для валидации

В Intro.js можно полностью управлять кнопками Next, Previous, Done через кастомные элементы. Это позволяет проверять состояние интерфейса перед активацией кнопок.

intro.setOptions({
  showButtons: true,
  nextLabel: 'Далее',
  doneLabel: 'Готово',
  steps: [
    {
      element: '#email',
      intro: 'Введите email',
      tooltipClass: 'custom-tooltip'
    }
  ]
});

intro.onafterchange(function(targetElement) {
  const nextBtn = document.querySelector('.introjs-nextbutton');
  if (targetElement.id === 'email') {
    nextBtn.disabled = true;
    document.querySelector('#email').addEventListener('input', function() {
      nextBtn.disabled = this.value.trim() === '';
    });
  }
});

Особенности:

  • onafterchange позволяет динамически изменять состояние кнопок после отображения шага.
  • Можно комбинировать с CSS-классами для визуального выделения заблокированных кнопок.

Валидация кликов по элементам

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

intro.onbeforechange(function(targetElement) {
  if (targetElement.id === 'important-btn') {
    const btn = document.querySelector('#important-btn');
    btn.addEventListener('click', function handler() {
      intro.nextStep();
      btn.removeEventListener('click', handler);
    });
    return false; // блокируем переход до клика
  }
});

Советы по организации валидации

  1. Минимизировать логику в onbeforechange — тяжелые вычисления лучше выносить в отдельные функции.
  2. Использовать CSS для подсказки пользователю — заблокированная кнопка должна выглядеть неактивной.
  3. Обрабатывать все возможные сценарии — пользователь может пытаться перепрыгнуть шаги, особенно при кастомной навигации.
  4. Документировать шаги — каждый шаг с валидацией должен иметь комментарий, какие действия ожидаются.

Интеграция с формами

При использовании Intro.js вместе с формами удобно проверять поля формы в реальном времени. Валидация может быть синхронной (регулярные выражения) или асинхронной (API-запросы), и управлять кнопкой Next через disabled.

const intro = introJs();
intro.setOptions({
  steps: [
    { element: '#form-field', intro: 'Заполните поле' }
  ]
});

intro.onafterchange(function(targetElement) {
  const nextBtn = document.querySelector('.introjs-nextbutton');
  nextBtn.disabled = true;
  const field = document.querySelector('#form-field');
  field.addEventListener('input', () => {
    nextBtn.disabled = !/^[a-zA-Z0-9]+$/.test(field.value);
  });
});

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