JavaScript Eğitimi #10: Proje - Todo Uygulaması - Tüm Öğrenilenleri Birleştirin
JavaScript eğitim serisinin final projesi. Sıfırdan tam fonksiyonlu bir Todo uygulaması geliştirerek tüm öğrendiklerinizi pratiğe dökün.
JavaScript Eğitimi #10: Proje - Todo Uygulaması
Bu seride JavaScript'in temellerini öğrendik: değişkenler, koşullar, döngüler, fonksiyonlar, diziler, nesneler, DOM manipülasyonu ve event yönetimi. Şimdi tüm bu bilgileri birleştirip gerçek bir uygulama yapmanın zamanı geldi.
Todo (yapılacaklar listesi) uygulaması, programlama öğrenirken yapılan klasik projelerden biridir. Basit görünse de temel CRUD (Create, Read, Update, Delete) işlemlerini, state yönetimini ve veri kalıcılığını içerir. Bu derste adım adım bir Todo uygulaması geliştireceğiz.
İçindekiler
- Proje Gereksinimleri
- HTML Yapısı
- CSS Stilleri
- JavaScript - Temel Yapı
- Todo Ekleme
- Todo Listeleme
- Todo Silme
- Todo Tamamlama
- Filtreleme
- LocalStorage ile Kalıcılık
- Düzenleme Özelliği
- Son Dokunuşlar
- Tam Kod
- Sonraki Adımlar
- Sık Sorulan Sorular
- Sonuç
Proje Gereksinimleri
Uygulamamız şu özelliklere sahip olacak:
Temel Özellikler:
- Todo ekleme (metin girişi)
- Todo silme
- Todo tamamlandı olarak işaretleme
- Tüm todoları listeleme
İleri Özellikler:
- Filtreleme (tümü, aktif, tamamlanan)
- LocalStorage ile veri kalıcılığı
- Todo düzenleme
- Tümünü temizle butonu
- Kalan görev sayısı
HTML Yapısı
Önce HTML iskeletimizi oluşturalım:
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Todo Uygulaması</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<header class="header">
<h1>Todo List</h1>
</header>
<main class="main">
<!-- Todo Ekleme Formu -->
<form id="todoForm" class="todo-form">
<input
type="text"
id="todoInput"
class="todo-input"
placeholder="Yeni görev ekle..."
autocomplete="off"
>
<button type="submit" class="btn btn-primary">Ekle</button>
</form>
<!-- Filtre Butonları -->
<div class="filters">
<button class="filter-btn active" data-filter="all">Tümü</button>
<button class="filter-btn" data-filter="active">Aktif</button>
<button class="filter-btn" data-filter="completed">Tamamlanan</button>
</div>
<!-- Todo Listesi -->
<ul id="todoList" class="todo-list"></ul>
<!-- Alt Bilgi -->
<footer class="footer">
<span id="todoCount" class="todo-count">0 görev kaldı</span>
<button id="clearCompleted" class="btn btn-secondary">
Tamamlananları Temizle
</button>
</footer>
</main>
</div>
<script src="app.js"></script>
</body>
</html>CSS Stilleri
Şimdi uygulamayı güzelleştirelim:
/* style.css */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--primary-color: #4f46e5;
--primary-hover: #4338ca;
--danger-color: #ef4444;
--danger-hover: #dc2626;
--success-color: #22c55e;
--text-color: #1f2937;
--text-light: #6b7280;
--bg-color: #f3f4f6;
--card-bg: #ffffff;
--border-color: #e5e7eb;
--shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background-color: var(--bg-color);
color: var(--text-color);
min-height: 100vh;
padding: 40px 20px;
}
.container {
max-width: 600px;
margin: 0 auto;
}
/* Header */
.header {
text-align: center;
margin-bottom: 30px;
}
.header h1 {
font-size: 2.5rem;
color: var(--primary-color);
font-weight: 700;
}
/* Main */
.main {
background: var(--card-bg);
border-radius: 16px;
box-shadow: var(--shadow);
padding: 24px;
}
/* Form */
.todo-form {
display: flex;
gap: 12px;
margin-bottom: 20px;
}
.todo-input {
flex: 1;
padding: 12px 16px;
font-size: 1rem;
border: 2px solid var(--border-color);
border-radius: 8px;
outline: none;
transition: border-color 0.2s;
}
.todo-input:focus {
border-color: var(--primary-color);
}
/* Buttons */
.btn {
padding: 12px 20px;
font-size: 1rem;
font-weight: 500;
border: none;
border-radius: 8px;
cursor: pointer;
transition: background-color 0.2s, transform 0.1s;
}
.btn:active {
transform: scale(0.98);
}
.btn-primary {
background-color: var(--primary-color);
color: white;
}
.btn-primary:hover {
background-color: var(--primary-hover);
}
.btn-secondary {
background-color: transparent;
color: var(--text-light);
}
.btn-secondary:hover {
background-color: var(--bg-color);
}
.btn-danger {
background-color: var(--danger-color);
color: white;
padding: 6px 12px;
font-size: 0.875rem;
}
.btn-danger:hover {
background-color: var(--danger-hover);
}
/* Filters */
.filters {
display: flex;
gap: 8px;
margin-bottom: 20px;
padding-bottom: 16px;
border-bottom: 1px solid var(--border-color);
}
.filter-btn {
padding: 8px 16px;
font-size: 0.875rem;
background: transparent;
border: 1px solid var(--border-color);
border-radius: 20px;
cursor: pointer;
transition: all 0.2s;
}
.filter-btn:hover {
border-color: var(--primary-color);
color: var(--primary-color);
}
.filter-btn.active {
background-color: var(--primary-color);
border-color: var(--primary-color);
color: white;
}
/* Todo List */
.todo-list {
list-style: none;
margin-bottom: 20px;
}
.todo-item {
display: flex;
align-items: center;
gap: 12px;
padding: 16px;
background: var(--bg-color);
border-radius: 8px;
margin-bottom: 8px;
transition: all 0.2s;
}
.todo-item:hover {
transform: translateX(4px);
}
.todo-item.completed {
opacity: 0.6;
}
.todo-item.completed .todo-text {
text-decoration: line-through;
color: var(--text-light);
}
/* Checkbox */
.todo-checkbox {
width: 22px;
height: 22px;
border: 2px solid var(--border-color);
border-radius: 50%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
transition: all 0.2s;
}
.todo-checkbox:hover {
border-color: var(--primary-color);
}
.todo-item.completed .todo-checkbox {
background-color: var(--success-color);
border-color: var(--success-color);
}
.todo-item.completed .todo-checkbox::after {
content: "✓";
color: white;
font-size: 14px;
}
/* Todo Text */
.todo-text {
flex: 1;
font-size: 1rem;
word-break: break-word;
}
/* Edit Input */
.todo-edit-input {
flex: 1;
padding: 8px 12px;
font-size: 1rem;
border: 2px solid var(--primary-color);
border-radius: 4px;
outline: none;
}
/* Actions */
.todo-actions {
display: flex;
gap: 8px;
opacity: 0;
transition: opacity 0.2s;
}
.todo-item:hover .todo-actions {
opacity: 1;
}
.action-btn {
padding: 6px;
background: transparent;
border: none;
cursor: pointer;
color: var(--text-light);
font-size: 1rem;
border-radius: 4px;
transition: all 0.2s;
}
.action-btn:hover {
background: var(--card-bg);
}
.action-btn.delete:hover {
color: var(--danger-color);
}
.action-btn.edit:hover {
color: var(--primary-color);
}
/* Footer */
.footer {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 16px;
border-top: 1px solid var(--border-color);
}
.todo-count {
color: var(--text-light);
font-size: 0.875rem;
}
/* Empty State */
.empty-state {
text-align: center;
padding: 40px;
color: var(--text-light);
}
.empty-state-icon {
font-size: 3rem;
margin-bottom: 16px;
}
/* Responsive */
@media (max-width: 480px) {
.todo-form {
flex-direction: column;
}
.filters {
flex-wrap: wrap;
}
.footer {
flex-direction: column;
gap: 12px;
}
}JavaScript - Temel Yapı
Şimdi JavaScript dosyamızı oluşturalım. Modüler bir yapı kullanacağız:
// app.js
// State (Uygulama Durumu)
let todos = [];
let currentFilter = "all";
// DOM Elementleri
const todoForm = document.getElementById("todoForm");
const todoInput = document.getElementById("todoInput");
const todoList = document.getElementById("todoList");
const todoCount = document.getElementById("todoCount");
const clearCompletedBtn = document.getElementById("clearCompleted");
const filterBtns = document.querySelectorAll(".filter-btn");
// Storage Key
const STORAGE_KEY = "todos";
// Uygulama Başlatma
function init() {
// LocalStorage'dan todoları yükle
loadTodos();
// Event Listener'ları ekle
todoForm.addEventListener("submit", handleFormSubmit);
todoList.addEventListener("click", handleTodoClick);
clearCompletedBtn.addEventListener("click", clearCompleted);
filterBtns.forEach(btn => {
btn.addEventListener("click", handleFilterClick);
});
// İlk render
renderTodos();
}
// Sayfa yüklendiğinde başlat
document.addEventListener("DOMContentLoaded", init);Todo Ekleme
Form submit edildiğinde yeni todo ekleyelim:
// Unique ID oluşturma
function generateId() {
return Date.now().toString(36) + Math.random().toString(36).substr(2);
}
// Form submit handler
function handleFormSubmit(e) {
e.preventDefault();
const text = todoInput.value.trim();
// Boş kontrolü
if (!text) {
todoInput.focus();
return;
}
// Yeni todo oluştur
const newTodo = {
id: generateId(),
text: text,
completed: false,
createdAt: new Date().toISOString()
};
// State'e ekle
todos.unshift(newTodo); // Başa ekle
// LocalStorage'a kaydet
saveTodos();
// UI güncelle
renderTodos();
// Input'u temizle
todoInput.value = "";
todoInput.focus();
}Todo Listeleme
Todoları DOM'a render edelim:
// Todoları render et
function renderTodos() {
// Filtrelenmiş todoları al
const filteredTodos = getFilteredTodos();
// Liste boşsa
if (filteredTodos.length === 0) {
todoList.innerHTML = `
<li class="empty-state">
<div class="empty-state-icon">📝</div>
<p>${getEmptyMessage()}</p>
</li>
`;
} else {
// Todoları HTML'e çevir
todoList.innerHTML = filteredTodos.map(todo => createTodoHTML(todo)).join("");
}
// Sayacı güncelle
updateCount();
}
// Tek bir todo için HTML oluştur
function createTodoHTML(todo) {
return `
<li class="todo-item ${todo.completed ? 'completed' : ''}" data-id="${todo.id}">
<div class="todo-checkbox" data-action="toggle"></div>
<span class="todo-text">${escapeHTML(todo.text)}</span>
<div class="todo-actions">
<button class="action-btn edit" data-action="edit" title="Düzenle">✏️</button>
<button class="action-btn delete" data-action="delete" title="Sil">🗑️</button>
</div>
</li>
`;
}
// XSS önleme - HTML escape
function escapeHTML(text) {
const div = document.createElement("div");
div.textContent = text;
return div.innerHTML;
}
// Filtrelenmiş todoları getir
function getFilteredTodos() {
switch (currentFilter) {
case "active":
return todos.filter(todo => !todo.completed);
case "completed":
return todos.filter(todo => todo.completed);
default:
return todos;
}
}
// Boş mesajı getir
function getEmptyMessage() {
switch (currentFilter) {
case "active":
return "Aktif görev yok 🎉";
case "completed":
return "Tamamlanan görev yok";
default:
return "Henüz görev eklenmemiş";
}
}
// Kalan görev sayısını güncelle
function updateCount() {
const activeCount = todos.filter(todo => !todo.completed).length;
todoCount.textContent = `${activeCount} görev kaldı`;
}Todo Silme
Event delegation kullanarak silme işlemi:
// Todo üzerindeki tıklamaları yönet
function handleTodoClick(e) {
const action = e.target.dataset.action;
if (!action) return;
const todoItem = e.target.closest(".todo-item");
if (!todoItem) return;
const todoId = todoItem.dataset.id;
switch (action) {
case "toggle":
toggleTodo(todoId);
break;
case "delete":
deleteTodo(todoId);
break;
case "edit":
editTodo(todoId);
break;
}
}
// Todo sil
function deleteTodo(id) {
// Onay sor (opsiyonel)
// if (!confirm("Bu görevi silmek istediğinize emin misiniz?")) return;
// State'den kaldır
todos = todos.filter(todo => todo.id !== id);
// Kaydet ve render et
saveTodos();
renderTodos();
}
// Tamamlananları temizle
function clearCompleted() {
const completedCount = todos.filter(todo => todo.completed).length;
if (completedCount === 0) {
alert("Silinecek tamamlanmış görev yok.");
return;
}
if (confirm(`${completedCount} tamamlanmış görevi silmek istiyor musunuz?`)) {
todos = todos.filter(todo => !todo.completed);
saveTodos();
renderTodos();
}
}Todo Tamamlama
Tamamlandı durumunu toggle edelim:
// Todo tamamla/geri al
function toggleTodo(id) {
todos = todos.map(todo => {
if (todo.id === id) {
return {
...todo,
completed: !todo.completed,
completedAt: !todo.completed ? new Date().toISOString() : null
};
}
return todo;
});
saveTodos();
renderTodos();
}Filtreleme
Filtre butonlarını yönetelim:
// Filtre tıklama handler
function handleFilterClick(e) {
const filter = e.target.dataset.filter;
if (filter === currentFilter) return;
// Aktif sınıfı güncelle
filterBtns.forEach(btn => {
btn.classList.toggle("active", btn.dataset.filter === filter);
});
// Filtreyi güncelle ve render et
currentFilter = filter;
renderTodos();
}LocalStorage ile Kalıcılık
Verileri tarayıcıda kalıcı olarak saklayalım:
// Todoları LocalStorage'a kaydet
function saveTodos() {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(todos));
} catch (error) {
console.error("Kaydetme hatası:", error);
}
}
// Todoları LocalStorage'dan yükle
function loadTodos() {
try {
const saved = localStorage.getItem(STORAGE_KEY);
todos = saved ? JSON.parse(saved) : [];
} catch (error) {
console.error("Yükleme hatası:", error);
todos = [];
}
}Düzenleme Özelliği
Todo metnini düzenleme:
// Todo düzenle
function editTodo(id) {
const todoItem = document.querySelector(`[data-id="${id}"]`);
const todoTextEl = todoItem.querySelector(".todo-text");
const currentText = todos.find(todo => todo.id === id).text;
// Edit moduna geç
todoItem.classList.add("editing");
// Input oluştur
const input = document.createElement("input");
input.type = "text";
input.className = "todo-edit-input";
input.value = currentText;
// Text elementi gizle, input'u ekle
todoTextEl.style.display = "none";
todoTextEl.parentNode.insertBefore(input, todoTextEl);
input.focus();
input.select();
// Kaydetme fonksiyonu
function saveEdit() {
const newText = input.value.trim();
if (newText && newText !== currentText) {
todos = todos.map(todo => {
if (todo.id === id) {
return { ...todo, text: newText };
}
return todo;
});
saveTodos();
}
renderTodos();
}
// İptal fonksiyonu
function cancelEdit() {
renderTodos();
}
// Event listener'lar
input.addEventListener("blur", saveEdit);
input.addEventListener("keydown", (e) => {
if (e.key === "Enter") {
e.preventDefault();
saveEdit();
} else if (e.key === "Escape") {
cancelEdit();
}
});
}Son Dokunuşlar
Birkaç ek özellik ekleyelim:
// Tüm todoları tamamla/geri al
function toggleAll() {
const allCompleted = todos.every(todo => todo.completed);
todos = todos.map(todo => ({
...todo,
completed: !allCompleted
}));
saveTodos();
renderTodos();
}
// Klavye kısayolları
document.addEventListener("keydown", (e) => {
// Ctrl/Cmd + A - Tümünü seç (varsayılanı engelle, toggleAll yap)
if ((e.ctrlKey || e.metaKey) && e.key === "a" && document.activeElement !== todoInput) {
// e.preventDefault();
// toggleAll();
}
});
// Çift tıklama ile düzenleme
todoList.addEventListener("dblclick", (e) => {
const todoItem = e.target.closest(".todo-item");
if (todoItem && e.target.classList.contains("todo-text")) {
editTodo(todoItem.dataset.id);
}
});
// Sürükle-bırak ile sıralama (basit versiyon)
// İleri seviye için SortableJS kütüphanesi önerilirTam Kod
İşte tüm JavaScript kodu bir arada:
// app.js - Todo Uygulaması
// ============ STATE ============
let todos = [];
let currentFilter = "all";
const STORAGE_KEY = "todos";
// ============ DOM ELEMENTS ============
const todoForm = document.getElementById("todoForm");
const todoInput = document.getElementById("todoInput");
const todoList = document.getElementById("todoList");
const todoCount = document.getElementById("todoCount");
const clearCompletedBtn = document.getElementById("clearCompleted");
const filterBtns = document.querySelectorAll(".filter-btn");
// ============ UTILITY FUNCTIONS ============
function generateId() {
return Date.now().toString(36) + Math.random().toString(36).substr(2);
}
function escapeHTML(text) {
const div = document.createElement("div");
div.textContent = text;
return div.innerHTML;
}
function saveTodos() {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(todos));
} catch (error) {
console.error("Kaydetme hatası:", error);
}
}
function loadTodos() {
try {
const saved = localStorage.getItem(STORAGE_KEY);
todos = saved ? JSON.parse(saved) : [];
} catch (error) {
console.error("Yükleme hatası:", error);
todos = [];
}
}
// ============ TODO OPERATIONS ============
function addTodo(text) {
const newTodo = {
id: generateId(),
text: text,
completed: false,
createdAt: new Date().toISOString()
};
todos.unshift(newTodo);
saveTodos();
renderTodos();
}
function deleteTodo(id) {
todos = todos.filter(todo => todo.id !== id);
saveTodos();
renderTodos();
}
function toggleTodo(id) {
todos = todos.map(todo => {
if (todo.id === id) {
return { ...todo, completed: !todo.completed };
}
return todo;
});
saveTodos();
renderTodos();
}
function editTodo(id) {
const todoItem = document.querySelector(`[data-id="${id}"]`);
const todoTextEl = todoItem.querySelector(".todo-text");
const currentText = todos.find(todo => todo.id === id).text;
const input = document.createElement("input");
input.type = "text";
input.className = "todo-edit-input";
input.value = currentText;
todoTextEl.style.display = "none";
todoTextEl.parentNode.insertBefore(input, todoTextEl);
input.focus();
input.select();
function saveEdit() {
const newText = input.value.trim();
if (newText && newText !== currentText) {
todos = todos.map(todo =>
todo.id === id ? { ...todo, text: newText } : todo
);
saveTodos();
}
renderTodos();
}
input.addEventListener("blur", saveEdit);
input.addEventListener("keydown", (e) => {
if (e.key === "Enter") saveEdit();
if (e.key === "Escape") renderTodos();
});
}
function clearCompleted() {
todos = todos.filter(todo => !todo.completed);
saveTodos();
renderTodos();
}
// ============ FILTERING ============
function getFilteredTodos() {
switch (currentFilter) {
case "active":
return todos.filter(todo => !todo.completed);
case "completed":
return todos.filter(todo => todo.completed);
default:
return todos;
}
}
function getEmptyMessage() {
const messages = {
active: "Aktif görev yok 🎉",
completed: "Tamamlanan görev yok",
all: "Henüz görev eklenmemiş"
};
return messages[currentFilter];
}
// ============ RENDERING ============
function createTodoHTML(todo) {
return `
<li class="todo-item ${todo.completed ? 'completed' : ''}" data-id="${todo.id}">
<div class="todo-checkbox" data-action="toggle"></div>
<span class="todo-text">${escapeHTML(todo.text)}</span>
<div class="todo-actions">
<button class="action-btn edit" data-action="edit" title="Düzenle">✏️</button>
<button class="action-btn delete" data-action="delete" title="Sil">🗑️</button>
</div>
</li>
`;
}
function renderTodos() {
const filteredTodos = getFilteredTodos();
if (filteredTodos.length === 0) {
todoList.innerHTML = `
<li class="empty-state">
<div class="empty-state-icon">📝</div>
<p>${getEmptyMessage()}</p>
</li>
`;
} else {
todoList.innerHTML = filteredTodos.map(createTodoHTML).join("");
}
updateCount();
}
function updateCount() {
const activeCount = todos.filter(todo => !todo.completed).length;
todoCount.textContent = `${activeCount} görev kaldı`;
}
// ============ EVENT HANDLERS ============
function handleFormSubmit(e) {
e.preventDefault();
const text = todoInput.value.trim();
if (!text) return;
addTodo(text);
todoInput.value = "";
todoInput.focus();
}
function handleTodoClick(e) {
const action = e.target.dataset.action;
if (!action) return;
const todoItem = e.target.closest(".todo-item");
if (!todoItem) return;
const id = todoItem.dataset.id;
switch (action) {
case "toggle": toggleTodo(id); break;
case "delete": deleteTodo(id); break;
case "edit": editTodo(id); break;
}
}
function handleFilterClick(e) {
const filter = e.target.dataset.filter;
if (filter === currentFilter) return;
filterBtns.forEach(btn => {
btn.classList.toggle("active", btn.dataset.filter === filter);
});
currentFilter = filter;
renderTodos();
}
// ============ INITIALIZATION ============
function init() {
loadTodos();
todoForm.addEventListener("submit", handleFormSubmit);
todoList.addEventListener("click", handleTodoClick);
todoList.addEventListener("dblclick", (e) => {
const todoItem = e.target.closest(".todo-item");
if (todoItem && e.target.classList.contains("todo-text")) {
editTodo(todoItem.dataset.id);
}
});
clearCompletedBtn.addEventListener("click", clearCompleted);
filterBtns.forEach(btn => {
btn.addEventListener("click", handleFilterClick);
});
renderTodos();
}
document.addEventListener("DOMContentLoaded", init);Sonraki Adımlar
Bu temel Todo uygulamasını geliştirmek için:
Özellik Eklemeleri:
- Kategoriler/etiketler
- Öncelik seviyeleri (düşük, orta, yüksek)
- Son tarih belirleme
- Alt görevler
- Sürükle-bırak ile sıralama
Teknik İyileştirmeler:
- TypeScript'e geçiş
- Unit testler ekleme
- PWA (Progressive Web App) yapma
- Backend API ile senkronizasyon
UI İyileştirmeleri:
- Dark mode
- Animasyonlar
- Mobil uyumluluk testleri
- Accessibility (erişilebilirlik)
Sık Sorulan Sorular
Proje dosyalarını nasıl organize etmeliyim?
Basit projeler için tek HTML, CSS ve JS dosyası yeterli. Büyüdükçe modüler yapı kullanın: utils.js, storage.js, ui.js gibi.
localStorage yerine ne kullanabilirim?
IndexedDB (büyük veriler için), Backend API (senkronizasyon için), Firebase/Supabase (hızlı çözüm için).
Projeyi nasıl yayınlarım?
GitHub Pages, Netlify, Vercel gibi platformlara ücretsiz deploy edebilirsiniz. Sadece dosyaları yükleyin.
React/Vue ile yapmak daha mı iyi?
Bu ölçekte fark yok. Framework'ler daha büyük, kompleks projeler için avantaj sağlar. Önce vanilla JS ile temelleri öğrenmek önemli.
Kodumu nasıl geliştirebilirim?
ESLint kullanın, kod incelemeleri yapın, başkalarının kodlarını okuyun, açık kaynak projelere katkıda bulunun.
Sonuç
Tebrikler! 10 bölümlük JavaScript eğitim serisini tamamladınız. Sıfırdan başlayıp tam fonksiyonlu bir uygulama geliştirdiniz.
Bu seride öğrendikleriniz:
- Değişkenler ve veri tipleri
- Operatörler ve koşullar
- Döngüler
- Fonksiyonlar
- Diziler ve array metodları
- Nesneler
- DOM manipülasyonu
- Event yönetimi
- Form işleme ve localStorage
- Gerçek proje geliştirme
Bundan sonra ne yapmalısınız:
- Bu projeyi geliştirmeye devam edin
- Farklı projeler yapın (hava durumu app, not defteri, oyun)
- React, Vue veya Angular öğrenin
- Node.js ile backend geliştirme öğrenin
- TypeScript öğrenin
Programlama öğrenmenin en iyi yolu pratik yapmaktır. Kod yazın, hatalar yapın, onları düzeltin. Her hata bir öğrenme fırsatıdır.
Başarılar dilerim!
Kaynaklar
- GitHub - TodoMVC - Farklı frameworklerde Todo örnekleri
- MDN Web Docs - JavaScript referansı
- javascript.info - Kapsamlı JavaScript eğitimi
- freeCodeCamp - Ücretsiz programlama eğitimi
Seri Özeti
Bu 10 bölümlük JavaScript eğitim serisinde şunları öğrendiniz:
| Bölüm | Konu | Öğrenilenler |
|---|---|---|
| 1 | Giriş ve Ortam Kurulumu | JS nedir, VS Code, ilk kod |
| 2 | Değişkenler ve Veri Tipleri | let, const, string, number, boolean |
| 3 | Operatörler ve Koşullar | if-else, switch, ternary |
| 4 | Döngüler | for, while, break, continue |
| 5 | Fonksiyonlar | Declaration, arrow, scope, closure |
| 6 | Diziler | map, filter, reduce, find |
| 7 | Nesneler | Property, method, JSON, destructuring |
| 8 | DOM Manipülasyonu | querySelector, innerHTML, classList |
| 9 | Events ve Form İşleme | addEventListener, form, localStorage |
| 10 | Proje: Todo App | Tüm konuların birleşimi |
Serinin tamamını bitirdiyseniz, artık JavaScript ile web uygulamaları geliştirebilecek temele sahipsiniz. Öğrenmeye devam edin!
Projenizi Hayata Geçirelim
Web sitesi, mobil uygulama veya yapay zeka çözümü mü arıyorsunuz? Fikirlerinizi birlikte değerlendirelim.
Ücretsiz Danışmanlık Alın