Загрузка данных
/**
* Получить карточку персонажа
*
* @param character
* @returns {string}
*/
function getCharacterCard(character) {
return `
<div class="card mb-3 col-sm-12 col-md-6 col-lg-4">
<div class="row g-0">
<div class="col-4">
<img src="${character.thumbnail}"
style="max-width: 100%;"
alt="${character.name}"
>
</div>
<div class="col-8">
<div class="card-body">
<h5 class="card-title">${character.name}</h5>
<button type="button"
data-bs-toggle="modal"
data-bs-target="#exampleModal-${character.id}"
class="btn btn-secondary btn-sm"
>Подробнее</button>
</div>
</div>
</div>
</div>
`;
}
/**
* Получить модальное окно персонажа
*
* @param character
* @returns {string}
*/
function getCharacterModal(character) {
return `
<div id="exampleModal-${character.id}"
tabindex="-1"
aria-labelledby="exampleModalLabel-${character.id}"
class="modal fade"
style="display: none;"
aria-hidden="true"
>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">${character.name}</h5>
<button type="button"
data-bs-dismiss="modal"
aria-label="Close"
class="btn-close"
></button>
</div>
<div class="modal-body">
<img src="${character.thumbnail}"
style="max-width: 100%;"
alt="${character.name}"
>
<div>
<p class="text-muted">${character.modified}</p>
<h5>Описание:</h5>
<p>${character.description || 'Описание отсутствует'}</p>
</div>
<div class="modal-footer">
<button type="button"
data-bs-dismiss="modal"
class="btn btn-secondary btn-sm"
>Закрыть</button>
</div>
</div>
</div>
</div>
</div>
`;
}
/**
* получим информацию о персонажах с API
*/
function fetchCharacters() {
return fetch('https://cdn.jsdelivr.net/gh/akabab/superhero-api@0.3.0/api/all.json')
.then(response => {
if (!response.ok) {
throw new Error('Ошибка загрузки данных');
}
return response.json();
})
.then(data => {
const characters = data.map((hero, index) => ({
id: index,
name: hero.name,
thumbnail: hero.images.xs,
description: hero.biography.fullName || 'Нет описания',
modified: hero.appearance.race || 'Неизвестно'
}));
return characters;
})
.catch(error => {
console.error('Ошибка при загрузке персонажей:', error);
return [];
});
}
/**
* Получить массив карточек персонажей
*
* @param characters
* @returns {Array}
*/
function getCharacterCards(characters) {
const cards = [];
if (!characters || !Array.isArray(characters)) {
return cards;
}
for (let i = 0; i < characters.length; i++) {
const cardHtml = getCharacterCard(characters[i]);
cards.push(cardHtml);
}
return cards;
}
/**
* Получить массив модальных окон персонажей
*
* @param characters
* @returns {Array}
*/
function getCharacterModals(characters) {
const modals = [];
if (!characters || !Array.isArray(characters)) {
return modals;
}
for (let i = 0; i < characters.length; i++) {
const modalHtml = getCharacterModal(characters[i]);
modals.push(modalHtml);
}
return modals;
}
async function displayCharacters() {
const container = document.getElementById('characters-container');
if (container) {
container.innerHTML = '<div class="text-center"><div class="spinner-border" role="status"><span class="visually-hidden">Загрузка...</span></div></div>';
}
const characters = await fetchCharacters();
const cards = getCharacterCards(characters);
const modals = getCharacterModals(characters);
if (container) {
container.innerHTML = cards.join('');
}
const modalsContainer = document.getElementById('modals-container');
if (modalsContainer) {
modalsContainer.innerHTML = modals.join('');
} else {
const modalWrapper = document.createElement('div');
modalWrapper.id = 'modals-container';
modalWrapper.innerHTML = modals.join('');
document.body.appendChild(modalWrapper);
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', displayCharacters);
} else {
displayCharacters();
}