التعامل مع DOM في JavaScript — دليل شامل 2026
دليل عملي مفصل للتعامل مع DOM في JavaScript — التحديد، التعديل، الأحداث، الإنشاء، مع تمارين وحلول
في المقال السابق، تعلمت المصفوفات والكائنات وكيف تخزن مجموعات من البيانات. لكن كل هذا كان يعمل في الطرفية فقط. الآن حان الوقت لجعل JavaScript تتفاعل مع صفحات الويب — وهذا ما يسمى DOM.
في هذا الدليل العملي، سنأخذك خطوة بخطوة لفهم DOM في JavaScript — من التحديد إلى التعديل والأحداث، مع تمارين وحلول.
ما هو DOM؟
DOM هو اختصار لـ Document Object Model (نموذج كائن المستند). هو تمثيل شجري لصفحة HTML، يمكن لـ JavaScript الوصول إليه وتعديله.
تشبيه بسيط: تخيل صفحة HTML كمبنى، و DOM هو المخطط الذي يحدد كل غرفة (عنصر) وموقعها. JavaScript هي "المفتاح" الذي يسمح لك بالدخول وتعديل أي غرفة.
مثال:
<!DOCTYPE html>
<html>
<body>
<h1 id="title">مرحباً</h1>
<p class="text">هذا نص</p>
</body>
</html>
شجرة DOM:
document
└── html
└── body
├── h1#title
└── p.text
لماذا نحتاج DOM؟
- التفاعل: تغيير النصوص والألوان عند الضغط على زر.
- التحقق من النماذج: التأكد من صحة البيانات قبل الإرسال.
- الرسوم المتحركة: تحريك العناصر.
- التطبيقات التفاعلية: بناء تطبيقات ويب كاملة.
الوصول إلى العناصر
هناك عدة طرق للوصول إلى عناصر HTML من JavaScript:
1. getElementById — بالمعرف (ID)
<h1 id="title">مرحباً</h1>
const title = document.getElementById("title");
console.log(title.textContent); // مرحباً
2. querySelector — بأي محدد CSS
// بالمعرف
const title = document.querySelector("#title");
// بالكلاس
const text = document.querySelector(".text");
// بالعنصر
const heading = document.querySelector("h1");
// محدد معقد
const firstLink = document.querySelector("nav a");
⚠️ ملاحظة: querySelector يُرجع أول عنصر يطابق المحدد.
3. querySelectorAll — كل العناصر المطابقة
const allParagraphs = document.querySelectorAll("p");
allParagraphs.forEach((p) => {
console.log(p.textContent);
});
⚠️ ملاحظة: querySelectorAll يُرجع NodeList (قائمة)، وليس مصفوفة.
4. getElementsByClassName — بالكلاس
const elements = document.getElementsByClassName("text");
5. getElementsByTagName — بالوسم
const paragraphs = document.getElementsByTagName("p");
جدول طرق الوصول
| الطريقة | المحدد | النتيجة |
|---|---|---|
getElementById() | ID | عنصر واحد |
querySelector() | CSS | أول عنصر |
querySelectorAll() | CSS | كل العناصر |
getElementsByClassName() | Class | مجموعة |
getElementsByTagName() | Tag | مجموعة |
تعديل المحتوى
1. textContent — تعديل النص
const title = document.querySelector("#title");
title.textContent = "مرحباً بالعالم الجديد!";
2. innerHTML — تعديل HTML
const container = document.querySelector("#container");
container.innerHTML = "<p>نص جديد <strong>مهم</strong></p>";
⚠️ تحذير: innerHTML خطير إذا استخدمته مع بيانات المستخدم (XSS). استخدم textContent بدلاً منه.
3. innerText — مثل textContent
title.innerText = "نص جديد";
الفرق: innerText يحترم التنسيق (CSS)، بينما textContent يأخذ كل النص.
تعديل الأنماط (CSS)
1. تغيير لون النص:
title.style.color = "red";
title.style.fontSize = "30px";
title.style.backgroundColor = "yellow";
2. إضافة/حذف كلاسات:
title.classList.add("highlight");
title.classList.remove("old-class");
title.classList.toggle("active");
3. التحقق من وجود كلاس:
if (title.classList.contains("highlight")) {
console.log("يحتوي على الكلاس");
}
تعديل الخصائص (Attributes)
<img id="myImage" src="old.jpg" alt="صورة">
const img = document.querySelector("#myImage");
// قراءة
console.log(img.getAttribute("src")); // old.jpg
// تعديل
img.setAttribute("src", "new.jpg");
img.setAttribute("alt", "صورة جديدة");
// حذف
img.removeAttribute("alt");
إنشاء وحذف العناصر
إنشاء عنصر جديد:
const newParagraph = document.createElement("p");
newParagraph.textContent = "هذا نص جديد";
newParagraph.classList.add("text");
// إضافته إلى الصفحة
document.body.appendChild(newParagraph);
إضافة عنصر داخل عنصر آخر:
const container = document.querySelector("#container");
const newDiv = document.createElement("div");
newDiv.textContent = "محتوى";
container.appendChild(newDiv);
حذف عنصر:
const element = document.querySelector(".remove-me");
element.remove();
استبدال عنصر:
const oldElement = document.querySelector(".old");
const newElement = document.createElement("p");
newElement.textContent = "جديد";
oldElement.replaceWith(newElement);
الأحداث (Events)
الأحداث هي تفاعلات المستخدم مع الصفحة: النقر، الكتابة، التمرير...
1. addEventListener — الطريقة الحديثة
const button = document.querySelector("#myButton");
button.addEventListener("click", () => {
console.log("تم النقر!");
});
2. الأحداث الشائعة:
| الحدث | الوصف |
|---|---|
click | نقر بالفأرة |
dblclick | نقر مزدوج |
mouseover | مرور الفأرة |
mouseout | خروج الفأرة |
keydown | ضغط مفتاح |
keyup | رفع مفتاح |
input | كتابة في حقل |
submit | إرسال نموذج |
scroll | تمرير الصفحة |
load | تحميل الصفحة |
3. مثال: زر يغير النص
<button id="changeBtn">اضغط</button>
<h1 id="title">النص الأصلي</h1>
const btn = document.querySelector("#changeBtn");
const title = document.querySelector("#title");
btn.addEventListener("click", () => {
title.textContent = "تم التغيير!";
});
4. مثال: حقل إدخال
<input type="text" id="nameInput" placeholder="أدخل اسمك">
<p id="greeting"></p>
const input = document.querySelector("#nameInput");
const greeting = document.querySelector("#greeting");
input.addEventListener("input", (event) => {
greeting.textContent = "مرحباً " + event.target.value;
});
⚠️ ملاحظة: event.target هو العنصر الذي أطلق الحدث.
5. مثال: نموذج
<form id="myForm">
<input type="email" id="email" required>
<button type="submit">إرسال</button>
</form>
const form = document.querySelector("#myForm");
form.addEventListener("submit", (event) => {
event.preventDefault(); // منع الإرسال الافتراضي
console.log("تم الإرسال!");
});
إزالة مستمع الحدث
function handleClick() {
console.log("تم النقر");
}
button.addEventListener("click", handleClick);
// لاحقاً
button.removeEventListener("click", handleClick);
⚠️ مهم: يجب تمرير نفس الدالة (المرجع نفسه).
التفويض (Event Delegation)
بدلاً من إضافة مستمع لكل عنصر، أضفه للعنصر الأب:
<ul id="list">
<li>عنصر 1</li>
<li>عنصر 2</li>
<li>عنصر 3</li>
</ul>
const list = document.querySelector("#list");
list.addEventListener("click", (event) => {
if (event.target.tagName === "LI") {
console.log("نقرت على: " + event.target.textContent);
}
});
الفائدة: يعمل مع العناصر المضافة ديناميكياً.
التعامل مع event
كائن event يحتوي على معلومات الحدث:
button.addEventListener("click", (event) => {
console.log(event.type); // "click"
console.log(event.target); // العنصر الذي أطلق الحدث
console.log(event.clientX); // إحداثي X
console.log(event.clientY); // إحداثي Y
});
preventDefault() — منع السلوك الافتراضي
const link = document.querySelector("a");
link.addEventListener("click", (event) => {
event.preventDefault(); // منع الانتقال
console.log("تم منع الانتقال");
});
stopPropagation() — منع انتشار الحدث
child.addEventListener("click", (event) => {
event.stopPropagation(); // منع وصول الحدث للأب
});
تمارين عملية
تمرين 1: تغيير نص
أنشئ زراً يغير نص عنوان عند الضغط.
الحل:
<button id="btn">اضغط</button>
<h1 id="title">النص الأصلي</h1>
<script>
const btn = document.querySelector("#btn");
const title = document.querySelector("#title");
btn.addEventListener("click", () => {
title.textContent = "تم التغيير!";
});
</script>
تمرين 2: عداد
أنشئ زراً يزيد عدداً في الصفحة.
الحل:
<button id="increment">+1</button>
<p>العدد: <span id="count">0</span></p>
<script>
let count = 0;
const btn = document.querySelector("#increment");
const display = document.querySelector("#count");
btn.addEventListener("click", () => {
count++;
display.textContent = count;
});
</script>
تمرين 3: تغيير اللون
أنشئ زراً يغير لون خلفية الصفحة.
الحل:
<button id="colorBtn">لون عشوائي</button>
<script>
const btn = document.querySelector("#colorBtn");
btn.addEventListener("click", () => {
const colors = ["red", "blue", "green", "yellow", "purple"];
const random = colors[Math.floor(Math.random() * colors.length)];
document.body.style.backgroundColor = random;
});
</script>
تمرين 4: عرض النص المدخل
أنشئ حقل إدخال يعرض النص أثناء الكتابة.
الحل:
<input type="text" id="input" placeholder="اكتب...">
<p id="output"></p>
<script>
const input = document.querySelector("#input");
const output = document.querySelector("#output");
input.addEventListener("input", (e) => {
output.textContent = e.target.value;
});
</script>
تمرين 5: قائمة مهام بسيطة
أنشئ قائمة مهام يمكن إضافة عناصر إليها.
الحل:
<input type="text" id="taskInput" placeholder="مهمة جديدة">
<button id="addBtn">إضافة</button>
<ul id="taskList"></ul>
<script>
const input = document.querySelector("#taskInput");
const btn = document.querySelector("#addBtn");
const list = document.querySelector("#taskList");
btn.addEventListener("click", () => {
const text = input.value.trim();
if (text === "") return;
const li = document.createElement("li");
li.textContent = text;
li.addEventListener("click", () => li.remove());
list.appendChild(li);
input.value = "";
});
</script>
تمرين 6: تبديل الوضع الداكن
أنشئ زراً يبدل بين الوضع الفاتح والداكن.
الحل:
<button id="themeBtn">تبديل الوضع</button>
<script>
const btn = document.querySelector("#themeBtn");
btn.addEventListener("click", () => {
document.body.classList.toggle("dark");
});
</script>
<style>
.dark {
background-color: #333;
color: white;
}
</style>
حل المشاكل الشائعة
🔴 المشكلة 1: Cannot read property of null
السبب: العنصر غير موجود عند تنفيذ الكود.
const element = document.querySelector("#notExists");
element.textContent = "نص"; // ❌ خطأ
الحل: ضع الكود بعد تحميل DOM، أو تحقق من الوجود:
document.addEventListener("DOMContentLoaded", () => {
const element = document.querySelector("#exists");
if (element) {
element.textContent = "نص";
}
});
🔴 المشكلة 2: addEventListener لا يعمل
السبب: استدعيت الدالة بدلاً من تمريرها.
// خطأ:
button.addEventListener("click", handleClick()); // ❌
// صحيح:
button.addEventListener("click", handleClick); // ✅
🔴 المشكلة 3: this في مستمع الأحداث
السبب: this يشير إلى العنصر عند استخدام function العادية.
button.addEventListener("click", function() {
console.log(this); // العنصر
});
button.addEventListener("click", () => {
console.log(this); // window (أو undefined)
});
الحل: استخدم event.target بدلاً من this.
🔴 المشكلة 4: النموذج يعيد التحميل
السبب: السلوك الافتراضي للنموذج هو إعادة تحميل الصفحة.
الحل: استخدم event.preventDefault().
جدول الأوامر الأساسية
| الأمر | الوظيفة |
|---|---|
document.querySelector() | تحديد عنصر |
document.querySelectorAll() | تحديد كل العناصر |
element.textContent | قراءة/تعديل النص |
element.innerHTML | قراءة/تعديل HTML |
element.style.property | تعديل النمط |
element.classList.add() | إضافة كلاس |
element.addEventListener() | إضافة مستمع حدث |
document.createElement() | إنشاء عنصر |
parent.appendChild(child) | إضافة عنصر |
element.remove() | حذف عنصر |
قائمة تحقق نهائية
| المهمة | الحالة |
|---|---|
| فهم DOM وكيفية الوصول للعناصر | ⬜ |
| استخدام querySelector و querySelectorAll | ⬜ |
| تعديل النص والأنماط | ⬜ |
| إنشاء وحذف العناصر | ⬜ |
| استخدام addEventListener | ⬜ |
| التعامل مع event و preventDefault | ⬜ |
| حل التمارين الستة | ⬜ |
ماذا بعد هذا المقال؟
الآن بعد أن أتقنت DOM، أنت جاهز للمقال التالي:
- مشروع: آلة حاسبة — تطبيق عملي شامل.
- مشروع: قائمة مهام — تطبيق عملي متقدم.
- Async/Await — البرمجة غير المتزامنة.
الخلاصة
في هذا المقال، تعلمت:
- ✅ ما هو DOM ولماذا نحتاجه.
- ✅ الوصول للعناصر بعدة طرق.
- ✅ تعديل النص والأنماط.
- ✅ إنشاء وحذف العناصر.
- ✅ الأحداث (Events) و
addEventListener. - ✅
eventوpreventDefaultوstopPropagation. - ✅ التفويض (Event Delegation).
تذكر: DOM هو ما يجعل JavaScript تتفاعل مع صفحات الويب. أتقنه جيداً، وستتمكن من بناء تطبيقات ويب تفاعلية كاملة.
هل أتقنت DOM؟ شاركنا في التعليقات!
المصفوفات والكائنات في JavaScript — دليل شامل 2026
مشروع آلة حاسبة بـ JavaScript — دليل عملي شامل 2026
📚 مقالات ذات صلة
مشروع قائمة المهام بـ JavaScript — دليل عملي شامل 2026
مشروع عملي لبناء تطبيق قائمة مهام كامل بـ JavaScript — إضافة، حذف، تعديل، حفظ تلقائي، مع الكود الكامل والشرح
مشروع آلة حاسبة بـ JavaScript — دليل عملي شامل 2026
مشروع عملي لبناء آلة حاسبة كاملة بـ JavaScript و HTML و CSS — خطوة بخطوة مع الكود الكامل والشرح
المصفوفات والكائنات في JavaScript — دليل شامل 2026
دليل عملي مفصل للمصفوفات والكائنات في JavaScript — الإنشاء، التعديل، الطرق الشائعة، مع تمارين وحلول