DOM Mastery — Events, Delegation & Performance
"Talking to the Browser"
JavaScript এর লজিক (Variables, Loops, Functions) শেখা এক জিনিস, আর সেই লজিক দিয়ে ব্রাউজারের পর্দায় কিছু ঘটানো (UI Manipulation) আরেক জিনিস।
React, Vue বা Angular—তুমি যাই শেখো না কেন, দিনশেষে সবাই এই DOM API ব্যবহার করেই কাজ করে। তাই এটা ভালো বুঝলে তুমি যেকোনো লাইব্রেরি বা ফ্রেমওয়ার্কের বস হতে পারবে।
⭐ ১. DOM আসলে কী? (The Bridge)
ব্রাউজার যখন কোনো HTML ফাইল লোড করে, সে টেক্সটগুলোকে একটি Tree Structure বা গাছের মতো ডালে-পালায় সাজিয়ে ফেলে। এই গাছটাকেই বলা হয় DOM (Document Object Model)।
এটি হলো HTML এবং JavaScript এর মাঝখানের সেতু।
Visualizing the Tree:
document
└── html
├── head
└── body
├── div (Parent)
│ └── button (Child)
└── script
⭐ ২. Selecting Elements (The Hook)
এলিমেন্ট ধরার জন্য আধুনিক এবং পুরনো দুই ধরণের মেথড আছে।
A) The Modern Way (Recommended)
সিনিয়ররা সাধারণত querySelector ব্যবহার করেন কারণ এটি CSS সিলেক্টরের মতো ফ্লেক্সিবল।
// ১. আইড দিয়ে (Best for single item)
const box = document.querySelector("#box");
// ২. ক্লাস দিয়ে
const btn = document.querySelector(".btn-primary");
// ৩. মাল্টিপল আইটেম (NodeList রিটার্ন করে)
const items = document.querySelectorAll(".item");
Senior Insight (NodeList vs Array):
querySelectorAll অ্যারে রিটার্ন করে না, NodeList রিটার্ন করে। তাই map, filter সরাসরি কাজ করে না। Solution: [...items].map(...) অথবা Array.from(items) ব্যবহার করে অ্যারে বানিয়ে নাও।
B) The Legacy Way (Fastest)
যদি পারফরম্যান্স চরম লেভেলে দরকার হয় (যেমন গেম ডেভেলপমেন্ট), তবে getElementById সামান্য ফাস্ট।
const box = document.getElementById("box");
⭐ ৩. Changing UI: Content & Style
Content Manipulation (Security Alert 🚨)
const box = document.querySelector("#box");
// ✅ Safe: শুধু টেক্সট বদলাবে
box.textContent = "Hello World";
// ⚠️ Dangerous: HTML ইনজেক্ট করে (XSS Attack হতে পারে)
box.innerHTML = "Bold Text"; // ইউজারের ইনপুট কখনো innerHTML এ দেবে না!
Style Manipulation
// ❌ জুনিয়র ওয়ে: এক লাইন করে স্টাইল
box.style.color = "red";
box.style.fontSize = "20px";
// ✅ সিনিয়র ওয়ে: ক্লাস অ্যাড/রিমুভ (Clean & Maintainable)
box.classList.add("active");
box.classList.toggle("dark-mode");
⭐ ৪. Events: Bubbling & Capturing (Theory of Flow)
এটি জাভাস্ক্রিপ্টের ইভেন্ট সিস্টেমের হৃৎপিণ্ড। ইভেন্ট শুধু এক জায়গায় ঘটে না, এটি ট্রাভেল করে।
The Bubble Phase 🛁
যখন তুমি কোনো বাটনে ক্লিক করো, সেই ক্লিক ইভেন্টটি বাটন থেকে শুরু হয়ে উপরের দিকে (Parent → Body → HTML → Document) ভেসে ওঠে। একে বলে Bubbling।
// HTML:
document.getElementById("parent").addEventListener("click", () => {
console.log("Parent Clicked");
});
document.getElementById("child").addEventListener("click", () => {
console.log("Child Clicked");
});
// Output (বাটনে ক্লিক করলে):
// "Child Clicked"
// "Parent Clicked" (কারণ ইভেন্ট বাবল হয়ে প্যারেন্টে গেছে)
Stop Propagation (Bubbling থামানো)
মাঝেমধ্যে আমরা চাই না প্যারেন্ট জানুক যে চাইল্ডে ক্লিক হয়েছে।
button.addEventListener("click", (event) => {
event.stopPropagation(); // ✋ ইভেন্ট আর উপরে যাবে না
console.log("Clicked logic only for button");
});
⭐ ৫. Event Delegation (The Senior Pattern) 🚀
ধরা যাক, তোমার একটা লিস্ট (ul) আছে এবং তাতে ১০০টা আইটেম (li) আছে। তুমি কি ১০০টা ইভেন্ট লিসেনার লাগাবে? কখনোই না! এতে ব্রাউজার স্লো হয়ে যাবে।
সমাধান: ইভেন্ট লিসেনার লাগাও বাবার (ul) গায়ে, সে সব সন্তানের (li) ক্লিক একাই হ্যান্ডেল করবে।
const list = document.querySelector("#todo-list");
list.addEventListener("click", (e) => {
// e.target হলো সেই আইটেম যেটাতে ক্লিক করা হয়েছে
if (e.target.tagName === "LI") {
console.log("Item clicked:", e.target.textContent);
// টাস্ক কমপ্লিট করার লজিক
e.target.classList.toggle("completed");
}
});
সুবিধা:
- Memory Save: ১০০টার বদলে ১টা লিসেনার
- Dynamic Support: ভবিষ্যতে নতুন li অ্যাড করলেও ইভেন্ট অটোমেটিক কাজ করবে
⭐ ৬. DOM Traversing (Smart Navigation)
শুধু parentElement বা children দিয়ে কাজ চলে না। আধুনিক মেথড closest() দারুণ কাজের।
const deleteBtn = document.querySelector(".delete");
deleteBtn.addEventListener("click", (e) => {
// ক্লিক করা বাটনের সবচেয়ে কাছের 'row' ক্লাসযুক্ত প্যারেন্টকে খুঁজে বের করো
const row = e.target.closest(".row");
row.remove();
});
⭐ ৭. Performance Optimization (Pro Tips) ⚡
DOM অপারেশন অনেক ভারী (Expensive)। তাই সিনিয়ররা এগুলো মেনে চলেন:
A) DocumentFragment (Batch Insert)
ধরা যাক তুমি ১০০০ আইটেম লুপ চালিয়ে অ্যাপেন্ড করছ। প্রতিবার অ্যাপেন্ড করলে ব্রাউজার ১০০০ বার পেইন্ট করবে।
// ❌ স্লো: প্রতিবার DOM হিট করছে
/* for(let i=0; i<1000; i++) {
document.body.appendChild(item);
} */
// ✅ ফাস্ট: সব মেমোরিতে রেডি করে একবার DOM এ দেওয়া
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
const li = document.createElement("li");
li.textContent = `Item ${i}`;
fragment.appendChild(li); // মেমোরিতে জমা হচ্ছে
}
document.getElementById("list").appendChild(fragment); // ১ বার পেইন্ট হবে!
B) Reflow & Repaint
- Reflow: যখন লেআউট চেঞ্জ হয় (width, height, margin)। এটা খুব স্লো।
- Repaint: যখন শুধু কালার চেঞ্জ হয় (color, opacity)। এটা কিছুটা ফাস্ট।
Tip: লুপের ভেতর style.width বারবার চেঞ্জ করবে না। ক্লাসের মাধ্যমে একবারে চেঞ্জ করো।
🧠 ৮. Senior Interview Questions
Q1: event.target এবং event.currentTarget এর পার্থক্য কী?
A: target হলো সেই এলিমেন্ট যার ওপর আসল ক্লিক পড়েছে (যেমন আইকন)। currentTarget হলো সেই এলিমেন্ট যার সাথে ইভেন্ট লিসেনার লাগানো আছে (যেমন বাটন)।
Q2: innerHTML কেন নিরাপদ নয়?
A: এটি Cross-Site Scripting (XSS) অ্যাটাকের সুযোগ দেয়। হ্যাকাররা স্ক্রিপ্ট ট্যাগ ইনজেক্ট করে কুকি চুরি করতে পারে।
Q3: Event Delegation এর সুবিধা কী?
A: মেমোরি সেভ হয় এবং ডাইনামিকলি অ্যাডেড এলিমেন্টের জন্য আলাদা লিসেনার লাগাতে হয় না।
Q4: HTML Collection vs NodeList?
A: getElementsByClassName দেয় HTMLCollection (Live, DOM চেঞ্জ হলে অটো আপডেট হয়)। querySelectorAll দেয় NodeList (Static, আপডেটেড হয় না)। মডার্ন ডেভেলপমেন্টে আমরা NodeList বেশি ব্যবহার করি।
🚀 অধ্যায় ১১ সারাংশ (Checklist)
আমরা শিখলাম:
- ✓ Selectors: querySelector ইজ কিং
- ✓ Security: innerHTML সাবধানে, textContent বা createElement নিরাপদ
- ✓ Flow: Bubbling (নিচ থেকে উপরে) এবং Capturing (উপর থেকে নিচে)
- ✓ Delegation: প্যারেন্টের কাছে দায়িত্ব দেওয়া (পারফরম্যান্স বুস্ট)
- ✓ Performance: DocumentFragment দিয়ে ব্যাচ আপডেট করা
Next Step: আমরা ব্রাউজার কন্ট্রোল শিখে ফেলেছি। এখন আমাদের অ্যাপের ডাটা ব্রাউজারে সেভ করে রাখতে হবে যাতে রিফ্রেশ দিলেও হারিয়ে না যায়। পরের অধ্যায়: "Browser Storage & Fetch API"।