JavaScript📅 2026-09-27⏱ 8 دقائق قراءة📜 مقال 8 من 10

التعامل مع 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، أنت جاهز للمقال التالي:

  1. مشروع: آلة حاسبة — تطبيق عملي شامل.
  2. مشروع: قائمة مهام — تطبيق عملي متقدم.
  3. Async/Await — البرمجة غير المتزامنة.

الخلاصة

في هذا المقال، تعلمت:

  • ✅ ما هو DOM ولماذا نحتاجه.
  • ✅ الوصول للعناصر بعدة طرق.
  • ✅ تعديل النص والأنماط.
  • ✅ إنشاء وحذف العناصر.
  • ✅ الأحداث (Events) و addEventListener.
  • ✅ event و preventDefault و stopPropagation.
  • ✅ التفويض (Event Delegation).

تذكر: DOM هو ما يجعل JavaScript تتفاعل مع صفحات الويب. أتقنه جيداً، وستتمكن من بناء تطبيقات ويب تفاعلية كاملة.

هل أتقنت DOM؟ شاركنا في التعليقات!

📚 مقالات ذات صلة

JavaScript

مشروع قائمة المهام بـ JavaScript — دليل عملي شامل 2026

مشروع عملي لبناء تطبيق قائمة مهام كامل بـ JavaScript — إضافة، حذف، تعديل، حفظ تلقائي، مع الكود الكامل والشرح

JavaScript

مشروع آلة حاسبة بـ JavaScript — دليل عملي شامل 2026

مشروع عملي لبناء آلة حاسبة كاملة بـ JavaScript و HTML و CSS — خطوة بخطوة مع الكود الكامل والشرح

JavaScript

المصفوفات والكائنات في JavaScript — دليل شامل 2026

دليل عملي مفصل للمصفوفات والكائنات في JavaScript — الإنشاء، التعديل، الطرق الشائعة، مع تمارين وحلول