Driver.js предоставляет возможность динамического выделения элементов интерфейса с помощью последовательностей шагов (steps). Иногда возникает необходимость обновлять целевые элементы на лету, например, если DOM изменяется после первоначальной инициализации тура. Для этого библиотека предлагает несколько подходов, позволяющих изменять или переопределять селекторы элементов без пересоздания Driver.
defineStepsМетод defineSteps позволяет полностью задать или
обновить последовательность шагов после создания экземпляра Driver:
const driver = new Driver();
driver.defineSteps([
{
element: '#newButton',
popover: {
title: 'Новая кнопка',
description: 'Эта кнопка появилась после AJAX-загрузки',
position: 'bottom'
}
},
{
element: '.updatedSection',
popover: {
title: 'Обновлённый раздел',
description: 'Секция была динамически заменена',
position: 'left'
}
}
]);
driver.start();
Ключевой момент: defineSteps полностью
заменяет старые шаги на новые, что удобно при динамическом формировании
интерфейса.
Если нужно изменить только один шаг, Driver.js позволяет получить
доступ к шагам через driver.steps и вручную модифицировать
объект шага:
driver.steps[1].element = '#dynamicSection';
driver.steps[1].popover.title = 'Обновлённая секция';
driver.steps[1].popover.description = 'Контент изменился';
После этого при следующем показе этого шага будет использоваться новый элемент и новые данные.
Важно: прямое изменение элементов работает только до
вызова driver.start(). Если тур уже запущен, требуется
рестарт текущего шага с помощью
driver.reset() или driver.stop() +
driver.start().
Driver.js умеет работать с селекторами, которые могут появиться в DOM
только после выполнения асинхронных операций. Для этого полезно
использовать проверку существования элемента перед вызовом
driver.start() или отдельного шага:
function waitForElement(selector, timeout = 3000) {
return new Promise((resolve, reject) => {
const start = Date.now();
const check = () => {
const el = document.querySelector(selector);
if (el) resolve(el);
else if (Date.now() - start > timeout) reject('Элемент не найден');
else requestAnimationFrame(check);
};
check();
});
}
waitForElement('#lazyButton').then(() => {
driver.defineSteps([{
element: '#lazyButton',
popover: {
title: 'Поздно загруженная кнопка',
description: 'Эта кнопка появилась после загрузки данных',
position: 'top'
}
}]);
driver.start();
});
Преимущество: шаги будут корректно работать даже если элементы создаются динамически после рендера страницы.
Driver.js автоматически вычисляет позицию popover на основе текущего местоположения целевого элемента. Если элемент обновился по размеру или сместился, можно принудительно пересчитать позицию:
driver.reposition();
Метод reposition обновляет координаты текущего
шага и гарантирует, что popover останется на правильной
позиции. Это особенно полезно после анимаций или изменения DOM.
В сложных интерфейсах тур может работать непрерывно, а целевые элементы заменяются или исчезают. В этом случае логика обновления шагов может быть такой:
function updateStepElement(stepIndex, newSelector) {
const step = driver.steps[stepIndex];
if (!document.querySelector(newSelector)) return;
step.element = newSelector;
if (driver.activeStep === stepIndex) {
driver.reposition();
}
}
// пример использования
updateStepElement(0, '#newDynamicElement');
Таким образом можно поддерживать актуальные элементы даже во время активного тура без полной перезагрузки всех шагов.
Promise или события MutationObserver.reposition(), иначе popover может оказаться
неправильно расположен.| Метод/Свойство | Назначение |
|---|---|
defineSteps(steps) |
Полностью задаёт или обновляет все шаги |
driver.steps |
Массив шагов для прямого изменения конкретного шага |
driver.reposition() |
Пересчёт позиции popover относительно элемента |
driver.reset() |
Сброс текущего состояния тура для повторного старта |
activeStep |
Индекс текущего шага, для которого можно обновлять элемент |
Эти инструменты позволяют создавать динамические, интерактивные туры, где элементы интерфейса могут меняться, а подсветка и popover остаются актуальными.