Project: Image Changer with DOM and Events
Acest proiect folosește manipularea DOM și evenimentele pentru a schimba imaginea afișată când utilizatorul apasă pe un buton.
Schimbă imaginea
let imagineIndex = 1;
function schimbaImagine() {
imagineIndex = imagineIndex === 1 ? 2 : 1;
const img = document.getElementById("imagine");
img.src = `images/img${imagineIndex}.png`;
}
Project: Character Counter with Validation
Acest proiect folosește manipularea DOM și evenimentele pentru a număra caracterele introduse într-un câmp de text și pentru a valida dacă limita a fost depășită.
const textarea = document.getElementById("comentariu");
const contor = document.getElementById("contor");
const eroare = document.getElementById("eroare");
const limita = 100;
textarea.addEventListener("input", () => {
const lungime = textarea.value.length;
contor.textContent = `${lungime} / ${limita} caractere`;
if (lungime > limita) {
eroare.textContent = "Ai depășit limita de caractere!";
contor.style.color = "red";
} else {
eroare.textContent = "";
contor.style.color = "black";
}
});
function trimiteComentariu() {
const lungime = textarea.value.length;
if (lungime > limita) {
alert("Comentariul este prea lung!");
} else if (lungime === 0) {
alert("Comentariul nu poate fi gol!");
} else {
alert("Comentariul a fost trimis!");
textarea.value = "";
contor.textContent = `0 / ${limita} caractere`;
contor.style.color = "black";
}
}
Scrie un comentariu
0 / 100 caractere
Project: To-Do List App
Acest proiect creează o aplicație simplă de tip „to-do list” care permite utilizatorului să adauge, să bifeze și să șteargă sarcini.
Adaugă o sarcină
function adaugaTask() {
const input = document.getElementById("taskInput");
const valoare = input.value.trim();
if (valoare === "") {
alert("Introdu o sarcină!");
return;
}
const li = document.createElement("li");
li.textContent = valoare;
li.style.margin = "8px 0";
li.style.cursor = "pointer";
li.onclick = function () {
li.style.textDecoration = li.style.textDecoration === "line-through" ? "none" : "line-through";
li.style.color = li.style.textDecoration === "line-through" ? "gray" : "black";
};
const stergeBtn = document.createElement("button");
stergeBtn.textContent = "Șterge";
stergeBtn.style.marginLeft = "10px";
stergeBtn.style.padding = "4px 8px";
stergeBtn.onclick = function () {
li.remove();
};
li.appendChild(stergeBtn);
document.getElementById("taskList").appendChild(li);
input.value = "";
}
Project: Secret Message Encoder
Acest proiect folosește funcții JavaScript pentru a codifica și decodifica mesaje secrete folosind metode simple precum Base64.
Codifică un mesaj
Decodifică un mesaj
function codifica() {
const input = document.getElementById("mesajInput").value;
if (input.trim() === "") {
alert("Scrie un mesaj înainte de a-l codifica!");
return;
}
const codificat = btoa(input);
document.getElementById("mesajCodificat").textContent = `Codificat: ${codificat}`;
}
function decodifica() {
const input = document.getElementById("mesajCodificatInput").value;
try {
const decodificat = atob(input);
document.getElementById("mesajDecodificat").textContent = `Decodificat: ${decodificat}`;
} catch (e) {
alert("Mesajul introdus nu este valid Base64!");
}
}
Singleton Pattern
const Singleton = (function () {
let instance;
function createInstance() {
return { mesaj: "Aceasta este instanța unică." };
}
return {
getInstance: function () {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
const inst1 = Singleton.getInstance();
const inst2 = Singleton.getInstance();
console.log(inst1 === inst2);
Asigură că există o singură instanță a unui obiect și oferă un punct global de acces.
Factory Pattern
function AnimalFactory(tip) {
if (tip === "caine") {
return { sunet: () => "Ham!" };
} else if (tip === "pisica") {
return { sunet: () => "Miau!" };
}
return { sunet: () => "Necunoscut!" };
}
const animal = AnimalFactory("pisica");
console.log(animal.sunet());
Crează obiecte fără a specifica clasa exactă — util pentru instanțiere flexibilă.
Observer Pattern
class Subject {
constructor() {
this.observatori = [];
}
adauga(observer) {
this.observatori.push(observer);
}
notifica(mesaj) {
this.observatori.forEach(obs => obs.update(mesaj));
}
}
class Observer {
update(mesaj) {
console.log("Primit:", mesaj);
}
}
const subiect = new Subject();
const obs1 = new Observer();
subiect.adauga(obs1);
subiect.notifica("Salutare!");
Permite unui obiect să notifice alte obiecte când starea sa se schimbă.
Module Pattern and IIFE
Acest proiect demonstrează cum putem folosi o funcție imediat invocată (IIFE) pentru a crea un modul cu variabile private și metode publice.
Modulul Contor
const Contor = (function () {
let valoare = 0;
function actualizeazaAfisaj() {
document.getElementById("valoareContor").textContent = `Valoare: ${valoare}`;
}
return {
increment: function () {
valoare++;
actualizeazaAfisaj();
},
decrement: function () {
valoare--;
actualizeazaAfisaj();
}
};
})();
Valoare: 0
MVC Pattern Introduction
Acest proiect demonstrează principiul Model-View-Controller în JavaScript, o arhitectură care separă logica aplicației în trei componente distincte:
- Model - gestionează datele și logica aplicației.
- View - afișează datele către utilizator.
- Controller - intermediază între Model și View, răspunzând la acțiunile utilizatorului.
Contor cu arhitectură MVC
// 🔹 MODEL: gestionează datele
const Model = {
valoare: 0,
increment: function () {
this.valoare++;
},
decrement: function () {
this.valoare--;
},
getValoare: function () {
return this.valoare;
}
};
// 🔹 VIEW: afișează datele
const View = {
afiseaza: function (valoare) {
document.getElementById("view").textContent = `Valoare: ${valoare}`;
}
};
// 🔹 CONTROLLER: leagă acțiunile utilizatorului de model și view
const Controller = {
increment: function () {
Model.increment(); // modifică datele
View.afiseaza(Model.getValoare()); // actualizează interfața
},
decrement: function () {
Model.decrement();
View.afiseaza(Model.getValoare());
}
};
// 🔹 Inițializare: afișăm valoarea inițială
View.afiseaza(Model.getValoare());
Valoare: 0