Proje Detayları
Adım Adım Geliştirme
Bu bölümde, not alma uygulamasını adım adım nasıl geliştirebileceğinizi öğreneceksiniz. Her adımda, ilgili kod parçalarını ve açıklamalarını bulacaksınız.
Adım 1: Proje Yapısını Oluşturma
İlk olarak, projemiz için gerekli dosyaları oluşturalım:
index.html
- Ana HTML dosyasıstyle.css
- CSS stil dosyasıscript.js
- JavaScript kod dosyası
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Not Alma Uygulaması</title>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
</head>
<body>
<div class="notes-app">
<div class="notes-header">
<h2>Not Alma Uygulaması</h2>
</div>
<div class="notes-container">
<div class="notes-sidebar">
<div class="search-container">
<input type="text" class="search-input" placeholder="Notlarda ara..." id="searchInput">
</div>
<ul class="notes-list" id="notesList">
<!-- Not öğeleri buraya dinamik olarak eklenecek -->
</ul>
</div>
<div class="notes-editor">
<div class="editor-toolbar">
<div class="toolbar-left">
<button class="toolbar-btn" id="boldBtn"><i class="fas fa-bold"></i></button>
<button class="toolbar-btn" id="italicBtn"><i class="fas fa-italic"></i></button>
<button class="toolbar-btn" id="underlineBtn"><i class="fas fa-underline"></i></button>
<button class="toolbar-btn" id="listBtn"><i class="fas fa-list-ul"></i></button>
</div>
<div class="toolbar-right">
<button class="toolbar-btn" id="deleteNoteBtn"><i class="fas fa-trash-alt"></i></button>
</div>
</div>
<div class="editor-content">
<input type="text" class="note-title-input" id="noteTitleInput" placeholder="Not başlığı">
<textarea class="note-body-input" id="noteBodyInput" placeholder="Not içeriği..."></textarea>
</div>
</div>
</div>
<button class="add-note-btn" id="addNoteBtn"><i class="fas fa-plus"></i></button>
<!-- Silme Onay Modalı -->
<div class="delete-confirm-modal" id="deleteModal">
<div class="modal-content">
<div class="modal-title">Bu notu silmek istediğinizden emin misiniz?</div>
<div class="modal-buttons">
<button class="modal-btn cancel-btn" id="cancelDeleteBtn">İptal</button>
<button class="modal-btn delete-btn" id="confirmDeleteBtn">Sil</button>
</div>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
/* Genel Stiller */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f0f2f5;
color: #333;
line-height: 1.6;
padding: 20px;
}
/* Not Alma Uygulaması Stilleri */
.notes-app {
max-width: 1000px;
margin: 0 auto;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
overflow: hidden;
position: relative;
}
.notes-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px 20px;
background-color: #4caf50;
color: white;
}
.notes-header h2 {
margin: 0;
font-size: 1.5rem;
}
.notes-container {
display: flex;
min-height: 500px;
border-top: none;
}
.notes-sidebar {
width: 30%;
background-color: #f5f5f5;
border-right: 1px solid #ddd;
overflow-y: auto;
}
.notes-list {
list-style: none;
padding: 0;
margin: 0;
}
.note-item {
padding: 15px;
border-bottom: 1px solid #ddd;
cursor: pointer;
transition: background-color 0.2s;
}
.note-item:hover {
background-color: #eee;
}
.note-item.active {
background-color: #e3f2fd;
border-left: 4px solid #2196f3;
}
.note-title {
font-weight: bold;
margin-bottom: 5px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.note-preview {
color: #666;
font-size: 0.9rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.note-date {
font-size: 0.8rem;
color: #999;
margin-top: 5px;
}
.notes-editor {
width: 70%;
display: flex;
flex-direction: column;
}
.editor-toolbar {
padding: 10px;
background-color: #f9f9f9;
border-bottom: 1px solid #ddd;
display: flex;
justify-content: space-between;
}
.toolbar-left {
display: flex;
gap: 10px;
}
.toolbar-right {
display: flex;
gap: 10px;
}
.toolbar-btn {
background: none;
border: none;
padding: 5px 10px;
cursor: pointer;
border-radius: 3px;
transition: background-color 0.2s;
}
.toolbar-btn:hover {
background-color: #eee;
}
.toolbar-btn.active {
background-color: #e3f2fd;
color: #2196f3;
}
.editor-content {
flex: 1;
padding: 20px;
overflow-y: auto;
}
.note-title-input {
width: 100%;
padding: 10px;
font-size: 1.2rem;
border: 1px solid #ddd;
border-radius: 4px;
margin-bottom: 15px;
}
.note-body-input {
width: 100%;
height: calc(100% - 60px);
padding: 10px;
font-size: 1rem;
border: 1px solid #ddd;
border-radius: 4px;
resize: none;
font-family: inherit;
}
.add-note-btn {
position: absolute;
bottom: 20px;
right: 20px;
width: 50px;
height: 50px;
border-radius: 50%;
background-color: #4caf50;
color: white;
border: none;
font-size: 1.5rem;
cursor: pointer;
box-shadow: 0 3px 5px rgba(0,0,0,0.2);
transition: background-color 0.3s;
display: flex;
align-items: center;
justify-content: center;
}
.add-note-btn:hover {
background-color: #45a049;
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
color: #666;
padding: 20px;
text-align: center;
}
.empty-state i {
font-size: 3rem;
margin-bottom: 15px;
color: #ddd;
}
.empty-state p {
margin-bottom: 20px;
}
.empty-state button {
padding: 10px 15px;
background-color: #4caf50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s;
}
.empty-state button:hover {
background-color: #45a049;
}
.search-container {
padding: 10px;
border-bottom: 1px solid #ddd;
}
.search-input {
width: 100%;
padding: 8px 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 0.9rem;
}
.delete-confirm-modal {
display: none;
position: fixed;
z-index: 1000;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0,0,0,0.5);
}
.modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
max-width: 500px;
border-radius: 5px;
text-align: center;
}
.modal-title {
font-size: 1.2rem;
margin-bottom: 15px;
}
.modal-buttons {
display: flex;
justify-content: center;
gap: 10px;
margin-top: 20px;
}
.modal-btn {
padding: 8px 15px;
border: none;
border-radius: 4px;
cursor: pointer;
}
.cancel-btn {
background-color: #f5f5f5;
color: #333;
}
.delete-btn {
background-color: #f44336;
color: white;
}
/* Responsive Tasarım */
@media (max-width: 768px) {
.notes-container {
flex-direction: column;
}
.notes-sidebar, .notes-editor {
width: 100%;
}
.notes-sidebar {
border-right: none;
border-bottom: 1px solid #ddd;
max-height: 300px;
}
}
Adım 2: JavaScript Kodunu Yazma
Şimdi, uygulamanın işlevselliğini sağlayacak JavaScript kodunu yazalım:
// DOM elementlerini seçme
const notesList = document.getElementById('notesList');
const noteTitleInput = document.getElementById('noteTitleInput');
const noteBodyInput = document.getElementById('noteBodyInput');
const addNoteBtn = document.getElementById('addNoteBtn');
const deleteNoteBtn = document.getElementById('deleteNoteBtn');
const searchInput = document.getElementById('searchInput');
const deleteModal = document.getElementById('deleteModal');
const cancelDeleteBtn = document.getElementById('cancelDeleteBtn');
const confirmDeleteBtn = document.getElementById('confirmDeleteBtn');
const boldBtn = document.getElementById('boldBtn');
const italicBtn = document.getElementById('italicBtn');
const underlineBtn = document.getElementById('underlineBtn');
const listBtn = document.getElementById('listBtn');
// Not verilerini LocalStorage'dan al veya boş bir dizi oluştur
let notes = JSON.parse(localStorage.getItem('notes')) || [];
let activeNoteId = null;
// Sayfa yüklendiğinde
document.addEventListener('DOMContentLoaded', () => {
// Notları listele
renderNotes();
// Yeni not ekleme butonuna tıklama olayı
addNoteBtn.addEventListener('click', addNewNote);
// Not silme butonuna tıklama olayı
deleteNoteBtn.addEventListener('click', () => {
if (activeNoteId) {
openDeleteModal();
}
});
// Silme modalı iptal butonuna tıklama olayı
cancelDeleteBtn.addEventListener('click', closeDeleteModal);
// Silme modalı onay butonuna tıklama olayı
confirmDeleteBtn.addEventListener('click', () => {
deleteNote(activeNoteId);
closeDeleteModal();
});
// Not listesine tıklama olayı (event delegation)
notesList.addEventListener('click', (event) => {
const noteItem = event.target.closest('.note-item');
if (noteItem) {
const noteId = parseInt(noteItem.dataset.id);
setActiveNote(noteId);
}
});
// Not başlığı değişiklik olayı
noteTitleInput.addEventListener('input', saveActiveNote);
// Not içeriği değişiklik olayı
noteBodyInput.addEventListener('input', saveActiveNote);
// Arama olayı
searchInput.addEventListener('input', searchNotes);
// Biçimlendirme butonları olayları
boldBtn.addEventListener('click', () => formatText('bold'));
italicBtn.addEventListener('click', () => formatText('italic'));
underlineBtn.addEventListener('click', () => formatText('underline'));
listBtn.addEventListener('click', () => formatText('list'));
// İlk not varsa, onu aktif yap
if (notes.length > 0) {
setActiveNote(notes[0].id);
} else {
// Not yoksa, boş bir not oluştur
addNewNote();
}
});
// Notları listeleme fonksiyonu
function renderNotes(notesToRender = notes) {
notesList.innerHTML = ''; // Önceki notları temizle
if (notesToRender.length === 0) {
// Not yoksa, boş durum mesajı göster
notesList.innerHTML = `
Henüz not bulunmuyor.
`;
return;
}
// Notları tarihe göre sırala (en yeni en üstte)
notesToRender.sort((a, b) => b.updatedAt - a.updatedAt);
// Her not için bir liste öğesi oluştur
notesToRender.forEach(note => {
const noteItem = document.createElement('li');
noteItem.className = `note-item${note.id === activeNoteId ? ' active' : ''}`;
noteItem.dataset.id = note.id;
// Not içeriğinden önizleme oluştur (ilk 30 karakter)
const preview = note.body.substring(0, 30) + (note.body.length > 30 ? '...' : '');
// Tarih formatını oluştur
const date = new Date(note.updatedAt);
const formattedDate = `${date.toLocaleDateString('tr-TR', { day: 'numeric', month: 'long', year: 'numeric' })}, ${date.toLocaleTimeString('tr-TR', { hour: '2-digit', minute: '2-digit' })}`;
noteItem.innerHTML = `
${note.title || 'Başlıksız Not'}
${preview}
${formattedDate}
`;
notesList.appendChild(noteItem);
});
}
// Yeni not ekleme fonksiyonu
function addNewNote() {
// Yeni not nesnesi oluştur
const newNote = {
id: Date.now(), // Benzersiz ID için şu anki zaman damgasını kullan
title: '',
body: '',
createdAt: Date.now(),
updatedAt: Date.now()
};
// Notu diziye ekle
notes.unshift(newNote);
// Notları kaydet
saveNotes();
// Notları yeniden listele
renderNotes();
// Yeni notu aktif yap
setActiveNote(newNote.id);
}
// Aktif notu ayarlama fonksiyonu
function setActiveNote(noteId) {
// Aktif not ID'sini güncelle
activeNoteId = noteId;
// Aktif notu bul
const activeNote = notes.find(note => note.id === noteId);
if (activeNote) {
// Not başlığı ve içeriğini editöre yükle
noteTitleInput.value = activeNote.title;
noteBodyInput.value = activeNote.body;
// Tüm not öğelerinden 'active' sınıfını kaldır
document.querySelectorAll('.note-item').forEach(item => {
item.classList.remove('active');
});
// Aktif not öğesine 'active' sınıfını ekle
const activeNoteItem = document.querySelector(`.note-item[data-id="${noteId}"]`);
if (activeNoteItem) {
activeNoteItem.classList.add('active');
}
}
}
// Aktif notu kaydetme fonksiyonu
function saveActiveNote() {
if (!activeNoteId) return;
// Aktif notu bul
const noteIndex = notes.findIndex(note => note.id === activeNoteId);
if (noteIndex !== -1) {
// Not başlığı ve içeriğini güncelle
notes[noteIndex].title = noteTitleInput.value;
notes[noteIndex].body = noteBodyInput.value;
notes[noteIndex].updatedAt = Date.now();
// Notları kaydet
saveNotes();
// Notları yeniden listele
renderNotes();
}
}
// Not silme fonksiyonu
function deleteNote(noteId) {
// Notu diziden kaldır
notes = notes.filter(note => note.id !== noteId);
// Notları kaydet
saveNotes();
// Notları yeniden listele
renderNotes();
// Başka not varsa, ilk notu aktif yap
if (notes.length > 0) {
setActiveNote(notes[0].id);
} else {
// Not yoksa, editörü temizle
noteTitleInput.value = '';
noteBodyInput.value = '';
activeNoteId = null;
}
}
// Notları LocalStorage'a kaydetme fonksiyonu
function saveNotes() {
localStorage.setItem('notes', JSON.stringify(notes));
}
// Notlarda arama fonksiyonu
function searchNotes() {
const searchTerm = searchInput.value.toLowerCase();
if (searchTerm === '') {
// Arama terimi yoksa, tüm notları göster
renderNotes();
} else {
// Arama terimine göre notları filtrele
const filteredNotes = notes.filter(note => {
return (
note.title.toLowerCase().includes(searchTerm) ||
note.body.toLowerCase().includes(searchTerm)
);
});
// Filtrelenmiş notları göster
renderNotes(filteredNotes);
}
}
// Silme modalını açma fonksiyonu
function openDeleteModal() {
deleteModal.style.display = 'block';
}
// Silme modalını kapatma fonksiyonu
function closeDeleteModal() {
deleteModal.style.display = 'none';
}
// Metin biçimlendirme fonksiyonu
function formatText(format) {
// Seçili metni al
const textarea = noteBodyInput;
const start = textarea.selectionStart;
const end = textarea.selectionEnd;
const selectedText = textarea.value.substring(start, end);
let formattedText = '';
let cursorPosition = 0;
switch (format) {
case 'bold':
formattedText = `**${selectedText}**`;
cursorPosition = start + formattedText.length;
break;
case 'italic':
formattedText = `*${selectedText}*`;
cursorPosition = start + formattedText.length;
break;
case 'underline':
formattedText = `_${selectedText}_`;
cursorPosition = start + formattedText.length;
break;
case 'list':
// Seçili metin satırlarını al
const lines = selectedText.split('\n');
// Her satırın başına '- ' ekle
formattedText = lines.map(line => `- ${line}`).join('\n');
cursorPosition = start + formattedText.length;
break;
}
// Metni değiştir
textarea.value = textarea.value.substring(0, start) + formattedText + textarea.value.substring(end);
// İmleci uygun konuma getir
textarea.selectionStart = cursorPosition;
textarea.selectionEnd = cursorPosition;
// Textarea'ya odaklan
textarea.focus();
// Aktif notu kaydet
saveActiveNote();
}
Adım 3: Uygulamayı Test Etme
Şimdi uygulamanızı test etme zamanı! Aşağıdaki adımları izleyin:
- Tüm dosyaları (
index.html
,style.css
,script.js
) aynı klasöre kaydedin. - HTML dosyasını bir web tarayıcısında açın.
- Uygulama ilk açıldığında otomatik olarak boş bir not oluşturulacaktır.
- Not başlığı ve içeriğini düzenleyin.
- Yeni not ekleme butonuna tıklayarak başka notlar oluşturun.
- Notlar arasında geçiş yapın ve içeriklerini düzenleyin.
- Arama kutusunu kullanarak notlar arasında arama yapın.
- Biçimlendirme butonlarını kullanarak metni biçimlendirin.
- Silme butonunu kullanarak bir notu silin.
- Sayfayı yenileyin ve notların LocalStorage sayesinde korunduğunu doğrulayın.
İpucu: Tarayıcınızın geliştirici araçlarını (genellikle F12 tuşu ile açılır) kullanarak LocalStorage içeriğini inceleyebilir ve JavaScript hatalarını ayıklayabilirsiniz.
Projeyi Geliştirme
Temel not alma uygulamasını başarıyla oluşturduktan sonra, aşağıdaki özelliklerle projenizi geliştirebilirsiniz:
1. Markdown Desteği
Notları Markdown formatında yazabilme ve önizleme yapabilme özelliği ekleyin:
// HTML'e Markdown önizleme butonu ve alanı ekleyin
// <button class="toolbar-btn" id="previewBtn"><i class="fas fa-eye"></i></button>
// <div class="markdown-preview" id="markdownPreview"></div>
// Markdown önizleme butonunu seç
const previewBtn = document.getElementById('previewBtn');
const markdownPreview = document.getElementById('markdownPreview');
let isPreviewMode = false;
// Önizleme butonuna tıklama olayı
previewBtn.addEventListener('click', togglePreview);
// Önizleme modunu değiştirme fonksiyonu
function togglePreview() {
isPreviewMode = !isPreviewMode;
if (isPreviewMode) {
// Önizleme modunu etkinleştir
noteBodyInput.style.display = 'none';
markdownPreview.style.display = 'block';
previewBtn.classList.add('active');
// Markdown'ı HTML'e dönüştür
const markdown = noteBodyInput.value;
const html = convertMarkdownToHtml(markdown);
markdownPreview.innerHTML = html;
} else {
// Düzenleme modunu etkinleştir
noteBodyInput.style.display = 'block';
markdownPreview.style.display = 'none';
previewBtn.classList.remove('active');
}
}
// Markdown'ı HTML'e dönüştürme fonksiyonu
function convertMarkdownToHtml(markdown) {
// Basit bir Markdown dönüştürücü
// Gerçek bir uygulamada marked.js gibi bir kütüphane kullanabilirsiniz
let html = markdown;
// Başlıklar
html = html.replace(/^# (.*$)/gm, '<h1>$1</h1>');
html = html.replace(/^## (.*$)/gm, '<h2>$1</h2>');
html = html.replace(/^### (.*$)/gm, '<h3>$1</h3>');
// Kalın
html = html.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
// İtalik
html = html.replace(/\*(.*?)\*/g, '<em>$1</em>');
// Altı çizili
html = html.replace(/_(.*?)_/g, '<u>$1</u>');
// Listeler
html = html.replace(/^\- (.*$)/gm, '<li>$1</li>');
html = html.replace(/(<li>.*<\/li>)/gm, '<ul>$1</ul>');
// Satır sonları
html = html.replace(/\n/g, '<br>');
return html;
}
2. Kategori Sistemi
Notları kategorilere ayırabilme özelliği ekleyin:
// HTML'e kategori seçimi ekleyin
// <div class="category-selector">
// <select id="categorySelect">
// <option value="">Tüm Kategoriler</option>
// </select>
// <button id="addCategoryBtn"><i class="fas fa-plus"></i></button>
// </div>
// Kategori verilerini LocalStorage'dan al veya boş bir dizi oluştur
let categories = JSON.parse(localStorage.getItem('categories')) || [];
// DOM elementlerini seç
const categorySelect = document.getElementById('categorySelect');
const addCategoryBtn = document.getElementById('addCategoryBtn');
// Sayfa yüklendiğinde
document.addEventListener('DOMContentLoaded', () => {
// Kategorileri yükle
loadCategories();
// Kategori ekleme butonuna tıklama olayı
addCategoryBtn.addEventListener('click', addNewCategory);
// Kategori seçimi değişiklik olayı
categorySelect.addEventListener('change', filterNotesByCategory);
});
// Kategorileri yükleme fonksiyonu
function loadCategories() {
// Kategori seçimini temizle
categorySelect.innerHTML = '<option value="">Tüm Kategoriler</option>';
// Kategorileri ekle
categories.forEach(category => {
const option = document.createElement('option');
option.value = category.id;
option.textContent = category.name;
categorySelect.appendChild(option);
});
}
// Yeni kategori ekleme fonksiyonu
function addNewCategory() {
const categoryName = prompt('Yeni kategori adı:');
if (categoryName && categoryName.trim() !== '') {
// Yeni kategori nesnesi oluştur
const newCategory = {
id: Date.now(),
name: categoryName.trim()
};
// Kategoriyi diziye ekle
categories.push(newCategory);
// Kategorileri kaydet
saveCategories();
// Kategorileri yeniden yükle
loadCategories();
}
}
// Kategorileri LocalStorage'a kaydetme fonksiyonu
function saveCategories() {
localStorage.setItem('categories', JSON.stringify(categories));
}
// Kategoriye göre notları filtreleme fonksiyonu
function filterNotesByCategory() {
const selectedCategoryId = categorySelect.value;
if (selectedCategoryId === '') {
// Tüm kategoriler seçiliyse, tüm notları göster
renderNotes();
} else {
// Seçili kategoriye göre notları filtrele
const filteredNotes = notes.filter(note => note.categoryId === parseInt(selectedCategoryId));
// Filtrelenmiş notları göster
renderNotes(filteredNotes);
}
}
// Not nesnesine kategori alanı ekleyin
function addNewNote() {
const selectedCategoryId = categorySelect.value !== '' ? parseInt(categorySelect.value) : null;
// Yeni not nesnesi oluştur
const newNote = {
id: Date.now(),
title: '',
body: '',
categoryId: selectedCategoryId,
createdAt: Date.now(),
updatedAt: Date.now()
};
// ... diğer kodlar ...
}
3. Dışa/İçe Aktarma
Notları dışa aktarma ve içe aktarma özelliği ekleyin:
// HTML'e dışa/içe aktarma butonları ekleyin
// <button id="exportBtn">Dışa Aktar</button>
// <button id="importBtn">İçe Aktar</button>
// <input type="file" id="importFile" style="display: none;">
// DOM elementlerini seç
const exportBtn = document.getElementById('exportBtn');
const importBtn = document.getElementById('importBtn');
const importFile = document.getElementById('importFile');
// Sayfa yüklendiğinde
document.addEventListener('DOMContentLoaded', () => {
// Dışa aktarma butonuna tıklama olayı
exportBtn.addEventListener('click', exportNotes);
// İçe aktarma butonuna tıklama olayı
importBtn.addEventListener('click', () => {
importFile.click();
});
// Dosya seçimi değişiklik olayı
importFile.addEventListener('change', importNotes);
});
// Notları dışa aktarma fonksiyonu
function exportNotes() {
// Notları JSON formatına dönüştür
const notesData = JSON.stringify(notes, null, 2);
// Dosya adı oluştur
const fileName = `notes_${new Date().toISOString().slice(0, 10)}.json`;
// Dosya indirme bağlantısı oluştur
const blob = new Blob([notesData], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = fileName;
// Bağlantıya tıkla ve dosyayı indir
document.body.appendChild(a);
a.click();
// Bağlantıyı temizle
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
// Notları içe aktarma fonksiyonu
function importNotes(event) {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function(e) {
try {
// Dosya içeriğini JSON olarak ayrıştır
const importedNotes = JSON.parse(e.target.result);
// Geçerli bir notlar dizisi mi kontrol et
if (Array.isArray(importedNotes)) {
// Kullanıcıya onay sor
const confirmImport = confirm(`${importedNotes.length} not içe aktarılacak. Mevcut notlar korunacak. Devam etmek istiyor musunuz?`);
if (confirmImport) {
// İçe aktarılan notları mevcut notlara ekle
notes = [...notes, ...importedNotes];
// Notları kaydet
saveNotes();
// Notları yeniden listele
renderNotes();
// Kullanıcıya bilgi ver
alert(`${importedNotes.length} not başarıyla içe aktarıldı.`);
}
} else {
throw new Error('Geçersiz not formatı');
}
} catch (error) {
alert('Dosya içe aktarılamadı. Geçersiz format.');
console.error('İçe aktarma hatası:', error);
}
};
reader.readAsText(file);
}
// Dosya seçimini sıfırla
event.target.value = '';
}
Geliştirme Zorlukları
Not alma uygulamanızı daha da geliştirmek için aşağıdaki zorlukları deneyebilirsiniz:
- Zengin Metin Editörü: Tam özellikli bir zengin metin editörü ekleyin (örneğin, TinyMCE veya Quill.js kullanarak).
- Resim Ekleme: Notlara resim ekleyebilme özelliği ekleyin.
- Senkronizasyon: Notları bir bulut hizmetiyle senkronize etme özelliği ekleyin (örneğin, Firebase kullanarak).
- Paylaşım: Notları e-posta veya bağlantı olarak paylaşabilme özelliği ekleyin.
- Hatırlatıcılar: Notlara hatırlatıcı ekleyebilme ve bildirim alabilme özelliği ekleyin.
Sonuç ve Öğrenilen Dersler
Bu projede, JavaScript kullanarak bir not alma uygulaması geliştirdik. Bu süreçte şunları öğrendik:
- Notları oluşturma, düzenleme ve silme işlevselliği geliştirmeyi
- Notları LocalStorage kullanarak kalıcı hale getirmeyi
- Arama fonksiyonu ile notlar arasında filtreleme yapmayı
- Dinamik kullanıcı arayüzü oluşturmayı
- Tarih ve zaman işlemlerini JavaScript ile yönetmeyi
- Olay yetkilendirme (event delegation) tekniğini kullanmayı
- Responsive tasarım ilkelerini uygulamayı
Bu proje, modern web geliştirme becerilerinizi geliştirmenize ve gerçek dünya uygulamaları oluşturmanıza yardımcı olacak temel bilgileri sağlamıştır. Öğrendiğiniz teknikleri ve kavramları kullanarak, daha karmaşık ve tam özellikli not alma uygulamaları geliştirebilirsiniz.