/
RoditelevVV
/
web-static-labs
Обзор
Документация
Войти
/
RoditelevVV
/
web-static-labs
Код
Запросы
0
Задачи
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
html/lab6/task5/script.js
283 строки
11 KB
karpov
finish lab5, proba lab6
19 мар 2026, 17:02
19 мар 2026, 17:02
e0606a0
Код
Авторство
О чём код?
'use strict'; class AnimalGallery { constructor() { // API endpoints для кошек (как было - работает) this.catApiUrl = 'https://api.thecatapi.com/v1/images/search'; this.catBackupUrl = 'https://cataas.com/cat?json=true'; // API endpoints для собак - несколько вариантов this.dogApis = [ { url: 'https://dog.ceo/api/breeds/image/random', name: 'Dog CEO', parser: (data) => data.message }, { url: 'https://random.dog/woof.json', name: 'Random.dog', parser: (data) => data.url }, { url: 'https://shibe.online/api/shibes?count=1&urls=true&httpsUrls=true', name: 'Shibe.online', parser: (data) => data[0] } ]; // Ключ для localStorage this.STORAGE_KEY = 'favorite_animals'; // Элементы DOM this.radioCat = document.querySelector('input[value="cat"]'); this.radioDog = document.querySelector('input[value="dog"]'); this.loadBtn = document.getElementById('loadBtn'); this.favoriteBtn = document.getElementById('favoriteBtn'); this.imageContainer = document.getElementById('imageContainer'); this.currentIndicator = document.getElementById('currentIndicator'); this.favoritesGrid = document.getElementById('favoritesGrid'); this.emptyFavorites = document.getElementById('emptyFavorites'); this.favoritesCount = document.getElementById('favoritesCount'); this.clearFavoritesBtn = document.getElementById('clearFavoritesBtn'); // Текущее изображение this.currentImage = null; // Массив избранного this.favorites = []; this.init(); } init() { this.loadFavorites(); this.loadBtn.addEventListener('click', () => this.loadImage()); this.favoriteBtn.addEventListener('click', () => this.addToFavorites()); this.clearFavoritesBtn.addEventListener('click', () => this.clearFavorites()); this.renderFavorites(); } async loadImage() { const isCat = this.radioCat.checked; this.showLoading(); this.favoriteBtn.disabled = true; try { let imageUrl; let source = ''; if (isCat) { // Загрузка кошки - ПРОСТОЙ И РАБОЧИЙ КОД try { // Пробуем основной API const response = await fetch(this.catApiUrl); if (!response.ok) throw new Error('Ошибка'); const data = await response.json(); imageUrl = data[0].url; source = 'The Cat API'; } catch (e) { console.log('Первый API кошек не сработал, пробуем запасной...'); // Пробуем запасной CATAAS const backupResponse = await fetch(this.catBackupUrl); if (!backupResponse.ok) throw new Error('Ошибка'); const backupData = await backupResponse.json(); imageUrl = 'https://cataas.com' + backupData.url; source = 'CATAAS'; } } else { // Загрузка собаки - перебираем все API for (let i = 0; i < this.dogApis.length; i++) { const api = this.dogApis[i]; try { console.log(`Пробуем ${api.name}...`); const response = await fetch(api.url); if (!response.ok) continue; const data = await response.json(); imageUrl = api.parser(data); if (imageUrl) { source = api.name; break; } } catch (e) { console.log(`${api.name} не сработал`); continue; } } if (!imageUrl) { throw new Error('Ни один API собак не сработал'); } } this.currentImage = { url: imageUrl, type: isCat ? 'cat' : 'dog', loadedAt: new Date().toISOString(), source: source }; this.displayImage(this.currentImage); this.favoriteBtn.disabled = false; } catch (error) { console.error('Ошибка:', error); this.showError('Не удалось загрузить изображение'); // Запасной вариант - заглушка const isCat = this.radioCat.checked; const placeholderUrl = isCat ? `https://placekitten.com/400/300?image=${Math.floor(Math.random() * 10) + 1}` : `https://placedog.net/400/300?random=${Math.floor(Math.random() * 100)}`; this.currentImage = { url: placeholderUrl, type: isCat ? 'cat' : 'dog', loadedAt: new Date().toISOString(), source: 'Placeholder' }; this.displayImage(this.currentImage); this.favoriteBtn.disabled = false; } } displayImage(image) { const animalType = image.type === 'cat' ? '🐱 Кошка' : '🐶 Собака'; this.imageContainer.innerHTML = ` <img src="${image.url}" alt="${animalType}" class="animal-image" onerror="this.onerror=null; this.src='https://via.placeholder.com/400x300?text=Ошибка'"> `; let sourceText = image.source ? ` (${image.source})` : ''; this.currentIndicator.innerHTML = ` Текущее: ${animalType} • ${this.formatDate(image.loadedAt)}${sourceText} `; } addToFavorites() { if (!this.currentImage) return; const exists = this.favorites.some(fav => fav.url === this.currentImage.url); if (exists) { alert('Это изображение уже есть в избранном'); return; } const favorite = { id: Date.now().toString() + Math.random().toString(36).substr(2, 5), url: this.currentImage.url, type: this.currentImage.type, addedAt: new Date().toISOString() }; this.favorites.unshift(favorite); this.saveFavorites(); this.renderFavorites(); this.showNotification('Добавлено в избранное! ❤️'); } removeFromFavorites(id) { this.favorites = this.favorites.filter(fav => fav.id !== id); this.saveFavorites(); this.renderFavorites(); } clearFavorites() { if (this.favorites.length === 0) return; if (confirm('Очистить всё избранное?')) { this.favorites = []; this.saveFavorites(); this.renderFavorites(); } } loadFavorites() { try { const saved = localStorage.getItem(this.STORAGE_KEY); if (saved) { this.favorites = JSON.parse(saved); } } catch (error) { console.error('Ошибка загрузки избранного:', error); this.favorites = []; } } saveFavorites() { try { localStorage.setItem(this.STORAGE_KEY, JSON.stringify(this.favorites)); } catch (error) { console.error('Ошибка сохранения избранного:', error); alert('Не удалось сохранить избранное'); } } renderFavorites() { this.favoritesCount.textContent = this.favorites.length; if (this.favorites.length === 0) { this.favoritesGrid.innerHTML = ''; this.emptyFavorites.style.display = 'block'; return; } this.emptyFavorites.style.display = 'none'; let html = ''; this.favorites.forEach(fav => { const animalIcon = fav.type === 'cat' ? '🐱' : '🐶'; const animalName = fav.type === 'cat' ? 'Кошка' : 'Собака'; const addedDate = this.formatDate(fav.addedAt); html += ` <div class="favorite-card"> <img src="${fav.url}" alt="${animalName}" class="favorite-image" onclick="window.open('${fav.url}', '_blank')" onerror="this.src='https://via.placeholder.com/200x150?text=Ошибка'"> <div class="favorite-info"> <div class="favorite-type">${animalIcon} ${animalName}</div> <div class="favorite-date">${addedDate}</div> <div class="favorite-actions"> <button class="btn-danger" onclick="window.gallery.removeFromFavorites('${fav.id}')">✕</button> </div> </div> </div> `; }); this.favoritesGrid.innerHTML = html; } formatDate(isoString) { const date = new Date(isoString); return date.toLocaleString('ru-RU'); } showLoading() { this.imageContainer.innerHTML = '<p class="loading">⏳ Загрузка...</p>'; this.currentIndicator.innerHTML = ''; } showError(message) { this.imageContainer.innerHTML = `<p class="error">❌ ${message}</p>`; } showNotification(message) { const notification = document.createElement('div'); notification.style.cssText = ` position: fixed; top: 20px; right: 20px; background-color: #28a745; color: white; padding: 10px 20px; border-radius: 5px; z-index: 1000; `; notification.textContent = message; document.body.appendChild(notification); setTimeout(() => notification.remove(), 2000); } } document.addEventListener('DOMContentLoaded', () => { window.gallery = new AnimalGallery(); });