|
|
7 months ago | |
|---|---|---|
| .. | ||
| README.md | 7 months ago | |
| assignment.md | 7 months ago | |
README.md
Proiectul Terariu Partea 3: Manipularea DOM și Închideri în JavaScript
journey
title Călătoria ta JavaScript DOM
section Bază
Understand DOM: 3: Student
Learn closures: 4: Student
Connect elements: 4: Student
section Interacțiune
Setup drag events: 4: Student
Track coordinates: 5: Student
Handle movement: 5: Student
section Finisare
Add cleanup: 4: Student
Test functionality: 5: Student
Complete terrarium: 5: Student
Sketchnote de Tomomi Imura
Bine ați venit la unul dintre cele mai atractive aspecte ale dezvoltării web - a face lucrurile interactive! Document Object Model (DOM) este ca un pod între HTML-ul tău și JavaScript, iar astăzi îl vom folosi pentru a da viață terariului tău. Când Tim Berners-Lee a creat primul browser web, și-a imaginat o web unde documentele pot fi dinamice și interactive - DOM face această viziune posibilă.
Vom explora, de asemenea, închiderile JavaScript, care la început pot părea intimidante. Gândește-te la închideri ca la crearea unor „buzunare de memorie” unde funcțiile tale pot reține informații importante. Este ca și cum fiecare plantă din terariul tău ar avea propriul său registru de date pentru a-și urmări poziția. Până la finalul acestei lecții, vei înțelege cât de naturale și utile sunt ele.
Iată ce construim: un terariu în care utilizatorii pot trage și plasa plante oriunde doresc. Vei învăța tehnicile de manipulare a DOM care stau la baza a tot, de la încărcarea fișierelor prin drag-and-drop până la jocuri interactive. Haide să dăm viață terariului tău.
mindmap
root((DOM & JavaScript))
DOM Tree
Selecția Elementelor
Accesul la Proprietăți
Gestionarea Evenimentelor
Actualizări Dinamice
Events
Evenimentele Pointer
Evenimentele Mouse-ului
Evenimentele Touch
Ascultători de Evenimente
Closures
Variabile Private
Domeniul Funcției
Persistența Memoriei
Gestionarea Stării
Drag & Drop
Urmărirea Poziției
Matematica Coordonatelor
Ciclu de Viață al Evenimentului
Interacțiunea Utilizatorului
Modern Patterns
Delegarea Evenimentelor
Performanță
Cross-Device
Accesibilitate
Test Prealabil Lecției
Înțelegerea DOM: Poarta ta către pagini web interactive
Document Object Model (DOM) este modul în care JavaScript comunică cu elementele tale HTML. Când browserul tău încarcă o pagină HTML, creează o reprezentare structurată a acelei pagini în memorie - asta este DOM-ul. Gândește-te la el ca la un arbore genealogic unde fiecare element HTML este un membru al familiei pe care JavaScript îl poate accesa, modifica sau rearanja.
Manipularea DOM transformă paginile statice în site-uri interactive. De fiecare dată când vezi un buton care își schimbă culoarea la trecerea mouse-ului, un conținut care se actualizează fără reîmprospătarea paginii, sau elemente pe care le poți trage în jur, asta este manipularea DOM în acțiune.
flowchart TD
A["Document"] --> B["HTML"]
B --> C["Antet"]
B --> D["Corp"]
C --> E["Titlu"]
C --> F["Meta Tag-uri"]
D --> G["H1: Terariul meu"]
D --> H["Div: Container Pagină"]
H --> I["Div: Container Stânga"]
H --> J["Div: Container Dreapta"]
H --> K["Div: Terariu"]
I --> L["Elemente Plante 1-7"]
J --> M["Elemente Plante 8-14"]
L --> N["img#plant1"]
L --> O["img#plant2"]
M --> P["img#plant8"]
M --> Q["img#plant9"]
style A fill:#e1f5fe
style B fill:#f3e5f5
style D fill:#e8f5e8
style H fill:#fff3e0
style N fill:#ffebee
style O fill:#ffebee
style P fill:#ffebee
style Q fill:#ffebee
O reprezentare a DOM și a marcajului HTML care îl referențiază. De la Olfa Nasraoui
Iată ce face DOM-ul puternic:
- Oferă o modalitate structurată de a accesa orice element de pe pagina ta
- Permite actualizări dinamice ale conținutului fără reîmprospătarea paginii
- Îngăduie răspuns în timp real la interacțiunile utilizatorilor ca clicurile și tragerea
- Creează fundamentul pentru aplicații web moderne și interactive
Închideri în JavaScript: Crearea de cod organizat și puternic
O închidere JavaScript este ca și cum ai da unei funcții propriul său spațiu de lucru privat cu memorie persistentă. Gândește-te cum finchii lui Darwin de pe Insulele Galápagos și-au dezvoltat fiecare ciocuri specializate în funcție de mediul lor specific - închiderile funcționează similar, creând funcții specializate care „își amintesc” contextul lor specific chiar și după ce funcția părinte s-a încheiat.
În terariul nostru, închiderile ajută fiecare plantă să-și amintească poziția în mod independent. Acest model apare frecvent în dezvoltarea profesională JavaScript, ceea ce îl face un concept valoros de înțeles.
flowchart LR
A["dragElement(plant1)"] --> B["Creează Closure"]
A2["dragElement(plant2)"] --> B2["Creează Closure"]
B --> C["Variabile Private"]
B2 --> C2["Variabile Private"]
C --> D["pos1, pos2, pos3, pos4"]
C --> E["funcția pointerDrag"]
C --> F["funcția elementDrag"]
C --> G["funcția stopElementDrag"]
C2 --> D2["pos1, pos2, pos3, pos4"]
C2 --> E2["funcția pointerDrag"]
C2 --> F2["funcția elementDrag"]
C2 --> G2["funcția stopElementDrag"]
H["Planta 1 își amintește poziția"] --> B
H2["Planta 2 își amintește poziția"] --> B2
style B fill:#e8f5e8
style B2 fill:#e8f5e8
style C fill:#fff3e0
style C2 fill:#fff3e0
💡 Înțelegerea închiderilor: Închiderile sunt un subiect important în JavaScript, iar mulți dezvoltatori le folosesc ani de zile înainte să înțeleagă pe deplin toate aspectele teoretice. Astăzi ne concentrăm pe aplicația practică - vei vedea cum închiderile apar natural pe măsură ce construim caracteristicile noastre interactive. Înțelegerea va crește pe măsură ce vezi cum rezolvă probleme reale.
O reprezentare a DOM și a marcajului HTML care îl referențiază. De la Olfa Nasraoui
În această lecție, vom finaliza proiectul nostru interactiv de terariu prin crearea codului JavaScript care va permite unui utilizator să manipuleze plantele de pe pagină.
Înainte să începem: Pregătirea pentru succes
Ai nevoie de fișierele tale HTML și CSS din lecțiile anterioare despre terariu - suntem pe cale să facem designul static interactiv. Dacă vii pentru prima dată, parcurgerea acelor lecții mai întâi îți va oferi un context important.
Iată ce vom construi:
- Tragere și plasare liniară pentru toate plantele din terariu
- Urmărirea coordonatelor astfel încât plantele să-și amintească pozițiile
- O interfață complet interactivă utilizând JavaScript simplu (vanilla)
- Cod curat și organizat folosind modele de închidere
Configurarea fișierului JavaScript
Hai să creăm fișierul JavaScript care va face terariul tău interactiv.
Pasul 1: Creează fișierul script
În folderul terariului tău, creează un fișier nou numit script.js.
Pasul 2: Leagă JavaScript-ul de HTML-ul tău
Adaugă acest tag script în secțiunea <head> a fișierului index.html:
<script src="./script.js" defer></script>
De ce este important atributul defer:
- Asigură că JavaScript-ul tău așteaptă până când tot HTML-ul este încărcat
- Previne erorile când JavaScript caută elemente care încă nu sunt gata
- Garantează că toate elementele tale de plante sunt disponibile pentru interacțiune
- Oferă performanțe mai bune decât plasarea scripturilor la finalul paginii
⚠️ Notă importantă: Atributul
deferprevine probleme comune de sincronizare. Fără el, JavaScript-ul poate încerca să acceseze elemente HTML înainte să fie încărcate, cauzând erori.
Conectarea JavaScript la elementele tale HTML
Înainte să putem face elementele de tras, JavaScript trebuie să le localizeze în DOM. Gândește-te la asta ca la un sistem de catalogare a unei biblioteci - odată ce ai numărul de catalog, poți găsi exact cartea de care ai nevoie și accesa tot conținutul ei.
Vom folosi metoda document.getElementById() pentru a face aceste conexiuni. Este ca un sistem precis de arhivare - dai un ID și el găsește exact elementul de care ai nevoie în HTML-ul tău.
Activarea funcționalității de tragere pentru toate plantele
Adaugă acest cod în fișierul tău script.js:
// Activează funcționalitatea de drag pentru toate cele 14 plante
dragElement(document.getElementById('plant1'));
dragElement(document.getElementById('plant2'));
dragElement(document.getElementById('plant3'));
dragElement(document.getElementById('plant4'));
dragElement(document.getElementById('plant5'));
dragElement(document.getElementById('plant6'));
dragElement(document.getElementById('plant7'));
dragElement(document.getElementById('plant8'));
dragElement(document.getElementById('plant9'));
dragElement(document.getElementById('plant10'));
dragElement(document.getElementById('plant11'));
dragElement(document.getElementById('plant12'));
dragElement(document.getElementById('plant13'));
dragElement(document.getElementById('plant14'));
Iată ce face acest cod:
- Localizează fiecare element plantă în DOM folosind ID-ul său unic
- Recuperează o referință JavaScript către fiecare element HTML
- Trimite fiecare element către o funcție
dragElement(pe care o vom crea în continuare) - Pregătește fiecare plantă pentru interacțiunea de tragere și plasare
- Leagă structura ta HTML de funcționalitatea JavaScript
🎯 De ce folosim ID-uri în loc de clase? ID-urile oferă identificatori unici pentru elementele specifice, în timp ce clasele CSS sunt gândite pentru a stiliza grupuri de elemente. Când JavaScript trebuie să manipuleze elemente individuale, ID-urile oferă precizia și performanța de care avem nevoie.
💡 Sfat profesionist: Observă cum apelăm
dragElement()pentru fiecare plantă în parte. Această abordare asigură ca fiecare plantă să aibă comportamentul de tragere independent, esențial pentru o interacțiune lină cu utilizatorul.
🔄 Verificare pedagogică
Înțelegerea conexiunii DOM: Înainte de a trece la funcționalitatea de tragere, verifică dacă poți:
- ✅ Explica cum localizează
document.getElementById()elementele HTML - ✅ Înțelege de ce folosim ID-uri unice pentru fiecare plantă
- ✅ Descrie scopul atributului
deferîn tagurile script - ✅ Recunoaște cum se conectează JavaScript-ul și HTML-ul prin DOM
Test rapid: Ce s-ar întâmpla dacă două elemente ar avea același ID? De ce getElementById() returnează doar un element?
Răspuns: ID-urile trebuie să fie unice; dacă sunt duplicate, este returnat doar primul element
Construirea închiderii dragElement
Acum vom crea inima funcționalității noastre de tragere: o închidere care gestionează comportamentul de tras pentru fiecare plantă. Această închidere va conține mai multe funcții interne care lucrează împreună pentru a urmări mișcările mouse-ului și a actualiza pozițiile elementelor.
Închiderile sunt perfecte pentru această sarcină deoarece ne permit să creăm variabile „private” care persistă între apelurile funcțiilor, oferind fiecărei plante propriul sistem independent de urmărire a coordonatelor.
Înțelegerea închiderilor printr-un exemplu simplu
Hai să demonstrăm închiderile cu un exemplu simplu care ilustrează conceptul:
function createCounter() {
let count = 0; // Acesta este ca o variabilă privată
function increment() {
count++; // Funcția internă își amintește variabila exterioară
return count;
}
return increment; // Returnăm funcția internă
}
const myCounter = createCounter();
console.log(myCounter()); // 1
console.log(myCounter()); // 2
Ce se întâmplă în acest model de închidere:
- Creează o variabilă privată
countcare există doar în cadrul acestei închideri - Funcția internă poate accesa și modifica acea variabilă externă (mecanismul închiderii)
- Când returnăm funcția internă, ea își păstrează conexiunea cu acele date private
- Chiar și după ce
createCounter()se termină,countpersistă și își amintește valoarea
De ce închiderile sunt perfecte pentru funcționalitatea de tragere
Pentru terariul nostru, fiecare plantă trebuie să-și amintească coordonatele poziției curente. Închiderile oferă soluția perfectă:
Beneficiile cheie pentru proiectul nostru:
- Menține variabile private de poziție pentru fiecare plantă în mod independent
- Păstrează datele coordonatelor între evenimentele de tragere
- Previne conflictele de variabile între elemente diferite tragabile
- Creează un cod curat și organizat
🎯 Obiectiv de învățare: Nu trebuie să stăpânești fiecare detaliu al închiderilor acum. Concentrează-te pe a vedea cum ne ajută să organizăm codul și să menținem starea pentru funcționalitatea de tragere.
stateDiagram-v2
[*] --> Ready: Încărcarea paginii
Ready --> DragStart: Utilizator apasă jos (pointerdown)
DragStart --> Dragging: Mișcare mouse/deget (pointermove)
Dragging --> Dragging: Continuă mișcarea
Dragging --> DragEnd: Utilizator eliberează (pointerup)
DragEnd --> Ready: Resetare pentru următoarea tragere
state DragStart {
[*] --> CapturePosition
CapturePosition --> SetupListeners
SetupListeners --> [*]
}
state Dragging {
[*] --> CalculateMovement
CalculateMovement --> UpdatePosition
UpdatePosition --> [*]
}
state DragEnd {
[*] --> RemoveListeners
RemoveListeners --> CleanupState
CleanupState --> [*]
}
Crearea funcției dragElement
Acum să construim funcția principală care va gestiona întreaga logică de tragere. Adaugă această funcție sub declarațiile elementelor plantelor:
function dragElement(terrariumElement) {
// Inițializează variabilele de urmărire a poziției
let pos1 = 0, // Poziția anterioară a mouse-ului pe axa X
pos2 = 0, // Poziția anterioară a mouse-ului pe axa Y
pos3 = 0, // Poziția curentă a mouse-ului pe axa X
pos4 = 0; // Poziția curentă a mouse-ului pe axa Y
// Configurează ascultătorul de evenimente de drag inițial
terrariumElement.onpointerdown = pointerDrag;
}
Înțelegerea sistemului de urmărire a poziției:
pos1șipos2: Stochează diferența dintre pozițiile vechi și noi ale mouse-uluipos3șipos4: Urmăresc coordonatele curente ale mouse-uluiterrariumElement: Elementul specific al plantei pe care îl facem tragabilonpointerdown: Evenimentul care declanșează când utilizatorul începe să tragă
Cum funcționează tiparul închiderii:
- Creează variabile private de poziție pentru fiecare element plantă
- Menține aceste variabile pe tot parcursul ciclului de viață al tragerii
- Asigură că fiecare plantă își urmărește coordonatele independent
- Oferă o interfață curată prin funcția
dragElement
De ce folosim evenimentele pointer?
Te-ai putea întreba de ce folosim onpointerdown în loc de mai familiarul onclick. Iată raționamentul:
| Tip Eveniment | Cel Mai Potrivit Pentru | Partea Negativă |
|---|---|---|
onclick |
Clicuri simple pe butoane | Nu poate gestiona tragerea (doar clicuri și eliberări) |
onpointerdown |
Mouse și touch | Nou, dar bine suportat în zilele noastre |
onmousedown |
Doar mouse desktop | Exclude utilizatorii de pe mobil |
De ce evenimentele pointer sunt perfecte pentru ce construim:
- Funcționează bine indiferent dacă cineva folosește mouse, deget sau chiar un stylus
- Se simte la fel pe laptop, tabletă sau telefon mobil
- Gestionează mișcarea efectivă de tragere (nu doar clic și gata)
- Creează o experiență lină pe care utilizatorii o așteaptă de la aplicațiile web moderne
💡 Pregătire pentru viitor: Evenimentele pointer sunt modul modern de a gestiona interacțiunile utilizatorilor. În loc să scrii cod separat pentru mouse și touch, le obții pe ambele gratuit. Destul de tare, nu?
🔄 Verificare pedagogică
Înțelegerea gestionării evenimentelor: Fă o pauză să confirmi dacă ai înțeles:
- ✅ De ce folosim evenimente pointer în loc de evenimente mouse?
- ✅ Cum persistă variabilele închiderii între apelurile funcțiilor?
- ✅ Ce rol joacă
preventDefault()pentru tragerea lină? - ✅ De ce atașăm ascultători la document în loc de elemente individuale?
Conexiune cu lumea reală: Gândește-te la interfețele drag-and-drop pe care le folosești zilnic:
- Încărcări fișiere: Tragerea fișierelor într-o fereastră de browser
- Table Kanban: Mutarea sarcinilor între coloane
- Galerii foto: Reordonarea pozelor
- Interfețe mobile: Glisarea și tragerea pe ecranele tactile
Funcția pointerDrag: Capturarea începerii unei trageri
Când un utilizator apasă pe o plantă (fie cu clic de mouse sau atingere cu degetul), funcția pointerDrag intră în acțiune. Această funcție capturează coordonatele inițiale și configurează sistemul de tras.
Adaugă această funcție în interiorul închiderii dragElement, imediat după linia terrariumElement.onpointerdown = pointerDrag;:
function pointerDrag(e) {
// Previne comportamentul implicit al browserului (precum selecția textului)
e.preventDefault();
// Capturează poziția inițială a mouse-ului/touch-ului
pos3 = e.clientX; // Coordonata X unde a început tragerea
pos4 = e.clientY; // Coordonata Y unde a început tragerea
// Configurează ascultători de evenimente pentru procesul de tragere
document.onpointermove = elementDrag;
document.onpointerup = stopElementDrag;
}
Pas cu pas, ce se întâmplă aici:
- Previne comportamentele implicite ale browserului care s-ar putea interfera cu tragerea
- Înregistrează coordonatele exacte unde utilizatorul a început gestul de tragere
- Stabilește ascultători de evenimente pentru mișcarea continuă a tragerii
- Pregătește sistemul pentru a urmări mișcarea mouse-ului/degetului peste întreg documentul
Înțelegerea prevenirii evenimentelor
Linia e.preventDefault() este crucială pentru o tragere lină:
Fără prevenire, browserele ar putea:
- Selecta textul când se trage peste pagină
- Declanșa meniuri contextuale la tragere cu clic dreapta
- Interfera cu comportamentul personalizat de tragere
- Crea artefacte vizuale în timpul operației de tragere
🔍 Experiment: După ce termini această lecție, încearcă să elimini
e.preventDefault()și vezi cum afectează experiența de tragere. Vei înțelege rapid de ce această linie este esențială!
Sistemul de urmărire a coordonatelor
Proprietățile e.clientX și e.clientY ne oferă coordonatele precise ale mouse-ului/atingerii:
| Proprietate | Ce măsoară | Utilizare |
|---|---|---|
clientX |
Poziția orizontală relativă la fereastra vizuală | Urmărirea mișcării stânga-dreapta |
clientY |
Poziția verticală relativă la fereastra vizuală | Urmărirea mișcării sus-jos |
| Înțelegerea acestor coordonate: |
- Oferă informații de poziționare pixel-perfect
- Se actualizează în timp real pe măsură ce utilizatorul își mișcă cursorul
- Rămâne consecvent pe diferite dimensiuni de ecran și niveluri de zoom
- Permite interacțiuni de drag lineare și responsive
Configurarea ascultătorilor de evenimente la nivel de document
Observă cum atașăm evenimentele de mișcare și oprire întregului document, nu doar elementului plantei:
document.onpointermove = elementDrag;
document.onpointerup = stopElementDrag;
De ce facem atașarea la document:
- Continuă urmărirea chiar și când mouse-ul părăsește elementul plantei
- Previne întreruperea tragerii dacă utilizatorul se mișcă rapid
- Oferă o tragere fluidă pe întreg ecranul
- Gestionează cazurile speciale în care cursorul iese în afara ferestrei browserului
⚡ Notă despre performanță: Vom curăța acești ascultători la nivel de document când tragerea se oprește pentru a evita scurgerile de memorie și probleme de performanță.
Completarea sistemului de tragere: Mișcare și curățare
Acum vom adăuga cele două funcții rămase care se ocupă de mișcarea efectivă a tragerii și de curățarea când tragerea încetează. Aceste funcții lucrează împreună pentru a crea o mișcare fluidă și responsive a plantei prin terrariul tău.
Funcția elementDrag: Urmărirea mișcării
Adaugă funcția elementDrag imediat după acolada de închidere a funcției pointerDrag:
function elementDrag(e) {
// Calculează distanța parcursă de la ultimul eveniment
pos1 = pos3 - e.clientX; // Distanța orizontală parcursă
pos2 = pos4 - e.clientY; // Distanța verticală parcurse
// Actualizează urmărirea poziției curente
pos3 = e.clientX; // Noua poziție curentă pe axa X
pos4 = e.clientY; // Noua poziție curentă pe axa Y
// Aplică mișcarea la poziția elementului
terrariumElement.style.top = (terrariumElement.offsetTop - pos2) + 'px';
terrariumElement.style.left = (terrariumElement.offsetLeft - pos1) + 'px';
}
Înțelegerea matematicii coordonatelor:
pos1șipos2: Calculează cât de mult s-a mișcat mouse-ul de la ultima actualizarepos3șipos4: Stochează poziția curentă a mouse-ului pentru următorul calculoffsetTopșioffsetLeft: Obțin poziția curentă a elementului în pagină- Logica scăderii: Mută elementul cu aceeași distanță cu care s-a mișcat mouse-ul
sequenceDiagram
participant User
participant Mouse
participant JavaScript
participant Plant
User->>Mouse: Începe tragerea la (100, 50)
Mouse->>JavaScript: eveniment pointerdown
JavaScript->>JavaScript: Stochează poziția inițială (pos3=100, pos4=50)
JavaScript->>JavaScript: Configurează ascultători pentru mutare/eliberează
User->>Mouse: Mută la (110, 60)
Mouse->>JavaScript: eveniment pointermove
JavaScript->>JavaScript: Calculează: pos1=10, pos2=10
JavaScript->>Plant: Actualizează: left += 10px, top += 10px
Plant->>Plant: Redă în noua poziție
User->>Mouse: Eliberează la (120, 65)
Mouse->>JavaScript: eveniment pointerup
JavaScript->>JavaScript: Elimină ascultătorii
JavaScript->>JavaScript: Resetează pentru următoarea tragere
Iată o defalcare a calculelor de mișcare:
- Măsoară diferența între vechile și noile poziții ale mouse-ului
- Calculează cât trebuie mutat elementul pe baza mișcării mouse-ului
- Actualizează proprietățile CSS de poziționare ale elementului în timp real
- Stochează noua poziție ca referință pentru următorul calcul de mișcare
Reprezentare vizuală a matematicii
sequenceDiagram
participant Mouse
participant JavaScript
participant Plant
Mouse->>JavaScript: Mută de la (100,50) la (110,60)
JavaScript->>JavaScript: Calculează: mutat 10px la dreapta, 10px în jos
JavaScript->>Plant: Actualizează poziția cu +10px la dreapta, +10px în jos
Plant->>Plant: Redă la noua poziție
Funcția stopElementDrag: Curățarea
Adaugă funcția de curățare după acolada de închidere a funcției elementDrag:
function stopElementDrag() {
// Elimină ascultătorii de evenimente la nivel de document
document.onpointerup = null;
document.onpointermove = null;
}
De ce este esențială curățarea:
- Previne scurgerile de memorie cauzate de ascultătorii de evenimente rămași
- Oprește comportamentul de tragere când utilizatorul eliberează planta
- Permite altor elemente să fie trase independent
- Resetează sistemul pentru următoarea operațiune de tragere
Ce se întâmplă fără curățare:
- Ascultătorii de evenimente continuă să ruleze după ce tragerea se oprește
- Performanța degradează pe măsură ce ascultătorii nefolosiți se acumulează
- Comportament neașteptat la interacțiunea cu alte elemente
- Resursele browserului sunt risipite pe gestionarea evenimentelor inutile
Înțelegerea proprietăților CSS de poziționare
Sistemul nostru de tragere manipulează două proprietăți CSS cheie:
| Proprietate | La ce controlează | Cum o folosim |
|---|---|---|
top |
Distanță față de marginea de sus | Poziționare verticală în timpul tragerii |
left |
Distanță față de marginea din stânga | Poziționare orizontală în timpul tragerii |
Informații cheie despre proprietățile offset:
offsetTop: Distanța curentă față de partea de sus a elementului părinte poziționatoffsetLeft: Distanța curentă față de partea stângă a elementului părinte poziționat- Contextul poziționării: Aceste valori sunt relative la cel mai apropiat strămoș poziționat
- Actualizări în timp real: Se schimbă imediat ce modificăm proprietățile CSS
🎯 Filosofia designului: Acest sistem de tragere este intenționat flexibil – nu există „zone de plasare” sau restricții. Utilizatorii pot așeza plante oriunde, având control creativ complet asupra designului terariului.
Punând totul cap la cap: Sistemul tău complet de tragere
Felicitări! Tocmai ai construit un sistem sofisticat de drag-and-drop folosind JavaScript simplu. Funcția ta completă dragElement conține acum un closure puternic care gestionează:
Ce realizează closure-ul tău:
- Menține variabile private de poziție pentru fiecare plantă independent
- Gestionează întreg ciclul de viață al tragerii de la început la sfârșit
- Oferă o mișcare fluidă și responsive pe întreg ecranul
- Curăță resursele corespunzător pentru a preveni scurgeri de memorie
- Creează o interfață intuitivă și creativă pentru designul terariului
Testarea terariului tău interactiv
Acum testează-ți terariul interactiv! Deschide fișierul index.html într-un browser web și încearcă funcționalitățile:
- Fă click și ține apăsat pe orice plantă pentru a începe tragerea
- Mişcă mouse-ul sau degetul și urmărește cum planta urmează fluid mișcarea
- Eliberează pentru a plasa planta în noua poziție
- Experimentează cu diferite aranjamente pentru a explora interfața
🥇 Realizare: Ai creat o aplicație web complet interactivă folosind concepte de bază pe care dezvoltatorii profesioniști le folosesc zilnic. Funcționalitatea de drag-and-drop utilizează aceleași principii din spatele upload-urilor de fișiere, tablourilor kanban și multor alte interfețe interactive.
🔄 Verificare pedagogică
Înțelegerea completă a sistemului: Verifică-ți stăpânirea asupra întregului sistem de tragere:
- ✅ Cum mențin closure-urile un stat independent pentru fiecare plantă?
- ✅ De ce este necesar calculul matematic al coordonatelor pentru o mișcare fluidă?
- ✅ Ce se întâmplă dacă uităm să curățăm ascultătorii de evenimente?
- ✅ Cum se poate scala acest model pentru interacțiuni mai complexe?
Reflecție asupra calității codului: Revizuiește soluția ta completă:
- Design modular: Fiecare plantă are propria instanță de closure
- Eficiență a evenimentelor: Configurare și curățare corectă a ascultătorilor
- Suport cross-device: Funcționează pe desktop și pe mobil
- Conștientizare a performanței: Fără scurgeri de memorie sau calcule redundante
Provocarea GitHub Copilot Agent 🚀
Folosește modul Agent pentru a completa următoarea provocare:
Descriere: Extinde proiectul terrariului adăugând o funcție de resetare care readuce toate plantele la pozițiile lor inițiale cu animații line.
Prompt: Creează un buton de reset care, la clic, animează toate plantele înapoi la pozițiile lor inițiale din bara laterală folosind tranziții CSS. Funcția ar trebui să stocheze pozițiile inițiale când se încarcă pagina și să tranziționeze lin plantele înapoi la acele poziții în decurs de 1 secundă când butonul de reset este apăsat.
Află mai multe despre modul agent aici.
🚀 Provocare suplimentară: Extinde-ți abilitățile
Ești gata să duci terrariul tău la un nou nivel? Încearcă să implementezi aceste îmbunătățiri:
Extensii creative:
- Dublu click pe o plantă pentru a o aduce în față (manipulare z-index)
- Adaugă feedback vizual precum o strălucire subtilă când plasezi cursorul peste plante
- Implementează limite pentru a preveni tragerea plantelor în afara terariului
- Creează o funcție de salvare care reține pozițiile plantelor folosind localStorage
- Adaugă efecte sonore pentru ridicarea și plasarea plantelor
💡 Oportunitate de învățare: Fiecare dintre aceste provocări te va învăța noi aspecte ale manipulării DOM, gestionării evenimentelor și designului experienței utilizatorului.
Test post-lectură
Recapitulare & Studiu individual: Adâncirea înțelegerii
Ai stăpânit fundamentele manipulării DOM și closures, dar întotdeauna există mai mult de explorat! Iată câteva căi pentru a-ți extinde cunoștințele și abilitățile.
Alternative pentru Drag and Drop
Am folosit evenimentele pointer pentru flexibilitate maximă, dar web development oferă multiple abordări:
| Abordare | Potrivit pentru | Valoare educațională |
|---|---|---|
| API-ul HTML Drag and Drop | Upload-uri de fișiere, zone formale de drag | Înțelegerea capacităților native ale browserului |
| Evenimente Touch | Interacțiuni specifice pe mobil | Modele de dezvoltare mobile-first |
Proprietăți CSS transform |
Animații fluide | Tehnici de optimizare a performanței |
Subiecte avansate de manipulare DOM
Pașii următori în călătoria ta de învățare:
- Delegare de evenimente: Gestionarea eficientă a evenimentelor pentru multiple elemente
- Intersection Observer: Detectarea când elementele intră sau ies din viewport
- Mutation Observer: Monitorizarea schimbărilor în structura DOM
- Componente Web: Crearea de elemente UI reutilizabile și încapsulate
- Concepte Virtual DOM: Înțelegerea modului în care framework-urile optimizează actualizările DOM
Resurse esențiale pentru învățare continuă
Documentație tehnică:
- Ghid MDN pentru Pointer Events - Referință completă pentru pointer events
- Specificația W3C pentru Pointer Events - Documentație oficială a standardelor
- Înțelegere profundă a closure-urilor JavaScript - Modele avansate de closure
Compatibilitatea browserelor:
- CanIUse.com - Verifică suportul caracteristicilor în browsere
- Date de compatibilitate MDN Browser - Informații detaliate despre compatibilitate
Oportunități practice:
- Construiește un joc puzzle folosind mecanisme similare de tragere
- Creează un panou kanban cu gestionare drag-and-drop a sarcinilor
- Design o galerie foto cu aranjamente dragabile
- Experimentează gesturile touch pentru interfețele mobile
🎯 Strategie de învățare: Cea mai bună metodă de a fixa aceste concepte este prin practică. Încearcă să construiești variații de interfețe dragabile – fiecare proiect îți va arăta ceva nou despre interacțiunea utilizatorului și manipularea DOM.
⚡ Ce poți face în următoarele 5 minute
- Deschide DevTools în browser și tastează
document.querySelector('body')în consolă - Încearcă să schimbi textul unei pagini folosind
innerHTMLsautextContent - Adaugă un ascultător pentru evenimentul click pe orice buton sau link de pe o pagină web
- Inspectează structura DOM folosind panoul Elements
🎯 Ce poți realiza în această oră
- Completează quiz-ul post-lectură și recapitulează conceptele manipulării DOM
- Creează o pagină web interactivă care răspunde la click-uri
- Exersează gestionarea evenimentelor cu tipuri diferite (click, mouseover, keypress)
- Construiește o listă simplă de sarcini sau un contor folosind manipularea DOM
- Explorează relația dintre elementele HTML și obiectele JavaScript
📅 Călătoria ta JavaScript săptămânală
- Completează proiectul terrarium interactiv cu funcționalitate drag-and-drop
- Stăpânește delegarea evenimentelor pentru o gestionare eficientă
- Învață despre event loop și JavaScript asincron
- Exersează closures construind module cu stare privată
- Explorează API-uri moderne DOM precum Intersection Observer
- Construiește componente interactive fără a utiliza framework-uri
🌟 Maestria ta JavaScript lunară
- Creează o aplicație complexă SPA folosind JavaScript pur
- Învață un framework modern (React, Vue, sau Angular) și compară-l cu manipularea DOM vanilla
- Contribuie la proiecte open source JavaScript
- Stăpânește concepte avansate precum web components și elemente customizate
- Construiește aplicații web performante cu modele DOM optime
- Predă altora despre manipularea DOM și fundamentele JavaScript
🎯 Cronologia ta pentru stăpânirea DOM în JavaScript
timeline
title Progresul în Învățarea DOM & JavaScript
section Fundament (15 minute)
Înțelegerea DOM: Metode de selecție a elementelor
: Navigarea structurii arbore
: Modele de accesare a proprietăților
section Manipularea Evenimentelor (20 minute)
Interacțiunea Utilizatorului: Bazele evenimentelor pointer
: Configurarea ascultătorilor de evenimente
: Compatibilitate între dispozitive
: Tehnici de prevenire a evenimentelor
section Închideri (25 minute)
Gestionarea Domeniului: Crearea variabilelor private
: Persistența funcțiilor
: Modele de gestionare a stării
: Eficiența memoriei
section Sistemul de Drag (30 minute)
Funcționalități Interactive: Urmărirea coordonatelor
: Calculul poziției
: Matematica mișcării
: Proceduri de curățare
section Modele Avansate (45 minute)
Abilități Profesionale: Delegarea evenimentelor
: Optimizarea performanței
: Tratarea erorilor
: Considerații de accesibilitate
section Înțelegerea Framework-ului (1 săptămână)
Dezvoltare Modernă: Concepte Virtual DOM
: Biblioteci de gestionare a stării
: Arhitecturi de componente
: Integrarea uneltelor de build
section Nivel Expert (1 lună)
API-uri Avansate DOM: Intersection Observer
: Mutation Observer
: Elemente Personalizate
: Componente Web
🛠️ Rezumatul trusei tale de instrumente JavaScript
După completarea acestei lecții, ai acum:
- Stăpânire DOM: Selecția elementelor, manipularea proprietăților și navigarea în arbore
- Experiență cu evenimente: Gestionarea interacțiunilor cross-device folosind pointer events
- Înțelegere a closure-urilor: Administrarea stării private și persistența funcțiilor
- Sisteme interactive: Implementarea completă a drag-and-drop de la zero
- Conștientizare a performanței: Curățare corectă a evenimentelor și managementul memoriei
- Modele moderne: Tehnici de organizare a codului folosite în dezvoltarea profesională
- Experiență utilizator: Crearea de interfețe intuitive și responsive
Abilități profesionale dobândite: Ai construit funcționalități folosind aceleași tehnici ca:
- Trello/tablouri Kanban: Tragerea cardurilor între coloane
- Sisteme de upload fișiere: Manipulare drag-and-drop a fișierelor
- Galerii foto: Interfețe de aranjare a fotografiilor
- Aplicații mobile: Modele de interacțiune bazate pe touch
Nivel următor: Ești pregătit să explorezi framework-uri moderne precum React, Vue sau Angular care se bazează pe aceste concepte fundamentale de manipulare DOM!
Temă
Lucrează puțin mai mult cu DOM-ul
Declinarea răspunderii: Acest document a fost tradus folosind serviciul de traducere AI Co-op Translator. Deși ne străduim pentru acuratețe, vă rugăm să țineți cont că traducerile automate pot conține erori sau inexactități. Documentul original în limba sa nativă trebuie considerat sursa autorizată. Pentru informații critice, se recomandă traducerea profesională realizată de un specialist uman. Nu ne asumăm responsabilitatea pentru eventualele neînțelegeri sau interpretări greșite cauzate de utilizarea acestei traduceri.


