تحدثنا في مقالتين سابقتين عن طريقة الوصول إلى العناصر في DOM و التنقل بين عقد شجرة DOM وتعلمنا كيف يستطيع مطورو الويب استخدام الأصناف، والوسم، والمعرفات لإيجاد عقدة في DOM بالإضافة إلى استخدام خصائص القرابة بين هذه العقد للتنقل فيما بينها بهدف الوصول في النهاية إلى العقدة المطلوبة.
الخطوة التالية الآن ستكون احترافية بشكل أكبر حيث سنتعلم طريقة إضافة، وتغيير، واستبدال، وإزالة العقد من DOM. وسنتدرّب على ذلك عبر برنامج قائمة مهام بسيط مع لغة جافاسكربت.
سنتعلم في هذه المقالة كيفية إنشاء العقد وإضافتها إلى DOM، واستبدال وإزالة عقد قديمة.
إنشاء عقد جديدة
في مواقع الويب الثابتة، يتم إضافة العناصر بشكل مباشر من خلال كتابة ملف HTML باللاحقة .html
ولكن في تطبيقات الويب الديناميكية المتغيرة باستمرار، تُضَاف العناصر والنصوص بشكل آلي من خلال جافاسكربت باستخدام توابع مثل createElement()
و createTextNode()
التي تنشئ عقدة جديدة في DOM.
الخاصية / التابع | التوصيف |
---|---|
createElement()
|
إنشاء عقدة جديدة من نوع عنصر |
createTextNode()
|
إنشاء عقدة جديدة من نوع نص |
node.textContent
|
الوصول أو تعديل المحتوى النصي لعقدة العنصر |
node.innerHTML
|
الوصول أو تعديل محتوى HTML في العنصر |
لنبدأ أولًا بإنشاء الملف index.html ونقوم بحفظه في مجلد المشروع.
<!DOCTYPE html> <html lang="en"> <head> <title>Learning the DOM</title> </head> <body> <h1>Document Object Model</h1> </body> </html>
نضغط بالزر الأيمن على أي مكان في الصفحة لتظهر لدينا قائمة نختار منها "Inspect" لفتح أدوات التطوير ثم نختار اللسان Console. سنقوم الآن باستخدام التابع ()createElement
الموجود في الكائن document
من أجل إنشاء عنصر جديد هو p
:
> const paragraph = document.createElement('p');
للتأكد من أنه تم إنشاء العنصر p
، ندخل التعليمة التالية إلى الطرفية:
> console.log(paragraph)
حيث سيكون الخرج هو:
<p></p>
نلاحظ أن المتغير paragraph
أعطانا كخرج عنصر p
فارغ وهو غير مفيد من دون وجود نص فيه، لذلك سنقوم بإضافة النص من خلال تعديل الخاصية textContent
بالشكل التالي:
> paragraph.textContent = "I'm a brand new paragraph."; > console.log(paragraph)
عندها سيكون الخرج هو:
<p>I'm a brand new paragraph.</p>
إن استخدام ()createElement
و textContent
معًا يؤدي إلى بناء عقدة عنصر كاملة. ولكن يمكن أيضًا استخدام تابع بديل لتعديل محتوى العنصر من خلال الخاصيةinnerHTML
التي تسمح بإضافة تعليمات HTML ونص عادي إلى العنصر بآن واحد:
> paragraph.innerHTML = "I'm a paragraph with <strong>bold</strong> text.";
تحذير: إن طريقة استخدام innerHTML
شائعة لإضافة محتوى إلى العنصر ولكن سيصبح الموقع عرضة لخطر هجوم cross-site scripting (xxs) والذي يتم من خلال إضافة سطر تعليمة جافاسكربت قد تؤدي إلى ضرر بالموقع باستخدام innerHTML
غير مرغوب فيه، لذلك ينصح باستخدام textContent
وبالتالي سيتم التخلص من وسوم HTML فورًا. كما أنه من الممكن استخدام التابع createTextNode()
لإضافة عقدة نص، كما في التعليمة:
> const text = document.createTextNode("I'm a new text node."); > console.log(text)
وسيكون الخرج هو بالشكل:
"I'm a new text node."
إذًا، نستطيع من خلال هذه التوابع إنشاء عقد عناصر ونصوص جديدة، ولكن هذه العقد لن تصبح مرئية في واجهة الموقع حتى يتم إدخالها إلى المستند document
.
إضافة عقد إلى DOM
نحتاج الآن بعد بناء عقد العناصر والنصوص إلى إضافتها إلى document
ويتم ذلك من خلال استخدام مجموعة من التوابع مثل appendChild()
و insertBefore()
لإضافة العناصر في بداية، وسط، أو نهاية عنصر الأب، كما يمكن استخدام التابع replaceChild()
لاستبدال عقدة قديمة بأخرى جديدة.
الخاصية / التابع | التوصيف |
---|---|
node.appendChild()
|
إضافة عقدة كابن أخير للعنصر الأب |
node.insertBefore()
|
إضافة عقدة على نفس مستوى عقدة الأب قبل عقدة الأخ المحددة |
node.replaceChild()
|
استبدال العقدة الحالة بأخرى جديدة |
للتمرن على هذه التوابع سنقوم بإنشاء قائمة المهام التالية باستخدام html:
- Buy groceries
- Feed the cat
- Do laundry
وعند تحميل الملف السابق إلى المتصفح فإنه سيبدو بالشكل:
الآن سنقوم بإضافة عنصر جديد إلى نهاية قائمة المهام، وللقيام بذلك سننشئ عنصرًا ونضيف له نصًّا كما فعلنا في المقطع السابق:
> // ليمثل قائمة المهام ul إنشاء عنصر > const todoList = document.querySelector('ul'); > // إنشاء مهمة جديدة أي عنصر قائمة > const newTodo = document.createElement('li'); > newTodo.textContent = 'Do homework';
الأن سنقوم بإضافة هذه المهمة إلى نهاية القائمة باستخدام التابع appendChild()
:
> // إضافة مهمة جديدة إلى نهاية القائمة > todoList.appendChild(newTodo);
عند فتح ملف html الخاص بالقائمة، سنلاحظ أنه تم إضافة عنصر li
جديد في نهاية ul
:
<ul> <li>Buy groceries</li> <li>Feed the cat</li> <li>Do laundry</li> <li>Do homework</li> </ul>
قد نحتاج لإضافة مهمة جديدة إلى القائمة ولكنها على رأس الأولويات، وبالتالي نحتاج لإضافتها في رأس القائمة. وللقيام بذلك، سنبدأ أولًا بإنشاء عنصر من خلال التابع createElement()
ولكنه غير قابل للاستخدام بعد:
> // إنشاء مهمة جديدة > const anotherTodo = document.createElement('li'); > anotherTodo.textContent = 'Pay bills';
ولإضافة هذا العنصر إلى رأس القائمة، سنستخدم التابع insertBefore()
حيث نمرر لهذا التابع متغيرين الأول هو العقدة الجديدة التي نريد إضافتها والثاني هو العقدة الأخ الذي يأتي مباشرة بعد العقدة الجديدة وسيكون شكل التعليمة كما يلي:
parentNode.insertBefore(newNode, nextSibling);
الآن، لتطبيق التعليمة السابقة عمليًا على قائمتنا، سنضيف العقدة التي بنيناها سابقًا والمسماة anotherTodo
قبل العنصر الأول من أبناء القائمة والذي هو العنصر “Buy groceries”:
> // إضافة مهمة جديدة إلى بداية القائمة > todoList.insertBefore(anotherTodo, todoList.firstElementChild);
الآن سيصبح شكل ملف todo.html هو:
<ul> <li>Pay bills</li> <li>Buy groceries</li> <li>Feed the cat</li> <li>Do laundry</li> <li>Do homework</li> </ul>
وعند تحميل الملف السابق على المتصفح سيظهر كمايلي:
إذًا تمت إضافة العقدة الجديدة بنجاح لبداية القائمة، وهكذا نكون قد تعلمنا كيفية إضافة عقدة ابن لعقدة أب ولكن يمكننا أيضًا استبدال هذه العقدة الموجودة بعقدة جديدة.
لتعديل عقدة موجودة في قائمة المهام، سننشئ أولًا عنصرًا جديدًا:
> const modifiedTodo = document.createElement('li'); > modifiedTodo.textContent = 'Feed the dog';
سنقوم بالاستبدال باستخدام التابع replaceChild()
الذي يشبه التابع insertBefore()
حيث يتم تمرير متحولين له الأول هو العقدة الجديدة والثاني هو العقدة المراد استبدالها، حيث أن الشكل العام لهذه التعليمة هو:
parentNode.replaceChild(newNode, oldNode);
الآن سنقوم باستبدال العنصر الثالث في القائمة بالعنصر الجديد:
> // استبدال مهمة موجودة مسبقًا بأخرى > todoList.replaceChild(modifiedTodo, todoList.children[2]);
حيث سيتم تلقائيًا تعديل تعليمات ملف html لتصبح بالشكل:
<ul> <li>Pay bills</li> <li>Buy groceries</li> <li>Feed the dog</li> <li>Do laundry</li> <li>Do homework</li> </ul>
ويصبح شكل صفحة الويب:
باستخدام توابع appendChild()
، و insertBefore()
، و replaceChild()
يمكننا إضافة العناصر إلى أي مكان في DOM.
حذف عقد من DOM
بما أننا تعرفنا على طريقة إنشاء عناصر وإضافتهم إلى DOM أو تعديل العناصر الموجودة، تبقى لنا الخطوة الأخيرة لإتمامها وهي تعلم كيفية حذف عنصر موجود في DOM. نستطيع حذف العقد الأبناء من العقدة الأب باستعمال التابع removeChild()
كما نستطيع حذف العقدة نفسها باستخدام التابع remove()
.
التابع | التوصيف |
---|---|
node.removeChild()
|
حذف عقدة ابن |
node.remove()
|
حذف العقدة نفسها |
بالعودة إلى مثال قائمة المهام السابق، سنحذف عناصر من القائمة بعد الانتهاء منها. مثلًا سنقوم بحذف المهمة "Do homework" الموجودة في نهاية القائمة (أي هي الابن الأخير للقائمة) وذلك باستخدام التابع removeChild()
:
>todoList.removeChild(todoList.lastElementChild);
بالعودة لملف html نلاحظ أن عنصر li
الأخير قد حُذِف:
<ul> <li>Pay bills</li> <li>Buy groceries</li> <li>Feed the dog</li> <li>Do laundry</li> </ul>
الآن سنستخدم التابع الآخر وهو remove()
والذي يقوم بحذف العقدة نفسها مباشرة:
> // Remove second element child from todoList
> todoList.children[1].remove();
وبالتالي يصبح ملف html بالشكل التالي:
<ul> <li>Pay bills</li> <li>Feed the dog</li> <li>Do laundry</li> </ul>
باستخدام التابعين removeChild()
و remove()
، يمكننا إزلة أي عقدة من DOM كما يمكننا استخدام الخاصية innerHTML
لإزالة عقدة ابن من العنصر الأب من خلال استبدال الابن بسلسلة نصية فارغة (empty string) بالشكل ""
ولكن هذه الطريقة غير مفضلة في الاستخدام. ملخص تعلمنا في هذه المقالة كيفية استخدام الجافا سكربت لإنشاء عقد وعناصر جديدة ثم إضافتها إلى DOM، واستبدال أو حذف العقد والعناصر الموجودة. وبهذا نكون قد تعلمنا طريقة الوصول إلى عناصر DOM والتنقل بين العقد وتعديلها وبالتالي يمكنك البدء بإنشاء واجهة تطيبق ويب باستخدام الجافا سكربت.
ترجمة -وبتصرف- للمقالة How To Make Changes to the DOM للكاتبة Tania Rascia
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.