Библиотека Shepherd.js предоставляет гибкие механизмы для формирования содержимого шагов (steps), позволяя использовать не только простой текст, но и сложные HTML-структуры, динамически создаваемые элементы и даже компоненты UI-фреймворков.
Ключевым элементом является свойство text, которое
принимает:
Это открывает возможности для полного контроля над отображаемым содержимым.
Наиболее простой способ кастомизации — передача HTML-строки:
tour.addStep({
id: 'example-step',
text: `
<div class="custom-content">
<h3>Заголовок шага</h3>
<p>Подробное описание действия</p>
</div>
`,
attachTo: {
element: '.target-element',
on: 'bottom'
}
});
Особенности:
Для более сложных сценариев можно передать заранее созданный DOM-узел:
const content = document.createElement('div');
content.innerHTML = `
<h3>Динамический блок</h3>
<button id="action-btn">Нажать</button>
`;
tour.addStep({
id: 'dom-step',
text: content,
attachTo: {
element: '.target',
on: 'right'
}
});
Преимущества:
Функция в text позволяет формировать содержимое в момент
отображения шага:
tour.addStep({
id: 'dynamic-step',
text: () => {
const el = document.createElement('div');
el.textContent = `Текущее время: ${new Date().toLocaleTimeString()}`;
return el;
},
attachTo: {
element: '.clock',
on: 'top'
}
});
Ключевые моменты:
when и жизненный циклShepherd.js предоставляет хуки жизненного цикла шага, которые можно использовать для управления контентом:
tour.addStep({
id: 'lifecycle-step',
text: '<div id="content-area"></div>',
when: {
show: () => {
const container = document.getElementById('content-area');
container.innerHTML = '<strong>Контент загружен при показе</strong>';
}
}
});
Доступные события:
show — при отображенииhide — при скрытииbefore-show — перед показомИспользование шаблонизаторов (например, Handlebars, Mustache) упрощает генерацию сложного контента:
const template = Handlebars.compile(`
<div>
<h3>{{title}}</h3>
<p>{{description}}</p>
</div>
`);
tour.addStep({
id: 'template-step',
text: template({
title: 'Заголовок',
description: 'Описание шага'
})
});
Преимущества:
Для SPA-приложений контент можно рендерить через компоненты.
import ReactDOM from 'react-dom';
tour.addStep({
id: 'react-step',
text: () => {
const container = document.createElement('div');
ReactDOM.render(<MyComponent />, container);
return container;
}
});
import { createApp } from 'vue';
tour.addStep({
id: 'vue-step',
text: () => {
const container = document.createElement('div');
createApp(MyComponent).mount(container);
return container;
}
});
Особенности:
Контент шага может включать кнопки, формы и другие элементы:
tour.addStep({
id: 'interactive-step',
text: () => {
const wrapper = document.createElement('div');
const button = document.createElement('button');
button.textContent = 'Действие';
button.addEventListener('click', () => {
alert('Кнопка нажата');
});
wrapper.appendChild(button);
return wrapper;
}
});
Рекомендации:
Shepherd позволяет управлять внешним видом контейнера через
classes:
tour.addStep({
id: 'styled-step',
text: 'Стилизованный контент',
classes: 'my-custom-step'
});
CSS:
.my-custom-step {
background: #222;
color: #fff;
border-radius: 10px;
}
beforeShowPromise для асинхронного контентаПри необходимости загрузки данных перед показом:
tour.addStep({
id: 'async-step',
text: 'Загрузка...',
beforeShowPromise: () => {
return fetch('/api/data')
.then(res => res.json())
.then(data => {
document.querySelector('.shepherd-text').innerHTML =
`<pre>${JSON.stringify(data, null, 2)}</pre>`;
});
}
});
Назначение:
Помимо text, можно настраивать:
title — заголовокbuttons — массив кнопокfooter (через кастомный HTML)Пример:
tour.addStep({
id: 'full-step',
title: 'Заголовок',
text: '<p>Описание</p>',
buttons: [
{
text: 'Далее',
action: tour.next
}
]
});
Контент можно дополнять CSS-анимациями:
.fade-in {
animation: fadeIn 0.5s ease-in;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
text: '<div class="fade-in">Анимированный блок</div>'
function createStepContent(user) {
const container = document.createElement('div');
container.innerHTML = `
<h3>${user.name}</h3>
<p>Email: ${user.email}</p>
`;
const button = document.createElement('button');
button.textContent = 'Подробнее';
button.addEventListener('click', () => {
console.log(user);
});
container.appendChild(button);
return container;
}
tour.addStep({
id: 'user-step',
text: () => createStepContent({
name: 'Иван',
email: 'ivan@example.com'
})
});
Такой подход обеспечивает гибкость, масштабируемость и чистоту архитектуры при работе с кастомным контентом в Shepherd.js.