اذهب إلى المحتوى

تحدثنا في مقالتين سابقتين عن طريقة الوصول إلى العناصر في 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

وعند تحميل الملف السابق إلى المتصفح فإنه سيبدو بالشكل:

01.png

الآن سنقوم بإضافة عنصر جديد إلى نهاية قائمة المهام، وللقيام بذلك سننشئ عنصرًا ونضيف له نصًّا كما فعلنا في المقطع السابق:

> // ليمثل قائمة المهام 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>

02.png

قد نحتاج لإضافة مهمة جديدة إلى القائمة ولكنها على رأس الأولويات، وبالتالي نحتاج لإضافتها في رأس القائمة. وللقيام بذلك، سنبدأ أولًا بإنشاء عنصر من خلال التابع 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>

وعند تحميل الملف السابق على المتصفح سيظهر كمايلي:

03.png

إذًا تمت إضافة العقدة الجديدة بنجاح لبداية القائمة، وهكذا نكون قد تعلمنا كيفية إضافة عقدة ابن لعقدة أب ولكن يمكننا أيضًا استبدال هذه العقدة الموجودة بعقدة جديدة.

لتعديل عقدة موجودة في قائمة المهام، سننشئ أولًا عنصرًا جديدًا:

> 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>

ويصبح شكل صفحة الويب:

04.png

باستخدام توابع 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>

05.png

الآن سنستخدم التابع الآخر وهو 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>

06.png

باستخدام التابعين removeChild()‎ و remove()‎، يمكننا إزلة أي عقدة من DOM كما يمكننا استخدام الخاصية innerHTML لإزالة عقدة ابن من العنصر الأب من خلال استبدال الابن بسلسلة نصية فارغة (empty string) بالشكل "" ولكن هذه الطريقة غير مفضلة في الاستخدام. ملخص تعلمنا في هذه المقالة كيفية استخدام الجافا سكربت لإنشاء عقد وعناصر جديدة ثم إضافتها إلى DOM، واستبدال أو حذف العقد والعناصر الموجودة. وبهذا نكون قد تعلمنا طريقة الوصول إلى عناصر DOM والتنقل بين العقد وتعديلها وبالتالي يمكنك البدء بإنشاء واجهة تطيبق ويب باستخدام الجافا سكربت.

ترجمة -وبتصرف- للمقالة How To Make Changes to the DOM للكاتبة Tania Rascia


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...