SYS.ONLINE
[ ASK_ME ↗ ]
INDEX / DOC // SPEC
602 words
•
3 minutes

Mutation Observer in JS

Mutation Observer in JS

شرح الـ MutationObserver بالتفصيل 🔍#

مقدمة سريعة#

يا باشمهندسين، النهاردة هنتكلم عن حاجة مهمة جداً في JavaScript وهي الـ MutationObserver. الأداة دي هتساعدك تراقب أي تغيير بيحصل في صفحتك بشكل فوري وفعال.

هو إيه الـ MutationObserver بالظبط؟ 🤔#

تخيل إنك عندك كاميرا مراقبة بتصور كل حاجة بتحصل في الـ DOM بتاعك. أي عنصر يتضاف، يتمسح، أو يتعدل، الكاميرا دي هتاخد بالها على طول وتقولك. دي بالظبط وظيفة الـ MutationObserver.

ليه نستخدم MutationObserver؟ 💡#

  • لما تحتاج تعرف إن فيه حد غير حاجة في الصفحة
  • لما تحتاج تعمل حاجة معينة بعد ما يحصل تغيير في الصفحة
  • لما تحتاج تتأكد إن التغييرات اللي بتحصل صح
  • لما تحتاج تسجل كل التغييرات اللي بتحصل في الصفحة

إزاي نستخدمه؟ (بالخطوات) 🚀#

أولاً: إنشاء المراقب (Observer)#

const observer = new MutationObserver((mutationsList, observer) => {
    mutationsList.forEach((mutation) => {
        // هنا هنكتب إيه نعمل لما يحصل تغيير
        if (mutation.type === 'childList') {
            console.log('فيه عنصر اتضاف أو اتمسح');
        } else if (mutation.type === 'attributes') {
            console.log('فيه خاصية اتغيرت وهي: ' + mutation.attributeName);
        }
    });
});

الـ callback function اللي بنمررها للـ MutationObserver بتاخد 2 Arguments

  • mutationsList: قائمة بكل التغييرات اللي حصلت.

  • observer: الـ observer نفسه اللي بيتنفذ الكود من خلاله.

  • تالت حاجة التعامل مع التغييرات بنستخدم forEach loop عشان نمر على كل التغييرات اللي في mutationsList ونتعامل معاها بناءً على نوع التغيير

  • childList: لو التغيير في الأطفال (إضافة أو حذف عناصر).

  • attributes: لو التغيير في خصائص العنصر (زي تعديل خاصية معينة).

ثانياً: نحدد إيه اللي عايزين نراقبه#

// الإعدادات بتاعت المراقبة
const config = {
    attributes: true,        // راقب التغييرات في الخصائص
    childList: true,        // راقب التغييرات في العناصر
    subtree: true,          // راقب كل العناصر اللي جوه
    characterData: true     // راقب التغييرات في النصوص
};

// العنصر اللي هنراقبه
const targetNode = document.querySelector('#العنصر-بتاعي');

// نبدأ المراقبة
observer.observe(targetNode, config);

الـarguments بتاعة observe:

  • targetNode: العنصر اللي عايزين نراقبه.
  • config: إعدادات المراقبة، ودي عبارة عن object بيحدد نوع التغييرات اللي عايزين نتابعها:
    • attributes: لو عايزين نتابع التغييرات في خصائص العنصر.
    • childList: لو عايزين نتابع التغييرات في الأطفال (إضافة أو حذف عناصر).
    • subtree: لو عايزين نتابع التغييرات في كل الnodes اللي تحت العنصر ده.

أمثلة عملية 💪#

1️⃣ مراقبة تغييرات الـclasses#

// مراقبة تغييرات الكلاسات في عنصر معين
const classObserver = new MutationObserver((mutationsList) => {
    mutationsList.forEach((mutation) => {
        if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
            console.log('الكلاس اتغير!');
            console.log('الكلاسات الجديدة:', mutation.target.className);
        }
    });
});

