Küçük bir yapılacaklar uygulaması oluşturma rehberi: özellikleri planla, ekranları oluştur, mantığı ekle, veriyi kaydet (localStorage), test et ve yayınla.

Bu rehberde “uygulama” dediğim şey küçük bir web uygulaması: bir tarayıcıda açtığınız, tıklamalarınıza ve yazdıklarınıza tepki veren tek sayfalık bir proje. Kurulum yok, hesap yok, ağır ayarlar yok—sadece yerelde çalıştırabileceğiniz basit bir proje.
Sonunda elinizde şu özelliklere sahip bir yapılacaklar uygulaması olacak:
localStorage kullanarak (sekme kapanınca her şey gitmesin)Mükemmel ya da “kurumsal düzey” olmayacak—ama maksat bu. Bu, çok fazla araçla kafanızı karıştırmadan temel öğeleri öğretmeyi amaçlayan bir başlangıç projesi.
Uygulamayı adım adım inşa ederken ön yüz web uygulamalarının temel parçalarını öğreneceksiniz:
Basit tutun. Sadece şunlara ihtiyacınız var:
Bir klasör oluşturup birkaç dosyayı düzenleyebiliyorsanız hazırsınız.
Herhangi bir kod yazmadan önce “başarı”nın neye benzediğine karar verin. Bu öğretici tek bir iş yapan küçük bir uygulama inşa ediyor: yapmanız gereken işleri takip etmenize yardımcı olmak.
İnşa ederken önünüzde tutabileceğiniz bir cümle hedefi yazın:
“Bu uygulama bana görev eklememi sağlar, böylece unutmam.”
Hepsi bu. Takvimler, hatırlatıcılar, etiketler veya hesaplar ekleme isteği gelirse, bunları sonra düşünün.
Hızlıca iki liste yapın:
Olmazsa olmaz (bu proje için):
İsteğe bağlı (bugün gerekli değil): teslim tarihleri, öncelikler, kategoriler, arama, sürükle-bırak, bulut eşitleme.
“Olmazsa olmaz”ı küçük tutmak işi bitirmenize yardımcı olur.
Bu uygulama tek sayfa olabilir ve şunları içerir:
Tıkandığınızda takılıp kalmayın, açık olun:
Bunu kararlaştırdıktan sonra proje dosyalarını hazırlamaya hazırsınız.
Herhangi bir kod yazmadan önce uygulama için temiz bir “ev” klasörü oluşturalım. Başından itibaren dosyaları düzenli tutmak sonraki adımları kolaylaştırır.
Bilgisayarınızda todo-app gibi bir klasör oluşturun. Bu klasör bu proje için her şeyi tutacak.
Bu klasörün içinde üç dosya oluşturun:
index.html (sayfa yapısı)styles.css (görünüm ve düzen)app.js (davranış ve etkileşim)Bazı bilgisayarlar dosya uzantılarını gizler; gerçek dosyalar oluşturduğunuzdan emin olun. Yeni başlayanların sık yaptığı hata index.html.txt gibi yanlış bir uzantıyla dosya oluşturmaktır.
todo-app klasörünü kod editörünüzde (VS Code, Sublime Text vb.) açın. Sonra index.html dosyasını tarayıcıda açın.
Bu noktada sayfanız boş olabilir—tamam. Bir sonraki adımda içerik ekleyeceğiz.
Dosyaları düzenlediğinizde tarayıcı otomatik güncelleme yapmaz (bunu yapan bir araç kullanmıyorsanız).
Temel döngü şu şekildedir:
Bir şey “çalışmıyorsa”, önce yenilemeyi deneyin.
Bu uygulamayı index.html dosyasına çift tıklayarak da çalıştırabilirsiniz, ama yerel bir sunucu daha sonra (özellikle veri kaydetme veya dosya yükleme başladığında) garip sorunların önüne geçer.
Yeni başlayanlara uygun seçenekler:
python -m http.server
Sonra yazdırdığı adresi (genelde http://localhost:8000) tarayıcıda açın.
Şimdi uygulama için temiz bir iskelet oluşturacağız. Bu HTML henüz etkileşimli yapmayacak (o bir sonraki adım), ama JavaScript'in okuyup yazabileceği net yerler sağlar.
Şunları ekleyeceğiz:
İsimleri basit ve okunabilir tutun. İyi ID'ler/class'lar JavaScript'in elementleri karışmadan seçmesini sağlar.
index.html'e yapıştırın<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>To‑Do App</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<main class="app" id="app">
<h1 class="app__title" id="appTitle">My To‑Do List</h1>
<form class="task-form" id="taskForm">
<label class="task-form__label" for="taskInput">New task</label>
<div class="task-form__row">
<input
id="taskInput"
class="task-form__input"
type="text"
placeholder="e.g., Buy milk"
autocomplete="off"
/>
<button id="addButton" class="task-form__button" type="submit">
Add
</button>
</div>
</form>
<ul class="task-list" id="taskList" aria-label="Task list"></ul>
</main>
<script src="app.js"></script>
</body>
</html>
Yapı için bu kadar. id="taskInput" ve id="taskList" kullandığımıza dikkat edin—bunlar JavaScript'te en çok konuşacağınız iki öğe olacak.
Şu an sayfanız var ama muhtemelen düz bir belge gibi görünüyor. Biraz CSS, daha rahat kullanılır bir arayüz sağlar: düzgün boşluklar, okunaklı metin ve tıklanabilir hissi veren butonlar.
Ortalanmış bir kutu içeriği odaklar ve geniş ekranlarda içeriğin yayılmasını engeller.
/* Basic page setup */
body {
font-family: Arial, sans-serif;
background: #f6f7fb;
margin: 0;
padding: 24px;
}
/* Centered app container */
.container {
max-width: 520px;
margin: 0 auto;
background: #ffffff;
padding: 16px;
border-radius: 10px;
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.08);
}
Her görev ayrı bir “satır” gibi görünmeli, rahat boşlukla.
ul { list-style: none; padding: 0; margin: 16px 0 0; }
li {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 10px 12px;
border: 1px solid #e7e7ee;
border-radius: 8px;
margin-bottom: 10px;
}
.task-text { flex: 1; }
Bir görev tamamlandığında görsel olarak değişmeli ki anında ayırt edilesi:
.done .task-text {
text-decoration: line-through;
color: #777;
opacity: 0.85;
}
Butonların aynı boyutta ve stilde görünmesi uygulamayı bütünleştirir.
button {
border: none;
border-radius: 8px;
padding: 8px 10px;
cursor: pointer;
}
button:hover { filter: brightness(0.95); }
Bu kadar stil, temiz ve dostane bir arayüz için yeterli—ileri seviye numaralara gerek yok. Sonraki adımda JavaScript ile davranışı bağlayacağız.
Artık sayfada giriş, buton ve liste var; bunları işe koyacağız. Amaç basit: biri bir görev yazıp Ekleye (veya Entera) bastığında, listeye yeni öğe eklenmesi.
JavaScript dosyanızda önce gerekli öğeleri seçin, sonra iki eylemi dinleyin: buton tıklaması ve input içindeki Enter tuşu.
const taskInput = document.querySelector('#taskInput');
const addBtn = document.querySelector('#addBtn');
const taskList = document.querySelector('#taskList');
function addTask() {
const text = taskInput.value.trim();
// Block empty tasks (including ones that are just spaces)
if (text === '') return;
const li = document.createElement('li');
li.textContent = text;
taskList.appendChild(li);
// Clear the input and put the cursor back
taskInput.value = '';
taskInput.focus();
}
addBtn.addEventListener('click', addTask);
taskInput.addEventListener('keydown', (event) => {
if (event.key === 'Enter') {
addTask();
}
});
trim() ile temizler.<li> oluşturur, metnini koyar ve listeye ekler.Hiçbir şey olmuyorsa HTML'deki ID'lerin JavaScript seçimlerinizle tam eşleştiğini tekrar kontrol edin (bu yeni başlayanların en sık rastladığı sürtünme noktalarından biridir).
Artık görev ekleyebiliyorsunuz; şimdi onları eyleme geçirilebilir yapalım: bir görevi tamamlandı yapabilmeli ve silebilmelisiniz.
Görevleri sadece düz metinler yerine nesneler olarak saklayın. Bu her görev için sabit bir kimlik ve “tamamlandı” durumunu takip etme yeri sağlar:
text: görev metnidone: true veya falseid: doğru görevi bulup silmek için benzersiz bir sayıBasit bir örnek:
let tasks = [
{ id: 1, text: "Buy milk", done: false },
{ id: 2, text: "Email Sam", done: true }
];
Her görevi render ederken bir checkbox veya “Tamamla” butonu ile bir “Sil” butonu ekleyin.
Bir event listener tıklamalara tepki vermenin yoludur. Bir butona (veya tüm listeye) dinleyici bağlarsınız ve kullanıcı tıkladığında kodunuz çalışır.
Yeni başlayanlar için uygun bir desen event delegationdır: tüm liste konteynerine bir click dinleyicisi koyun, sonra neyin tıklandığını kontrol edin.
function toggleDone(id) {
tasks = tasks.map(t => t.id === id ? { ...t, done: !t.done } : t);
renderTasks();
}
function deleteTask(id) {
tasks = tasks.filter(t => t.id !== id);
renderTasks();
}
document.querySelector("#taskList").addEventListener("click", (e) => {
const id = Number(e.target.dataset.id);
if (e.target.matches(".toggle")) toggleDone(id);
if (e.target.matches(".delete")) deleteTask(id);
});
renderTasks() fonksiyonunuzda:
data-id="${task.id}" ekleyin..done sınıfı ekleyerek).Şu an yaptığınız liste can sıkıcı bir soruna sahip: sayfayı yenilerseniz (veya sekmeyi kapatırsanız) her şey kayboluyor.
Bunun nedeni görevlerin sadece JavaScript belleğinde olması. Sayfa yeniden yüklendiğinde o bellek sıfırlanır.
localStorage tarayıcıya gömülü. Bir anahtar altında metin saklayabildiğiniz küçük bir kutu gibi düşünün. Sunucuya veya hesaba gerek olmadığı için başlangıç projeleri için mükemmeldir.
Tüm görev listesini JSON metnine çevirip saklayacağız, sayfa açıldığında geri yüklenecek.
Her görev eklediğinizde, birini tamamladığınızda ya da sildiğinizde saveTasks() çağırın.
const STORAGE_KEY = "todo.tasks";
function saveTasks(tasks) {
localStorage.setItem(STORAGE_KEY, JSON.stringify(tasks));
}
Uygulamanız tasks dizisini güncellediği her yerde bunu hemen sonra yapın:
saveTasks(tasks);
renderTasks(tasks);
Sayfa yüklendiğinde kaydedilmiş değeri okuyun. Henüz kaydedilmiş bir şey yoksa boş bir liste kullanın.
function loadTasks() {
const saved = localStorage.getItem(STORAGE_KEY);
return saved ? JSON.parse(saved) : [];
}
let tasks = loadTasks();
renderTasks(tasks);
Bu kadar: uygulamanız artık yenilemeler arasında görevleri hatırlıyor.
İpucu: localStorage sadece metin saklar, bu yüzden JSON.stringify() dizinizi metne çevirir, JSON.parse() de geri diziye çevirir.
Test etmek sıkıcı gelebilir, ama küçük hataları bulup düzeltmek uygulamanızı “benim makinemde çalışıyor”dan “her durumda çalışıyor”a taşır. Her küçük değişiklikten sonra hızlı bir kontrol yapın.
Ana akışı bu sırayla çalıştırın:
Her adım başarısız olursa, yeni özellik eklemeden önce düzeltin. Küçük uygulamalarda sorunları üst üste koymak işleri karıştırır.
Uç durumlar, tasarlamadığınız ama gerçek insanların yapacağı girdilerdir:
Yaygın bir düzeltme boş görevleri engellemektir:
const text = input.value.trim();
addButton.disabled = text === "";
(Bunu her input olayında çalıştırabilir ve eklemeden hemen önce yine kontrol edebilirsiniz.)
Tıklamalar tepki vermiyorsa genelde şunlardan biridir:
id veya sınıf adı farklı)app.js bulunamadı)Rastgele görünen bir şey olursa, log atın:
console.log("Adding:", text);
console.log("Current tasks:", tasks);
Hata için tarayıcının Console'unu kontrol edin (kırmızı metin). Sorunu düzelttikten sonra bu logları kaldırın ki proje gereksiz çıktı üretmesin.
Bir yapılacaklar uygulaması, telefonlarda, klavyeyle ve ekran okuyucu gibi yardımcı araçlarla rahat kullanılmadan “tamamlanmış” sayılmaz.
Küçük ekranlarda küçük butonlar sinir bozucu olur. Tıklanabilir öğelere yeterli alan verin:
CSS kullanıyorsanız padding, font-size ve gap arttırmak en büyük farkı yaratır.
Ekran okuyucu kullananlar için kontrol isimleri net olmalı.
<label>ı olmalı (en iyi seçenek). Görsel olarak gizlemek isterseniz CSS ile gizleyin ama HTML'de bırakın.aria-label="Delete task" gibi bir etiket içermeli ki ekran okuyucu ne yaptığını söylesin.Bu, insanların her denetimin ne yaptığını tahmin etmek zorunda kalmadan anlamasına yardımcı olur.
Tüm uygulamayı fare olmadan kullanabilmelisiniz:
<form> kullanmak Enter'ı doğal hale getirir).Okunabilir bir font boyutu kullanın (16px iyi başlangıç) ve güçlü renk kontrastı (açık zemin üzerinde koyu metin veya tersine). Sadece renk kullanarak “tamamlandı”yı göstermeyin—çizgi üstü gibi açık bir stil ekleyin.
Her şey çalışınca 10–15 dakika ayırıp toparlayın. Bu, gelecekte düzeltmeyi kolaylaştırır ve projeye geri döndüğünüzde ne yaptığınızı anlamanıza yardımcı olur.
Küçük ve tahmin edilebilir tutun:
/index.html — sayfa yapısı (giriş, buton, liste)/styles.css — uygulamanın görünümü (boşluklar, fontlar, “tamamlandı” stili)/app.js — davranış (ekle, tamamla, sil, kaydet/yükle)/README.md — “gelecekteki siz” için kısa notlarAlt klasör tercih ediyorsanız şunu da kullanabilirsiniz:
/css/styles.css/js/app.jsSadece <link> ve <script> yollarınızın eşleştiğinden emin olun.
Kısa kazanımlar:
taskInput, taskList, saveTasks()Örneğin okunması kolay fonksiyonlar:
renderTasks(tasks)addTask(text)toggleTask(id)deleteTask(id)README.md basit olabilir:
index.htmli aç).En azından önemli bir kilometre taşından sonra klasörü zipleyin (ör. “localStorage çalışıyor”). Sürüm geçmişi istiyorsanız Git harika—ama zorunlu değil. Tek bir yedek bile kazara silinmelere karşı sizi kurtarır.
Yayınlamak, uygulamanızın dosyalarını internette herkesin açabileceği bir adrese koymaktır. Bu to‑do uygulaması “statik site” olduğu için (tarayıcıda çalışır, sunucuya gerek yok) ücretsiz olarak barındırılabilir.
Yüksek seviyede adımlar:
Uygulamanız ayrı dosyalar kullanıyorsa dosya isimlerinin linklerle tam eşleştiğini tekrar kontrol edin (ör. styles.css ile style.css kafa karıştırır).
En basit “yükle ve git” yaklaşımı için:
localStorage çalışıyor mu).Geçerse, linki bir arkadaşınıza gönderin ve denemesini isteyin—taze gözler hızla sorun yakalar.
Çalışan bir to‑do uygulaması yaptınız. Bir sonraki adım için büyük bir projeye atlamadan değer katan bu geliştirmeler hem faydalı hem de öğreticidir.
Her görevin yanında bir “Düzenle” butonu ekleyin. Tıklandığında görev etiketini küçük bir girişe (önceden doldurulmuş) ve “Kaydet” / “İptal” seçeneklerine dönüştürün.
İpucu: görev verinizi id ve text içeren nesneler halinde tutun. Düzenleme: doğru görevi id ile bulun, text güncelleyin, yeniden render ve kaydet.
En üstte üç buton ekleyin: Hepsi, Aktif, Tamamlandı.
Mevcut filtreyi currentFilter = 'all' gibi bir değişkende tutun. Render ederken gösterilecekler:
Ağırlaştırmadan ekleyin:
YYYY-MM-DD) ekleyin ve görev yanında gösterinTek bir ekstra alan bile veri modelinizi ve UI'yi birlikte güncelleme pratiği kazandırır.
Hazır olduğunuzda büyük fikir şudur: localStorage yerine görevleri bir API'ye (fetch()) gönderirsiniz. Sunucu veritabanında saklar, böylece görevler cihazlar arasında senkron olur.
Bu geçişi yeniden inşa etmeden denemek istiyorsanız, sohbet tabanlı bir prototipleme aracı olan Koder.ai size API endpoint'leri, veritabanı tabloları ve React/Go/PostgreSQL gibi projeleri hızla üretmede yardımcı olabilir.
Bir notlar uygulaması (arama dahil) veya alışkanlık takipçisi (günlük işaretlemeler) yapmayı deneyin. Aynı becerileri yeniden kullanır: liste render, düzenleme, kaydetme ve basit arayüz tasarımı.