반응형
4. 확장 가능한 프로젝트 구조
프로젝트 구조를 확장 가능하게 설계하면 나중에 기능을 추가하거나 유지보수하기가 쉬워집니다. 다음은 Simple To-Do List 프로젝트의 확장 가능한 디렉토리 및 파일 구조 예시입니다:
simple-to-do-list/
│
├── index.html
├── css/
│ └── style.css
├── js/
│ ├── app.js
│ ├── storage.js
│ └── ui.js
└── assets/
└── images/
└── logo.png
디렉토리 및 파일 설명
index.html:
- 프로젝트의 메인 HTML 파일입니다. 전체 구조를 정의하고, 필요한 CSS와 JavaScript 파일을 포함합니다.
css/style.css:
- 모든 스타일 관련 정의가 들어있는 CSS 파일입니다. 필요에 따라 더 많은 CSS 파일을 생성할 수 있습니다.
js/app.js:
- 애플리케이션의 주요 로직이 들어있는 JavaScript 파일입니다. 다른 모듈을 통합하고 전체 애플리케이션을 관리합니다.
js/storage.js:
- 로컬 스토리지와의 상호작용을 처리하는 모듈입니다. 할 일 데이터를 저장하고 불러오는 기능을 포함합니다.
js/ui.js:
- 사용자 인터페이스 관련 기능을 처리하는 모듈입니다. 할 일 추가, 수정, 삭제 시 UI 업데이트를 담당합니다.
assets/images/:
- 프로젝트에서 사용하는 모든 이미지 파일을 저장하는 디렉토리입니다. 예시로 로고 이미지가 포함되어 있습니다.
각 파일의 예시 코드
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple To-Do List</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="container">
<h1>To-Do List</h1>
<div class="input-container">
<input type="text" id="todo-input" placeholder="Add a new task...">
<button id="add-btn">Add</button>
</div>
<ul id="todo-list"></ul>
</div>
<script src="js/storage.js"></script>
<script src="js/ui.js"></script>
<script src="js/app.js"></script>
</body>
</html>
css/style.css
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.container {
background: white;
padding: 20px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
width: 300px;
}
h1 {
text-align: center;
}
.input-container {
display: flex;
justify-content: space-between;
margin-bottom: 20px;
}
#todo-input {
flex: 1;
padding: 10px;
}
#add-btn {
padding: 10px;
margin-left: 10px;
}
#todo-list {
list-style: none;
padding: 0;
}
.todo-item {
padding: 10px;
background: #eee;
margin-bottom: 10px;
border-radius: 5px;
display: flex;
justify-content: space-between;
align-items: center;
}
.todo-item.completed {
text-decoration: line-through;
opacity: 0.6;
}
js/app.js
document.addEventListener('DOMContentLoaded', () => {
const todoInput = document.getElementById('todo-input');
const addBtn = document.getElementById('add-btn');
const todoList = document.getElementById('todo-list');
addBtn.addEventListener('click', () => {
const todoText = todoInput.value.trim();
if (todoText !== '') {
addTodoItem(todoText);
todoInput.value = '';
}
});
todoList.addEventListener('click', (event) => {
if (event.target.classList.contains('delete-btn')) {
deleteTodoItem(event.target.parentElement);
} else if (event.target.classList.contains('todo-item')) {
toggleCompleteTodoItem(event.target);
}
});
loadTodoItems();
});
function addTodoItem(todoText) {
const todoItem = createTodoItemElement(todoText);
saveTodoItem(todoText);
document.getElementById('todo-list').appendChild(todoItem);
}
function deleteTodoItem(todoItem) {
removeTodoItem(todoItem.textContent.trim());
todoItem.remove();
}
function toggleCompleteTodoItem(todoItem) {
todoItem.classList.toggle('completed');
updateTodoItemStatus(todoItem.textContent.trim());
}
js/storage.js
function loadTodoItems() {
const todoItems = JSON.parse(localStorage.getItem('todoItems')) || [];
todoItems.forEach(item => {
const todoItem = createTodoItemElement(item.text, item.completed);
document.getElementById('todo-list').appendChild(todoItem);
});
}
function saveTodoItem(todoText) {
const todoItems = JSON.parse(localStorage.getItem('todoItems')) || [];
todoItems.push({ text: todoText, completed: false });
localStorage.setItem('todoItems', JSON.stringify(todoItems));
}
function removeTodoItem(todoText) {
let todoItems = JSON.parse(localStorage.getItem('todoItems')) || [];
todoItems = todoItems.filter(item => item.text !== todoText);
localStorage.setItem('todoItems', JSON.stringify(todoItems));
}
function updateTodoItemStatus(todoText) {
const todoItems = JSON.parse(localStorage.getItem('todoItems')) || [];
const todoItem = todoItems.find(item => item.text === todoText);
if (todoItem) {
todoItem.completed = !todoItem.completed;
localStorage.setItem('todoItems', JSON.stringify(todoItems));
}
}
js/ui.js
function createTodoItemElement(todoText, completed = false) {
const todoItem = document.createElement('li');
todoItem.textContent = todoText;
todoItem.classList.add('todo-item');
if (completed) {
todoItem.classList.add('completed');
}
const deleteBtn = document.createElement('button');
deleteBtn.textContent = 'Delete';
deleteBtn.classList.add('delete-btn');
todoItem.appendChild(deleteBtn);
return todoItem;
}
반응형
'Javascript 프로젝트 > 02_To Do List' 카테고리의 다른 글
[To Do List] 다음 단계 (0) | 2024.06.16 |
---|---|
[To Do List] 5단계: 단계별 진행 및 코드 주석과 Git 커밋 메시지 (0) | 2024.06.16 |
[To Do List] 3단계: 규칙 설정 (0) | 2024.06.16 |
[To Do List] 2단계: README.md 작성 (0) | 2024.06.16 |
[To Do List] 1단계: 프로젝트명과 설명 (0) | 2024.06.16 |