/
RoditelevVV
/
web-static-labs
Обзор
Документация
Войти
/
RoditelevVV
/
web-static-labs
Код
Запросы
0
Задачи
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
html/lab5/task2/script.js
231 строка
7 KB
karpov
finish lab3, lab4
12 мар 2026, 08:19
12 мар 2026, 08:19
74cd197
Код
Авторство
О чём код?
class TodoApp { constructor() { this.tasks = JSON.parse(localStorage.getItem('todoTasks')) || []; this.initializeElements(); this.setupEventListeners(); this.renderTasks(); this.updateTasksCount(); } initializeElements() { this.taskInput = document.getElementById('taskInput'); this.addTaskBtn = document.getElementById('addTaskBtn'); this.tasksList = document.getElementById('tasksList'); this.emptyState = document.getElementById('emptyState'); this.tasksCount = document.getElementById('tasksCount'); } setupEventListeners() { this.addTaskBtn.addEventListener('click', () => { this.addTask(); }); this.taskInput.addEventListener('keydown', (e) => { if (e.key === 'Enter' && e.ctrlKey) { e.preventDefault(); this.addTask(); } }); this.taskInput.addEventListener('input', function() { this.style.height = 'auto'; this.style.height = (this.scrollHeight) + 'px'; }); } addTask() { const taskText = this.taskInput.value.trim(); if (!taskText) { this.showNotification('Введите текст задачи!', 'error'); this.taskInput.focus(); return; } const newTask = { id: Date.now(), text: taskText, date: new Date().toLocaleString('ru-RU'), timestamp: Date.now() }; this.tasks.unshift(newTask); this.saveTasks(); this.renderTasks(); this.updateTasksCount(); this.taskInput.value = ''; this.taskInput.style.height = 'auto'; this.showNotification('Задача добавлена!', 'success'); this.taskInput.focus(); } deleteTask(taskId) { this.tasks = this.tasks.filter(task => task.id !== taskId); this.saveTasks(); this.renderTasks(); this.updateTasksCount(); this.showNotification('Задача удалена!', 'success'); } async copyToClipboard(taskText) { try { await navigator.clipboard.writeText(taskText); this.showNotification('Текст задачи скопирован в буфер!', 'success'); } catch (err) { const textArea = document.createElement('textarea'); textArea.value = taskText; document.body.appendChild(textArea); textArea.select(); try { document.execCommand('copy'); this.showNotification('Текст задачи скопирован в буфер!', 'success'); } catch (fallbackErr) { this.showNotification('Не удалось скопировать текст', 'error'); } document.body.removeChild(textArea); } } renderTasks() { if (this.tasks.length === 0) { this.tasksList.innerHTML = ''; this.tasksList.appendChild(this.emptyState); return; } this.tasksList.innerHTML = ''; this.tasks.forEach(task => { const taskElement = this.createTaskElement(task); this.tasksList.appendChild(taskElement); }); } createTaskElement(task) { const taskDiv = document.createElement('div'); taskDiv.className = 'task-item new-task'; taskDiv.innerHTML = ` <div class="task-header"> <div class="task-date">📅 ${task.date}</div> </div> <div class="task-content">${this.escapeHtml(task.text)}</div> <div class="task-actions"> <button class="action-btn copy-btn" data-task-id="${task.id}"> 📋 Копировать в буфер </button> <button class="action-btn delete-btn" data-task-id="${task.id}"> 🗑️ Удалить задачу </button> </div> `; setTimeout(() => { taskDiv.classList.remove('new-task'); }, 300); const copyBtn = taskDiv.querySelector('.copy-btn'); const deleteBtn = taskDiv.querySelector('.delete-btn'); copyBtn.addEventListener('click', () => { this.copyToClipboard(task.text); }); deleteBtn.addEventListener('click', () => { if (confirm('Вы уверены, что хотите удалить эту задачу?')) { this.deleteTask(task.id); } }); return taskDiv; } updateTasksCount() { this.tasksCount.textContent = this.tasks.length; } saveTasks() { localStorage.setItem('todoTasks', JSON.stringify(this.tasks)); } escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } showNotification(message, type = 'info') { // Создаем уведомление const notification = document.createElement('div'); notification.className = `notification ${type}`; notification.textContent = message; notification.style.cssText = ` position: fixed; top: 20px; right: 20px; padding: 15px 20px; border-radius: 8px; color: white; font-weight: 500; z-index: 1000; animation: slideIn 0.3s ease-out; max-width: 300px; `; if (type === 'success') { notification.style.background = 'linear-gradient(135deg, #00b09b, #96c93d)'; } else if (type === 'error') { notification.style.background = 'linear-gradient(135deg, #ff416c, #ff4b2b)'; } else { notification.style.background = 'linear-gradient(135deg, #667eea, #764ba2)'; } document.body.appendChild(notification); setTimeout(() => { notification.style.animation = 'slideOut 0.3s ease-in'; setTimeout(() => { if (notification.parentNode) { notification.parentNode.removeChild(notification); } }, 300); }, 3000); if (!document.querySelector('#notification-styles')) { const style = document.createElement('style'); style.id = 'notification-styles'; style.textContent = ` @keyframes slideIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } @keyframes slideOut { from { transform: translateX(0); opacity: 1; } to { transform: translateX(100%); opacity: 0; } } `; document.head.appendChild(style); } } } document.addEventListener('DOMContentLoaded', () => { new TodoApp(); });