|
|
<!--
|
|
|
CO_OP_TRANSLATOR_METADATA:
|
|
|
{
|
|
|
"original_hash": "bc93f6285423033ebf5b8abeb5282888",
|
|
|
"translation_date": "2025-10-22T15:30:14+00:00",
|
|
|
"source_file": "3-terrarium/3-intro-to-DOM-and-closures/README.md",
|
|
|
"language_code": "tl"
|
|
|
}
|
|
|
-->
|
|
|
# Terrarium Project Part 3: Manipulasyon ng DOM at JavaScript Closures
|
|
|
|
|
|

|
|
|
> Sketchnote ni [Tomomi Imura](https://twitter.com/girlie_mac)
|
|
|
|
|
|
Maligayang pagdating sa isa sa mga pinaka-kapanapanabik na aspeto ng web development - ang paggawa ng mga bagay na interactive! Ang Document Object Model (DOM) ay parang tulay sa pagitan ng iyong HTML at JavaScript, at ngayon gagamitin natin ito upang buhayin ang iyong terrarium. Nang likhain ni Tim Berners-Lee ang unang web browser, inisip niya ang isang web kung saan ang mga dokumento ay maaaring maging dynamic at interactive - ang DOM ang gumagawa ng pangitain na iyon.
|
|
|
|
|
|
Pag-aaralan din natin ang JavaScript closures, na maaaring mukhang nakakatakot sa simula. Isipin ang closures bilang paglikha ng "memory pockets" kung saan ang iyong mga function ay maaaring magtanda ng mahalagang impormasyon. Parang bawat halaman sa iyong terrarium ay may sariling talaan ng data upang subaybayan ang posisyon nito. Sa pagtatapos ng araling ito, maiintindihan mo kung gaano sila ka-natural at kapaki-pakinabang.
|
|
|
|
|
|
Narito ang ating gagawin: isang terrarium kung saan maaaring i-drag at i-drop ng mga user ang mga halaman kahit saan nila gusto. Matutunan mo ang mga teknik sa manipulasyon ng DOM na nagpapagana sa lahat mula sa drag-and-drop file uploads hanggang sa mga interactive na laro. Gawin nating buhay ang iyong terrarium.
|
|
|
|
|
|
## Pre-Lecture Quiz
|
|
|
|
|
|
[Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/19)
|
|
|
|
|
|
## Pag-unawa sa DOM: Ang Iyong Gateway sa Interactive na Mga Web Page
|
|
|
|
|
|
Ang Document Object Model (DOM) ang paraan ng JavaScript upang makipag-usap sa iyong mga elemento ng HTML. Kapag nag-load ang iyong browser ng isang HTML page, lumilikha ito ng isang structured na representasyon ng page na iyon sa memorya - iyon ang DOM. Isipin ito bilang isang family tree kung saan ang bawat elemento ng HTML ay isang miyembro ng pamilya na maaaring ma-access, mabago, o maayos ng JavaScript.
|
|
|
|
|
|
Ang manipulasyon ng DOM ang nagbabago sa mga static na page upang maging interactive na mga website. Tuwing makikita mo ang isang button na nagbabago ng kulay kapag hinover, content na nag-a-update nang hindi nagre-refresh ang page, o mga elementong maaaring i-drag, iyon ang manipulasyon ng DOM na gumagana.
|
|
|
|
|
|

|
|
|
|
|
|
> Isang representasyon ng DOM at ang HTML markup na tumutukoy dito. Mula kay [Olfa Nasraoui](https://www.researchgate.net/publication/221417012_Profile-Based_Focused_Crawler_for_Social_Media-Sharing_Websites)
|
|
|
|
|
|
**Narito ang nagpapalakas sa DOM:**
|
|
|
- **Nagbibigay** ng structured na paraan upang ma-access ang anumang elemento sa iyong page
|
|
|
- **Nagpapahintulot** ng dynamic na pag-update ng content nang walang page refresh
|
|
|
- **Nagbibigay-daan** sa real-time na tugon sa mga interaksyon ng user tulad ng pag-click at pag-drag
|
|
|
- **Lumilikha** ng pundasyon para sa mga modernong interactive na web application
|
|
|
|
|
|
## JavaScript Closures: Paglikha ng Organisado at Makapangyarihang Code
|
|
|
|
|
|
Ang [JavaScript closure](https://developer.mozilla.org/docs/Web/JavaScript/Closures) ay parang pagbibigay sa isang function ng sarili nitong pribadong workspace na may persistent memory. Isipin ang mga finch ni Darwin sa Galápagos Islands na bawat isa ay nagkaroon ng specialized na tuka batay sa kanilang partikular na kapaligiran - ang closures ay gumagana nang katulad, lumilikha ng mga specialized na function na "natatandaan" ang kanilang partikular na konteksto kahit matapos ang parent function.
|
|
|
|
|
|
Sa ating terrarium, ang closures ang tumutulong sa bawat halaman na matandaan ang sarili nitong posisyon nang independiyente. Ang pattern na ito ay makikita sa buong propesyonal na JavaScript development, kaya mahalagang maunawaan ito.
|
|
|
|
|
|
> 💡 **Pag-unawa sa Closures**: Ang closures ay isang mahalagang paksa sa JavaScript, at maraming developer ang gumagamit nito sa loob ng maraming taon bago lubos na maunawaan ang lahat ng teoretikal na aspeto. Ngayon, magpo-focus tayo sa praktikal na aplikasyon - makikita mo ang closures na natural na lumilitaw habang binubuo natin ang mga interactive na feature. Ang pag-unawa ay lalalim habang nakikita mo kung paano nila nilulutas ang mga totoong problema.
|
|
|
|
|
|

|
|
|
|
|
|
> Isang representasyon ng DOM at ang HTML markup na tumutukoy dito. Mula kay [Olfa Nasraoui](https://www.researchgate.net/publication/221417012_Profile-Based_Focused_Crawler_for_Social_Media-Sharing_Websites)
|
|
|
|
|
|
Sa araling ito, tatapusin natin ang ating interactive na terrarium project sa pamamagitan ng paglikha ng JavaScript na magpapahintulot sa user na manipulahin ang mga halaman sa page.
|
|
|
|
|
|
## Bago Tayo Magsimula: Paghahanda para sa Tagumpay
|
|
|
|
|
|
Kakailanganin mo ang iyong HTML at CSS files mula sa mga nakaraang aralin sa terrarium - gagawin nating interactive ang static na disenyo na iyon. Kung ngayon ka lang sasali, ang pagkompleto sa mga araling iyon muna ay magbibigay ng mahalagang konteksto.
|
|
|
|
|
|
Narito ang ating gagawin:
|
|
|
- **Smooth drag-and-drop** para sa lahat ng halaman sa terrarium
|
|
|
- **Coordinate tracking** upang matandaan ng mga halaman ang kanilang mga posisyon
|
|
|
- **Isang kumpletong interactive na interface** gamit ang vanilla JavaScript
|
|
|
- **Malinis at organisadong code** gamit ang closure patterns
|
|
|
|
|
|
## Pagsisimula ng Iyong JavaScript File
|
|
|
|
|
|
Gumawa tayo ng JavaScript file na magpapainteractive sa iyong terrarium.
|
|
|
|
|
|
**Hakbang 1: Gumawa ng iyong script file**
|
|
|
|
|
|
Sa iyong terrarium folder, gumawa ng bagong file na tinatawag na `script.js`.
|
|
|
|
|
|
**Hakbang 2: I-link ang JavaScript sa iyong HTML**
|
|
|
|
|
|
Idagdag ang script tag na ito sa `<head>` section ng iyong `index.html` file:
|
|
|
|
|
|
```html
|
|
|
<script src="./script.js" defer></script>
|
|
|
```
|
|
|
|
|
|
**Bakit mahalaga ang `defer` attribute:**
|
|
|
- **Tinitiyak** na ang iyong JavaScript ay maghihintay hanggang sa ma-load ang lahat ng HTML
|
|
|
- **Pinipigilan** ang mga error kung saan ang JavaScript ay naghahanap ng mga elementong hindi pa handa
|
|
|
- **Tinitiyak** na ang lahat ng iyong mga elemento ng halaman ay available para sa interaksyon
|
|
|
- **Nagbibigay** ng mas mahusay na performance kaysa sa paglalagay ng mga script sa ilalim ng page
|
|
|
|
|
|
> ⚠️ **Mahalagang Paalala**: Ang `defer` attribute ay pumipigil sa mga karaniwang timing issues. Kung wala ito, maaaring subukan ng JavaScript na ma-access ang mga elemento ng HTML bago sila ma-load, na nagdudulot ng mga error.
|
|
|
|
|
|
---
|
|
|
|
|
|
## Pagkonekta ng JavaScript sa Iyong Mga Elemento ng HTML
|
|
|
|
|
|
Bago natin magawang draggable ang mga elemento, kailangang mahanap ng JavaScript ang mga ito sa DOM. Isipin ito na parang sistema ng katalogo sa library - kapag mayroon kang catalog number, maaari mong mahanap ang eksaktong libro na kailangan mo at ma-access ang lahat ng nilalaman nito.
|
|
|
|
|
|
Gagamitin natin ang `document.getElementById()` method upang gawin ang mga koneksyon na ito. Parang mayroong eksaktong filing system - magbibigay ka ng ID, at matutukoy nito ang eksaktong elemento na kailangan mo sa iyong HTML.
|
|
|
|
|
|
### Pag-enable ng Drag Functionality para sa Lahat ng Halaman
|
|
|
|
|
|
Idagdag ang code na ito sa iyong `script.js` file:
|
|
|
|
|
|
```javascript
|
|
|
// Enable drag functionality for all 14 plants
|
|
|
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'));
|
|
|
```
|
|
|
|
|
|
**Narito ang nagagawa ng code na ito:**
|
|
|
- **Hinahanap** ang bawat elemento ng halaman sa DOM gamit ang natatanging ID nito
|
|
|
- **Kinukuha** ang JavaScript reference sa bawat elemento ng HTML
|
|
|
- **Ipinapasa** ang bawat elemento sa isang `dragElement` function (na gagawin natin sa susunod)
|
|
|
- **Ipinaghahanda** ang bawat halaman para sa drag-and-drop interaction
|
|
|
- **Kinokonekta** ang iyong HTML structure sa JavaScript functionality
|
|
|
|
|
|
> 🎯 **Bakit Gamitin ang IDs sa Halip na Classes?** Ang IDs ay nagbibigay ng natatanging identifier para sa mga partikular na elemento, habang ang CSS classes ay idinisenyo para sa pag-style ng mga grupo ng elemento. Kapag kailangang manipulahin ng JavaScript ang mga indibidwal na elemento, ang IDs ang nagbibigay ng precision at performance na kailangan natin.
|
|
|
|
|
|
> 💡 **Pro Tip**: Pansinin kung paano natin tinatawag ang `dragElement()` para sa bawat halaman nang paisa-isa. Ang approach na ito ay tinitiyak na ang bawat halaman ay magkakaroon ng sarili nitong independiyenteng dragging behavior, na mahalaga para sa smooth na interaksyon ng user.
|
|
|
|
|
|
---
|
|
|
|
|
|
## Pagbuo ng Drag Element Closure
|
|
|
|
|
|
Ngayon gagawin natin ang puso ng ating dragging functionality: isang closure na mag-aasikaso sa dragging behavior para sa bawat halaman. Ang closure na ito ay maglalaman ng maraming inner functions na magtutulungan upang subaybayan ang mga galaw ng mouse at i-update ang mga posisyon ng elemento.
|
|
|
|
|
|
Ang closures ay perpekto para sa task na ito dahil pinapayagan nila tayong lumikha ng "pribadong" mga variable na nagpapatuloy sa pagitan ng mga tawag sa function, na nagbibigay sa bawat halaman ng sarili nitong independiyenteng sistema ng coordinate tracking.
|
|
|
|
|
|
### Pag-unawa sa Closures gamit ang Simpleng Halimbawa
|
|
|
|
|
|
Hayaan akong ipakita ang closures gamit ang simpleng halimbawa na naglalarawan ng konsepto:
|
|
|
|
|
|
```javascript
|
|
|
function createCounter() {
|
|
|
let count = 0; // This is like a private variable
|
|
|
|
|
|
function increment() {
|
|
|
count++; // The inner function remembers the outer variable
|
|
|
return count;
|
|
|
}
|
|
|
|
|
|
return increment; // We're giving back the inner function
|
|
|
}
|
|
|
|
|
|
const myCounter = createCounter();
|
|
|
console.log(myCounter()); // 1
|
|
|
console.log(myCounter()); // 2
|
|
|
```
|
|
|
|
|
|
**Narito ang nangyayari sa pattern ng closure na ito:**
|
|
|
- **Lumilikha** ng pribadong `count` variable na umiiral lamang sa loob ng closure na ito
|
|
|
- **Ang inner function** ay maaaring ma-access at mabago ang outer variable (ang mekanismo ng closure)
|
|
|
- **Kapag ibinalik natin** ang inner function, pinapanatili nito ang koneksyon sa pribadong data na iyon
|
|
|
- **Kahit matapos** ang `createCounter()` na tapusin ang execution, nananatili ang `count` at natatandaan ang halaga nito
|
|
|
|
|
|
### Bakit Perpekto ang Closures para sa Drag Functionality
|
|
|
|
|
|
Para sa ating terrarium, kailangang matandaan ng bawat halaman ang kasalukuyang coordinate nito. Ang closures ang nagbibigay ng perpektong solusyon:
|
|
|
|
|
|
**Mga pangunahing benepisyo para sa ating proyekto:**
|
|
|
- **Pinapanatili** ang pribadong position variables para sa bawat halaman nang independiyente
|
|
|
- **Pinapanatili** ang coordinate data sa pagitan ng mga drag events
|
|
|
- **Pinipigilan** ang variable conflicts sa pagitan ng iba't ibang draggable elements
|
|
|
- **Lumilikha** ng malinis at organisadong code structure
|
|
|
|
|
|
> 🎯 **Layunin sa Pag-aaral**: Hindi mo kailangang ma-master ang bawat aspeto ng closures ngayon. Mag-focus sa kung paano nila tinutulungan tayong mag-organisa ng code at magpanatili ng state para sa ating dragging functionality.
|
|
|
|
|
|
### Paglikha ng dragElement Function
|
|
|
|
|
|
Ngayon buuin natin ang pangunahing function na mag-aasikaso sa lahat ng dragging logic. Idagdag ang function na ito sa ibaba ng iyong plant element declarations:
|
|
|
|
|
|
```javascript
|
|
|
function dragElement(terrariumElement) {
|
|
|
// Initialize position tracking variables
|
|
|
let pos1 = 0, // Previous mouse X position
|
|
|
pos2 = 0, // Previous mouse Y position
|
|
|
pos3 = 0, // Current mouse X position
|
|
|
pos4 = 0; // Current mouse Y position
|
|
|
|
|
|
// Set up the initial drag event listener
|
|
|
terrariumElement.onpointerdown = pointerDrag;
|
|
|
}
|
|
|
```
|
|
|
|
|
|
**Pag-unawa sa sistema ng position tracking:**
|
|
|
- **`pos1` at `pos2`**: Nag-iimbak ng pagkakaiba sa pagitan ng lumang at bagong mouse positions
|
|
|
- **`pos3` at `pos4`**: Nagta-track ng kasalukuyang mouse coordinates
|
|
|
- **`terrariumElement`**: Ang partikular na elemento ng halaman na ginagawa nating draggable
|
|
|
- **`onpointerdown`**: Ang event na nagti-trigger kapag sinimulan ng user ang pag-drag
|
|
|
|
|
|
**Narito kung paano gumagana ang pattern ng closure:**
|
|
|
- **Lumilikha** ng pribadong position variables para sa bawat elemento ng halaman
|
|
|
- **Pinapanatili** ang mga variable na ito sa buong lifecycle ng dragging
|
|
|
- **Tinitiyak** na ang bawat halaman ay nagta-track ng sarili nitong coordinates nang independiyente
|
|
|
- **Nagbibigay** ng malinis na interface sa pamamagitan ng `dragElement` function
|
|
|
|
|
|
### Bakit Gamitin ang Pointer Events?
|
|
|
|
|
|
Maaaring magtaka ka kung bakit natin ginagamit ang `onpointerdown` sa halip na ang mas pamilyar na `onclick`. Narito ang paliwanag:
|
|
|
|
|
|
| Uri ng Event | Pinakamahusay Para sa | Ang Catch |
|
|
|
|--------------|-----------------------|-----------|
|
|
|
| `onclick` | Simpleng pag-click ng button | Hindi kayang mag-handle ng dragging (click lang at release) |
|
|
|
| `onpointerdown` | Parehong mouse at touch | Mas bago, pero suportado na ngayon |
|
|
|
| `onmousedown` | Desktop mouse lang | Hindi kasama ang mga mobile user |
|
|
|
|
|
|
**Bakit perpekto ang pointer events para sa ating ginagawa:**
|
|
|
- **Maganda ang performance** kahit gumamit ng mouse, daliri, o stylus
|
|
|
- **Pareho ang pakiramdam** sa laptop, tablet, o phone
|
|
|
- **Nagha-handle** ng aktwal na galaw ng dragging (hindi lang click-and-done)
|
|
|
- **Lumilikha** ng smooth na karanasan na inaasahan ng mga user mula sa modernong web apps
|
|
|
|
|
|
> 💡 **Pag-iwas sa Problema sa Hinaharap**: Ang pointer events ang modernong paraan upang mag-handle ng user interactions. Sa halip na magsulat ng hiwalay na code para sa mouse at touch, makukuha mo ang pareho nang libre. Ang galing, di ba?
|
|
|
|
|
|
---
|
|
|
|
|
|
## Ang pointerDrag Function: Pagkuha ng Simula ng Drag
|
|
|
|
|
|
Kapag pinindot ng user ang isang halaman (gamit ang mouse click o finger touch), ang `pointerDrag` function ang gumagana. Ang function na ito ang kumukuha ng initial coordinates at nagse-set up ng dragging system.
|
|
|
|
|
|
Idagdag ang function na ito sa loob ng iyong `dragElement` closure, pagkatapos ng linya na `terrariumElement.onpointerdown = pointerDrag;`:
|
|
|
|
|
|
```javascript
|
|
|
function pointerDrag(e) {
|
|
|
// Prevent default browser behavior (like text selection)
|
|
|
e.preventDefault();
|
|
|
|
|
|
// Capture the initial mouse/touch position
|
|
|
pos3 = e.clientX; // X coordinate where drag started
|
|
|
pos4 = e.clientY; // Y coordinate where drag started
|
|
|
|
|
|
// Set up event listeners for the dragging process
|
|
|
document.onpointermove = elementDrag;
|
|
|
document.onpointerup = stopElementDrag;
|
|
|
}
|
|
|
```
|
|
|
|
|
|
**Hakbang-hakbang, narito ang nangyayari:**
|
|
|
- **Pinipigilan** ang default na browser behaviors na maaaring makasagabal sa dragging
|
|
|
- **Nire-record** ang eksaktong coordinates kung saan sinimulan ng user ang drag gesture
|
|
|
- **Nag-eestablish** ng event listeners para sa patuloy na galaw ng drag
|
|
|
- **Ipinaghahanda** ang sistema upang mag-track ng galaw ng mouse/finger sa buong dokumento
|
|
|
|
|
|
### Pag-unawa sa Event Prevention
|
|
|
|
|
|
Ang linya na `e.preventDefault()` ay mahalaga para sa smooth na dragging:
|
|
|
|
|
|
**Kung walang prevention, maaaring:**
|
|
|
- **Mag-select** ng text kapag nag-drag sa page
|
|
|
- **Mag-trigger** ng context menus sa right-click drag
|
|
|
- **Makialam** sa custom na dragging behavior natin
|
|
|
- **Lumikha** ng visual artifacts sa panahon ng drag operation
|
|
|
|
|
|
> 🔍 **Eksperimento**: Pagkatapos tapusin ang araling ito, subukang tanggalin ang `e.preventDefault()` at tingnan kung paano nito naaapektuhan ang dragging experience. Mabilis mong mauunawaan kung bakit mahalaga ang linyang ito!
|
|
|
|
|
|
### Sistema ng Coordinate Tracking
|
|
|
|
|
|
Ang `e.clientX` at `e.clientY` properties ang nagbibigay sa atin ng eksaktong mouse/touch coordinates:
|
|
|
|
|
|
| Property | Ano ang Sinusukat | Gamit |
|
|
|
|----------|-------------------|-------|
|
|
|
| `clientX` | Horizontal na posisyon kaugnay ng viewport | Pag-track ng galaw pakaliwa-pakanan |
|
|
|
| `clientY` | Vertical na posisyon kaugnay ng viewport | Pag-track ng galaw pataas-pababa |
|
|
|
|
|
|
**Pag-unawa sa mga coordinates na ito:**
|
|
|
- **Nagbibigay** ng pixel-perfect na impormasyon sa posisyon
|
|
|
- **Nag-a-update** nang real-time habang gumagalaw ang pointer ng user
|
|
|
- **Nanatili** na pare-pareho sa iba't ibang screen sizes at zoom levels
|
|
|
- **Nagpapahintulot** ng smooth, responsive na drag interactions
|
|
|
|
|
|
### Pag-set Up ng Document-Level Event Listeners
|
|
|
|
|
|
Pansinin kung paano natin ina-attach ang move at stop events sa buong `document`, hindi lang sa elemento ng halaman:
|
|
|
|
|
|
```javascript
|
|
|
document.onpointermove = elementDrag;
|
|
|
document.onpointerup = stopElementDrag;
|
|
|
```
|
|
|
|
|
|
**Bakit i-attach sa document:**
|
|
|
- **Nagpapatuloy** sa pag-track kahit lumabas ang mouse sa elemento ng halaman
|
|
|
- **Pinipigilan** ang pagputol ng drag kung mabilis gumalaw ang user
|
|
|
- **Nagbibigay** ng smooth na dragging sa buong screen
|
|
|
- **Nagha-handle** ng edge cases kung saan lumalabas ang cursor sa browser window
|
|
|
|
|
|
> ⚡ **Tandaan sa Performance**: Lilinisin natin ang mga document-level listeners kapag natapos ang dragging upang maiwasan ang memory leaks at performance issues.
|
|
|
|
|
|
## Pagtatapos ng Drag System: Galaw at Cleanup
|
|
|
|
|
|
Ngayon idadagdag natin ang dalawang natitirang functions na humahawak sa aktwal na galaw ng dragging at ang cleanup kapag natapos ang dragging. Ang mga functions na ito ay nagtutulungan upang lumikha ng smooth, responsive na galaw ng halaman sa iyong terrarium.
|
|
|
|
|
|
### Ang elementDrag Function: Pag-track ng Galaw
|
|
|
|
|
|
Idagdag ang `elementDrag` function pagkatapos ng closing curly bracket ng `pointerDrag`:
|
|
|
|
|
|
```javascript
|
|
|
function elementDrag(e) {
|
|
|
// Calculate the distance moved since the last event
|
|
|
pos1 = pos3 - e.clientX; // Horizontal distance moved
|
|
|
pos2 = pos4 - e.clientY; // Vertical distance moved
|
|
|
|
|
|
// Update the current position tracking
|
|
|
pos3 = e.clientX; // New current X position
|
|
|
pos4 = e.clientY; // New current Y position
|
|
|
|
|
|
// Apply the movement to the element's position
|
|
|
terrariumElement.style.top = (terrariumElement.offsetTop - pos2) + 'px';
|
|
|
terrariumElement.style.left = (terrariumElement.offsetLeft - pos1) + 'px';
|
|
|
}
|
|
|
```
|
|
|
|
|
|
**Pag-unawa sa coordinate mathematics:**
|
|
|
- **`pos1` at `pos2`**: Kinakalkula kung gaano kalayo ang galaw ng mouse mula sa huling update
|
|
|
- **`pos3` at `pos4`**: Iniimbak ang kasalukuyang posisyon ng mouse para sa susunod na kalkulasyon
|
|
|
- **`offsetTop` at `offsetLeft`**: Kinukuha ang kasalukuyang posisyon ng elemento sa pahina
|
|
|
- **Lohikang pagbabawas**: Inililipat ang elemento sa parehong distansya na nilakbay ng mouse
|
|
|
|
|
|
**Narito ang breakdown ng kalkulasyon ng paggalaw:**
|
|
|
1. **Sinusukat** ang pagkakaiba sa pagitan ng lumang at bagong posisyon ng mouse
|
|
|
2. **Kinakalkula** kung gaano kalayo ang ililipat ng elemento base sa galaw ng mouse
|
|
|
3. **Ina-update** ang mga CSS position properties ng elemento nang real-time
|
|
|
4. **Iniimbak** ang bagong posisyon bilang baseline para sa susunod na kalkulasyon ng paggalaw
|
|
|
|
|
|
### Visual na Representasyon ng Matematika
|
|
|
|
|
|
```mermaid
|
|
|
sequenceDiagram
|
|
|
participant Mouse
|
|
|
participant JavaScript
|
|
|
participant Plant
|
|
|
|
|
|
Mouse->>JavaScript: Move from (100,50) to (110,60)
|
|
|
JavaScript->>JavaScript: Calculate: moved 10px right, 10px down
|
|
|
JavaScript->>Plant: Update position by +10px right, +10px down
|
|
|
Plant->>Plant: Render at new position
|
|
|
```
|
|
|
|
|
|
### Ang stopElementDrag Function: Paglilinis
|
|
|
|
|
|
Idagdag ang cleanup function pagkatapos ng closing curly bracket ng `elementDrag`:
|
|
|
|
|
|
```javascript
|
|
|
function stopElementDrag() {
|
|
|
// Remove the document-level event listeners
|
|
|
document.onpointerup = null;
|
|
|
document.onpointermove = null;
|
|
|
}
|
|
|
```
|
|
|
|
|
|
**Bakit mahalaga ang cleanup:**
|
|
|
- **Pinipigilan** ang memory leaks mula sa mga event listener na naiwan
|
|
|
- **Itinitigil** ang dragging behavior kapag binitiwan ng user ang halaman
|
|
|
- **Pinapayagan** ang ibang elemento na ma-drag nang hiwalay
|
|
|
- **Ire-reset** ang sistema para sa susunod na drag operation
|
|
|
|
|
|
**Ano ang mangyayari kung walang cleanup:**
|
|
|
- Patuloy na tumatakbo ang mga event listener kahit natapos na ang pag-drag
|
|
|
- Bumabagal ang performance dahil sa mga hindi nagagamit na listener
|
|
|
- Nagkakaroon ng hindi inaasahang behavior kapag nakikipag-ugnayan sa ibang elemento
|
|
|
- Nasasayang ang resources ng browser sa hindi kinakailangang event handling
|
|
|
|
|
|
### Pag-unawa sa CSS Position Properties
|
|
|
|
|
|
Ang ating dragging system ay nagma-manipula ng dalawang pangunahing CSS properties:
|
|
|
|
|
|
| Property | Ano ang Kinokontrol | Paano Natin Ginagamit |
|
|
|
|----------|---------------------|-----------------------|
|
|
|
| `top` | Distansya mula sa itaas na gilid | Vertical na posisyon habang nagda-drag |
|
|
|
| `left` | Distansya mula sa kaliwang gilid | Horizontal na posisyon habang nagda-drag |
|
|
|
|
|
|
**Mga mahalagang kaalaman tungkol sa offset properties:**
|
|
|
- **`offsetTop`**: Kasalukuyang distansya mula sa itaas ng positioned parent element
|
|
|
- **`offsetLeft`**: Kasalukuyang distansya mula sa kaliwa ng positioned parent element
|
|
|
- **Positioning context**: Ang mga value na ito ay relative sa pinakamalapit na positioned ancestor
|
|
|
- **Real-time updates**: Agad na nagbabago kapag binago natin ang mga CSS properties
|
|
|
|
|
|
> 🎯 **Disenyo ng Pilosopiya**: Ang drag system na ito ay sadyang flexible – walang "drop zones" o limitasyon. Maaaring ilagay ng mga user ang mga halaman kahit saan, binibigyan sila ng ganap na kontrol sa disenyo ng kanilang terrarium.
|
|
|
|
|
|
## Pagsasama-sama: Ang Iyong Kumpletong Drag System
|
|
|
|
|
|
Binabati kita! Nakagawa ka ng isang sopistikadong drag-and-drop system gamit ang vanilla JavaScript. Ang iyong kumpletong `dragElement` function ay naglalaman na ngayon ng isang makapangyarihang closure na namamahala sa:
|
|
|
|
|
|
**Ano ang nagagawa ng iyong closure:**
|
|
|
- **Nagpapanatili** ng mga pribadong position variable para sa bawat halaman nang hiwalay
|
|
|
- **Humahawak** sa buong drag lifecycle mula simula hanggang matapos
|
|
|
- **Nagbibigay** ng smooth, responsive na paggalaw sa buong screen
|
|
|
- **Naglilinis** ng mga resources nang maayos upang maiwasan ang memory leaks
|
|
|
- **Lumilikha** ng intuitive, creative na interface para sa disenyo ng terrarium
|
|
|
|
|
|
### Pagsubok sa Iyong Interactive Terrarium
|
|
|
|
|
|
Ngayon subukan ang iyong interactive terrarium! Buksan ang iyong `index.html` file sa isang web browser at subukan ang functionality:
|
|
|
|
|
|
1. **I-click at hawakan** ang anumang halaman upang simulan ang pag-drag
|
|
|
2. **Igalaw ang iyong mouse o daliri** at panoorin ang halaman na sumusunod nang maayos
|
|
|
3. **Bitawan** upang ilagay ang halaman sa bagong posisyon
|
|
|
4. **Mag-eksperimento** sa iba't ibang ayos upang tuklasin ang interface
|
|
|
|
|
|
🥇 **Tagumpay**: Nakagawa ka ng isang ganap na interactive na web application gamit ang mga pangunahing konsepto na ginagamit ng mga propesyonal na developer araw-araw. Ang drag-and-drop functionality na ito ay gumagamit ng parehong prinsipyo sa likod ng file uploads, kanban boards, at marami pang ibang interactive na interface.
|
|
|
|
|
|

|
|
|
|
|
|
---
|
|
|
|
|
|
## Hamon ng GitHub Copilot Agent 🚀
|
|
|
|
|
|
Gamitin ang Agent mode upang tapusin ang sumusunod na hamon:
|
|
|
|
|
|
**Deskripsyon:** Pagandahin ang terrarium project sa pamamagitan ng pagdaragdag ng reset functionality na ibabalik ang lahat ng halaman sa kanilang orihinal na posisyon gamit ang smooth animations.
|
|
|
|
|
|
**Prompt:** Gumawa ng reset button na, kapag na-click, ay mag-a-animate ng lahat ng halaman pabalik sa kanilang orihinal na posisyon sa sidebar gamit ang CSS transitions. Ang function ay dapat mag-imbak ng orihinal na posisyon kapag nag-load ang pahina at maayos na i-transition ang mga halaman pabalik sa mga posisyon na iyon sa loob ng 1 segundo kapag na-click ang reset button.
|
|
|
|
|
|
Alamin pa ang tungkol sa [agent mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) dito.
|
|
|
|
|
|
## 🚀 Karagdagang Hamon: Palawakin ang Iyong Kakayahan
|
|
|
|
|
|
Handa ka na bang dalhin ang iyong terrarium sa susunod na antas? Subukang ipatupad ang mga pagpapahusay na ito:
|
|
|
|
|
|
**Mga Creative Extensions:**
|
|
|
- **Double-click** ang isang halaman upang ilagay ito sa harapan (z-index manipulation)
|
|
|
- **Magdagdag ng visual feedback** tulad ng banayad na glow kapag hover sa mga halaman
|
|
|
- **Magpatupad ng boundaries** upang pigilan ang mga halaman na ma-drag sa labas ng terrarium
|
|
|
- **Gumawa ng save function** na nagtatanda ng mga posisyon ng halaman gamit ang localStorage
|
|
|
- **Magdagdag ng sound effects** para sa pag-pick up at paglagay ng mga halaman
|
|
|
|
|
|
> 💡 **Pagkakataon sa Pag-aaral**: Ang bawat isa sa mga hamon na ito ay magtuturo sa iyo ng mga bagong aspeto ng DOM manipulation, event handling, at disenyo ng user experience.
|
|
|
|
|
|
## Post-Lecture Quiz
|
|
|
|
|
|
[Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/20)
|
|
|
|
|
|
## Review & Self Study: Palalimin ang Iyong Pag-unawa
|
|
|
|
|
|
Na-master mo na ang mga pangunahing kaalaman ng DOM manipulation at closures, ngunit palaging may mas marami pang matutunan! Narito ang ilang mga landas upang palawakin ang iyong kaalaman at kakayahan.
|
|
|
|
|
|
### Alternatibong Paraan ng Drag and Drop
|
|
|
|
|
|
Ginamit natin ang pointer events para sa maximum na flexibility, ngunit maraming paraan ang web development:
|
|
|
|
|
|
| Paraan | Pinakamahusay Para sa | Halaga ng Pag-aaral |
|
|
|
|--------|-----------------------|---------------------|
|
|
|
| [HTML Drag and Drop API](https://developer.mozilla.org/docs/Web/API/HTML_Drag_and_Drop_API) | File uploads, pormal na drag zones | Pag-unawa sa native browser capabilities |
|
|
|
| [Touch Events](https://developer.mozilla.org/docs/Web/API/Touch_events) | Mobile-specific interactions | Mga pattern ng mobile-first development |
|
|
|
| CSS `transform` properties | Smooth animations | Mga teknik sa performance optimization |
|
|
|
|
|
|
### Mga Advanced na Paksa sa DOM Manipulation
|
|
|
|
|
|
**Mga susunod na hakbang sa iyong pag-aaral:**
|
|
|
- **Event delegation**: Mahusay na paghawak ng events para sa maraming elemento
|
|
|
- **Intersection Observer**: Pag-detect kapag ang mga elemento ay pumasok/lumabas sa viewport
|
|
|
- **Mutation Observer**: Pagbabantay sa mga pagbabago sa istruktura ng DOM
|
|
|
- **Web Components**: Paglikha ng reusable, encapsulated na UI elements
|
|
|
- **Virtual DOM concepts**: Pag-unawa kung paano ino-optimize ng mga framework ang DOM updates
|
|
|
|
|
|
### Mahahalagang Resources para sa Patuloy na Pag-aaral
|
|
|
|
|
|
**Teknikal na Dokumentasyon:**
|
|
|
- [MDN Pointer Events Guide](https://developer.mozilla.org/docs/Web/API/Pointer_events) - Komprehensibong pointer event reference
|
|
|
- [W3C Pointer Events Specification](https://www.w3.org/TR/pointerevents1/) - Opisyal na dokumentasyon ng standards
|
|
|
- [JavaScript Closures Deep Dive](https://developer.mozilla.org/docs/Web/JavaScript/Closures) - Mga advanced na closure patterns
|
|
|
|
|
|
**Browser Compatibility:**
|
|
|
- [CanIUse.com](https://caniuse.com/) - Tingnan ang suporta ng feature sa iba't ibang browser
|
|
|
- [MDN Browser Compatibility Data](https://github.com/mdn/browser-compat-data) - Detalyadong impormasyon sa compatibility
|
|
|
|
|
|
**Mga Pagkakataon sa Practice:**
|
|
|
- **Gumawa** ng puzzle game gamit ang katulad na drag mechanics
|
|
|
- **Lumikha** ng kanban board na may drag-and-drop task management
|
|
|
- **Magdisenyo** ng image gallery na may draggable photo arrangements
|
|
|
- **Mag-eksperimento** sa touch gestures para sa mobile interfaces
|
|
|
|
|
|
> 🎯 **Strategiya sa Pag-aaral**: Ang pinakamahusay na paraan upang ma-solidify ang mga konseptong ito ay sa pamamagitan ng practice. Subukang gumawa ng mga variation ng draggable interfaces – bawat proyekto ay magtuturo sa iyo ng bago tungkol sa user interaction at DOM manipulation.
|
|
|
|
|
|
## Assignment
|
|
|
|
|
|
[Work a bit more with the DOM](assignment.md)
|
|
|
|
|
|
---
|
|
|
|
|
|
**Paunawa**:
|
|
|
Ang dokumentong ito ay isinalin gamit ang AI translation service na [Co-op Translator](https://github.com/Azure/co-op-translator). Bagamat sinisikap naming maging tumpak, pakatandaan na ang mga awtomatikong pagsasalin ay maaaring maglaman ng mga pagkakamali o hindi pagkakatugma. Ang orihinal na dokumento sa kanyang katutubong wika ang dapat ituring na opisyal na pinagmulan. Para sa mahalagang impormasyon, inirerekomenda ang propesyonal na pagsasalin ng tao. Hindi kami mananagot sa anumang hindi pagkakaunawaan o maling interpretasyon na dulot ng paggamit ng pagsasaling ito. |