classObserver.observe(el, {
    attributes: true,
    attributeFilter: ['class']
});

2️⃣ مراقبة إضافة عناصر جديدة#

// مراقبة إضافة عناصر جديدة في القائمة
const listObserver = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
        if (mutation.addedNodes.length > 0) {
            console.log('Element added:', mutation.addedNodes[0]);
        }
        if (mutation.removedNodes.length > 0) {
            console.log('Element removed:', mutation.removedNodes[0]);
        }
    });
});

listObserver.observe(القائمة، {
    childList: true
});

3️⃣ مراقبة تغييرات النصوص#

// مراقبة تغييرات النصوص في عنصر
const textObserver = new MutationObserver((mutationsList) => {
    mutationsList.forEach((mutation) => {
        if (mutation.type === 'characterData') {
            console.log('النص اتغير ل:', mutation.target.data);
        }
    });
});

textObserver.observe(العنصر، {
    characterData: true,
    subtree: true
});

نصايح مهمة 🎯#

  1. ما تنساش توقف المراقبة: لما تخلص استخدام الـobserver، اعمل:
observer.disconnect();
  1. استخدم takeRecords: لو عايز تاخد كل التغييرات اللي حصلت لحد دلوقتي:
const changesSnapshot = observer.takeRecords();
  1. خلي بالك من الأداء: ما تراقبش كل حاجة في الصفحة، ركز بس على العناصر المهمة يعني كمثال في مراقبة التغييرات في الكلاسات:

استخدام attributeFilter: ['class'] ممتاز لأنه بيحدد المراقبة على class attribute بس، وده بيساعد على تحسين الأداء لأنك بتراقب عنصر معين بدل ما تراقب كل الخصائص.

مشاكل شائعة وحلولها 🔧#

المشكلة الأولى: المراقب مش شغال#

الحل: تأكد إنك:

  • عملت observe للعنصر الصح
  • حطيت الإعدادات المناسبة
  • العنصر موجود في الـ DOM

المشكلة التانية: بيكون سبب في الـmemory leak اللي إتكلمنا عنه قبل كدا#

الحل:

  • اعمل disconnect لما تخلص
  • راقب أقل عدد ممكن من العناصر
  • استخدم attributeFilter لو محتاج تراقب خصائص معينة بس

في النهاية 🎉#

الـ MutationObserver أداة قوية جداً، بس لازم تستخدمها صح. ما تنساش إن فيه حاجات تانية زي الـ events ممكن تكون أبسط وأسرع في بعض الحالات يعني مبتستخدموش لما تكون التغييرات ممكن تتبعها بأحداث بسيطة زي scroll أو click أو input.

Join our whatsapp group here
My Channel here

TERMINAL.COLOPHON // CORE v2.5
LAST.DISPATCH: 2026.09.19
guest@ag-coding:~ (interactive-zsh)
LIVE CLI
RUN //
01 // ISSUES ●
53
Published Articles
02 // CORPUS ≈ 6.7H
80.8K
Total Words Written
03 // SECTORS #
2/39
Categories & Tags
04 // UPTIME 99.9%
ONLINE
Static Edge Node
QUANTUM TELEPORTER // ROULETTE 1-CLICK JUMP
TARGET DESTINATION:
TELEPORT NOW ↗
© 2026 Abdoelaziz Gamal // ALL RIGHTS RESERVED.
30.0444° N, 31.2357° E ■ DESIGNED & ENGINEERED IN CAIRO
OPERATOR // RADAR.HUD
SCROLL.PROGRESS
00% LIVE
Abdoelaziz Gamal
LIVE
// CHIEF ARCHITECT
Abdoelaziz Gamal
REACT.JS NEXT.JS SYS.ARCH
root@ag-coding:~# cat dossier.log ● UTF-8

Full-stack engineer from Mansoura. 5+ years shipping TypeScript / Next.js products — dashboards, multi-tenant apps, CRM, LMS, e-commerce. Behind AG Coding.