لماذا تلتهم JavaScript HTML: أمثلة التعليمات البرمجية

تطوير الويب يتطور باستمرار. في الآونة الأخيرة ، أصبح اتجاه واحد شائعًا ، والذي يتناقض بشكل أساسي مع الفكرة المقبولة بشكل عام حول كيفية تطوير تطبيقات الويب. والبعض لديه آمال كبيرة ، والبعض الآخر يشعر بخيبة أمل. لكل منها أسبابها الخاصة لهذا الأمر ، والذي يصعب شرحه باختصار.



يتكون رمز صفحة الويب بشكل تقليدي من ثلاثة أقسام ، يؤدي كل منها واجباته: يحدد كود HTML البنية والدلالات ، ويحدد كود CSS المظهر ، ويحدد رمز JavaScript سلوكه. في الفرق التي تضم مصممين ومطوري HTML / CSS ومطوري جافا سكريبت ، يعد هذا الفصل طبيعيًا: يحدد المصممون العناصر المرئية وواجهة المستخدم ، ويضع مطورو HTML و CSS هذه العناصر المرئية على صفحة في المتصفح ، ويضيف مطورو JavaScript تفاعل المستخدم إلى ربط كل شيء معًا و "جعله يعمل". يمكن للجميع العمل على مهامهم دون التدخل في كود فئتي المطورين الآخرين. ولكن كل هذا ينطبق على ما يسمى "النمط القديم".

في السنوات الأخيرة ، بدأ مطورو جافا سكريبت في تحديد بنية الصفحة في جافا سكريبت ، وليس بتنسيق HTML (على سبيل المثال ، باستخدام إطار React js ) ، مما يساعد على تبسيط إنشاء وصيانة رمز تفاعل المستخدم. بدون أطر js ، يصبح تطوير مواقع الويب الحديثة أكثر صعوبة. بالطبع ، عندما تخبر شخصًا ما أن كود HTML الذي كتبه يحتاج إلى أن يتم تقسيمه إلى أجزاء وأن يخلط مع جافا سكريبت ، وهو أمر مألوف جدًا له ، يمكن (لأسباب واضحة) إدراك العداء. على الأقل ، سيسأل المحاور لماذا نحتاج إلى هذا على الإطلاق ، وكيف سنستفيد من ذلك.

بصفتي مطور جافا سكريبت في فريق متعدد الوظائف ، يُسألني هذا السؤال أحيانًا ، وغالبًا ما يكون من الصعب بالنسبة لي الإجابة عليه. جميع المواد التي عثرت عليها في هذا الموضوع مكتوبة لجمهور على دراية بجافا سكريبت. وهذا ليس جيدًا جدًا لأولئك المتخصصين حصريًا في HTML و CSS. ولكن من المرجح أن يكون نمط HTML-in-JS (أو أي شيء آخر يوفر نفس الفوائد) مطلوبًا لبعض الوقت ، لذلك أعتقد أن هذا أمر مهم يجب على كل من يشارك في تطوير الويب فهمه.

في هذه المقالة سأقدم أمثلة برمجية لأولئك المهتمين ، لكن هدفي هو شرح هذا النهج بحيث يمكن فهمه بدونهم.

Likbez: HTML و CSS و JavaScript


من أجل زيادة جمهور هذه المقالة إلى أقصى حد ، أود أن أتحدث بإيجاز عن الدور الذي تلعبه هذه اللغات في إنشاء صفحات الويب ، وأي نوع من الفصل بينهما كان موجودًا في البداية. إذا كنت تعرف كل هذا ، يمكنك تخطي هذا القسم.

HTML: للبنية والدلالات


تحدد شفرة HTML (لغة ترميز النص التشعبي) بنية ودلالات المحتوى الذي سيتم وضعه على الصفحة. على سبيل المثال ، يحتوي كود HTML لهذه المقالة على النص الذي تقرأه الآن ، ووفقًا للبنية المحددة ، يتم وضع هذا النص في فقرة منفصلة ، بعد العنوان وقبل لصق CodePen .

على سبيل المثال ، قم بإنشاء صفحة ويب بسيطة بقائمة تسوق:



يمكننا حفظ هذا الرمز في ملف ، وفتحه في متصفح الويب ، وسيعرض المتصفح النتيجة. كما ترى ، كود HTML في هذا المثال عبارة عن صفحة تحتوي على العنوان "قائمة التسوق" (عنصران) ، ومربع نص الإدخال ، وزر "إضافة عنصر" وقائمة من عنصرين ("البيض") و "النفط"). سيقوم المستخدم بإدخال العنوان في متصفح الويب الخاص به ، ثم سيطلب المتصفح رمز HTML هذا من الخادم وتنزيله وعرضه. إذا كانت هناك عناصر بالفعل في القائمة ، فيمكن للخادم إرسال HTML مع عناصر جاهزة ، كما في هذا المثال.

جرب كتابة شيء ما في حقل الإدخال وانقر على الزر "إضافة عنصر". سترى أنه لا شيء يحدث. لا يرتبط الزر بأي كود يمكنه تغيير HTML ، ولا يمكن لـ HTML تغيير أي شيء بمفرده. سنعود إلى هذا في غضون دقيقة.

CSS: لتغيير المظهر


يحدد رمز CSS (أوراق الأنماط المتتالية) مظهر الصفحة. على سبيل المثال ، تحدد CSS في هذه المقالة الخط والتباعد واللون للنص الذي تقرأه.

ربما لاحظت أن مثال قائمة التسوق لدينا يبدو بسيطًا جدًا. لا يسمح HTML بتحديد أشياء مثل المسافات وأحجام الخطوط والألوان. لهذا السبب نستخدم CSS. يمكننا إضافة كود CSS لهذه الصفحة لتزيينها قليلاً:



كما ترى ، غيّر رمز CSS هذا حجم وسمك أحرف النص ، بالإضافة إلى لون الخلفية. يمكن للمطور ، عن طريق القياس ، كتابة قواعد لأسلوبه الخاص ، وسيتم تطبيقها بالتسلسل على أي بنية HTML: إذا أضفنا عناصر أو زر أو عناصر ul إلى هذه الصفحة ، فسيتم تطبيق نفس تغييرات الخط.
لكن الزر Add Item لا يزال لا يفعل شيئًا: هنا نحتاج فقط إلى JavaScript.

جافا سكريبت: لتنفيذ السلوك


تحدد شفرة JavaScript سلوك العناصر التفاعلية أو الديناميكية على الصفحة. على سبيل المثال ، يتم كتابة CodePen باستخدام JavaScript.

لكي يعمل الزر "إضافة عنصر" في مثالنا بدون JavaScript ، نحتاج إلى استخدام رمز HTML خاص لإجباره على إرسال البيانات مرة أخرى إلى الخادم ( <form action \ u003d '...'> إذا كنت مهتمًا فجأة). علاوة على ذلك ، سيقوم المتصفح بإعادة تحميل النسخة المحدثة من ملف HTML بالكامل دون حفظ الحالة الحالية للصفحة. إذا كانت قائمة التسوق هذه جزءًا من صفحة ويب كبيرة ، فسيتم فقد كل شيء فعله المستخدم. لا يهم عدد وحدات البكسل التي انتقلت إليها أثناء قراءة النص - عند إعادة تشغيل الخادم سيعيدك إلى البداية ، لا يهم عدد دقائق الفيديو التي شاهدتها - عند إعادة التشغيل ، سيبدأ مرة أخرى.

هذه هي الطريقة التي كانت تعمل بها جميع تطبيقات الويب: في كل مرة تفاعل فيها المستخدم مع صفحة الويب ، بدا أنه يغلق متصفح الويب الخاص به ويفتحه مرة أخرى. لا يهم هذا كثيرًا في دراسة حالة بسيطة ، ولكن بالنسبة لصفحة معقدة كبيرة ، والتي قد تستغرق بعض الوقت للتحميل ، فإن هذا الأسلوب غير فعال سواء للمتصفح أو الخادم.

إذا أردنا تغيير شيء ما على الصفحة دون إعادة تحميل هذه الصفحة بالكامل ، فنحن بحاجة إلى استخدام جافا سكريبت:



الآن ، عندما نكتب النص في حقل الإدخال وننقر فوق الزر إضافة عنصر ، تتم إضافة العنصر الجديد إلى القائمة ويتم تحديث عدد العناصر في الأعلى! في تطبيق حقيقي ، نضيف أيضًا بعض التعليمات البرمجية لإرسال عنصر جديد إلى الخادم في الخلفية بحيث يظهر في المرة التالية التي يتم فيها تحميل الصفحة.

هناك ما يبرر فصل جافا سكريبت عن HTML و CSS حتى في هذا المثال البسيط. تعمل التفاعلات الأكثر تعقيدًا على النحو التالي: يتم تحميل HTML وعرضه ، ويتم بعد ذلك تشغيل JavaScript لإضافة شيء إليه وتغييره. ومع ذلك ، مع تزايد تعقيد تطبيق الويب ، نحتاج إلى مراقبة ما وأين ومتى يتغير رمز JavaScript بعناية.

إذا واصلنا تطوير هذا التطبيق باستخدام قائمة تسوق ، فقد نضيف أزرارًا لتعديل أو إزالة العناصر من القائمة. لنفترض أننا نكتب رمز JavaScript لزر يحذف عنصرًا ، ولكن ننسى إضافة رمز يحدِّث معلومات حول العدد الإجمالي للعناصر في أعلى الصفحة. فجأة ، حصلنا على خطأ: بعد أن يحذف المستخدم العنصر ، لن يتطابق الرقم الإجمالي المشار إليه في الصفحة مع القائمة!

بمجرد ملاحظة الخطأ ، قمنا بإصلاحه عن طريق إضافة نفس سطر totalText.innerHTML من الكود الخاص بنا لإضافة عنصر إلى رمز إزالة العنصر. الآن لدينا نفس الرمز ، والذي يتم نسخه في عدة أماكن. بعد ذلك ، لنفترض أننا نريد تغيير هذا الرمز بحيث يعرض "العناصر: 2" بدلاً من "(عنصران)" في أعلى الصفحة. يجب أن نتأكد من أننا لا ننسى تحديث هذا الرمز في جميع الأماكن الثلاثة: في HTML ، في رمز JavaScript للزر Add Item وفي رمز JavaScript للزر Remove Item. إذا لم نفعل ذلك ، فسيكون لدينا خطأ آخر ، والذي سيتغير بسببه هذا النص بشكل كبير بعد التفاعل مع المستخدم.

بالفعل في هذا المثال البسيط ، نرى مدى سهولة الخلط في التعليمات البرمجية. بالطبع بكل تأكيد. هناك طرق وممارسات لتبسيط تعليمات JavaScript البرمجية لتسهيل حل هذه المشكلة. ومع ذلك ، عندما تصبح الأمور أكثر تعقيدًا ، سيتعين علينا مواصلة إعادة الهيكلة وإعادة كتابة المشروع باستمرار حتى يمكن تطويره وصيانته بسهولة. بينما يتم تخزين HTML وجافا سكريبت بشكل منفصل ، يمكن أن يستغرق الأمر الكثير من الجهد لضمان المزامنة بينهما. هذا هو أحد الأسباب التي جعلت أطر JavaScript الجديدة مثل React شائعة: فهي مصممة لتوفير علاقة أكثر رسمية وفعالية بين HTML و JavaScript. لفهم كيفية عمل ذلك ، نحتاج أولاً إلى التعمق قليلاً في علوم الكمبيوتر.

البرمجة الإلزامية مقابل


الشيء الرئيسي الذي يجب فهمه هو الاختلاف في التفكير. تسمح لك معظم لغات البرمجة بمتابعة نموذج واحد فقط ، على الرغم من أن بعضها يدعم لغتين في وقت واحد. من المهم فهم كلا النموذجين من أجل تقدير الميزة الرئيسية لـ HTML-in-JS من وجهة نظر مطور JavaScript.

  • . «» , . ( ) : , , . , , . - «». Vanilla JavaScript , jQuery. JavaScript .
    • « X, Y, Z».
    • : , .selected; , .selected.

  • . , . , , «» (), , - . , . (, React), , , . , , , , . , :
    • « XYZ. , , .
    • مثال: يحتوي هذا العنصر على فئة مختارة. إذا اختارها المستخدم.


HTML هي لغة تعريفية


ننسى جافا سكريبت للحظة. إليك حقيقة مهمة: HTML هي لغة تعريفية. في ملف HTML ، يمكنك التصريح عن شيء مثل:

<section>
  <h1>Hello</h1>
  <p>My name is Mike.</p>
</section>

عندما يقرأ متصفح الويب شفرة HTML هذه ، سيحدد بشكل مستقل الخطوات اللازمة ويقوم بها:

  1. قم بإنشاء عنصر قسم .
  2. إنشاء عنصر رأس المستوى 1 ( h1 ).
  3. اضبط نص عنصر العنوان على "مرحبًا".
  4. ضع عنصر العنوان في عنصر القسم.
  5. إنشاء عنصر فقرة ( ع ).
  6. اضبط نص عنصر الفقرة على "اسمي مايك".
  7. ضع عنصر فقرة في عنصر القسم .
  8. ضع عنصر القسم في مستند HTML.
  9. اعرض الوثيقة على الشاشة.

بالنسبة لمطور الويب ، لا يهم تمامًا كيف يفعل المتصفح هذه الأشياء: كل ما يهم هو ما يفعله. هذا مثال رائع لتوضيح الفرق بين نموذجي البرمجة. باختصار ، HTML عبارة عن تجريد إعلاني ملفوف حول محرك عرض مستعرض ويب تم تطبيقه بشكل حتمي. يهتم بكيفية ذلك ، ما عليك سوى القلق بشأن ما. يمكنك الاستمتاع بالحياة أثناء كتابة HTML الإعلاني لأن الأشخاص الطيبين من Mozilla و Google و Apple كتبوا رمزًا ضروريًا لك عند إنشاء متصفح الويب الخاص بك.

JavaScript هي لغة حتمية


لقد درسنا بالفعل مثالًا بسيطًا لجافا سكريبت الحتمية في مثال قائمة التسوق أعلاه ، وقد وصفت كيف يؤثر تعقيد وظائف التطبيق على الجهد المطلوب لتنفيذها واحتمال حدوث أخطاء في هذا التطبيق.

الآن دعونا نلقي نظرة على مهمة أكثر تعقيدًا قليلاً ونرى كيف يمكن تبسيطها باستخدام نهج تعريفي. تخيل صفحة ويب تحتوي على ما يلي:

  • قائمة بالأعلام التي تم وضع علامة عليها ، يتغير لون كل سطر عند تحديدها ؛
  • النص أدناه ، على سبيل المثال ، "1 من 4 تم تحديده" ، والذي يجب تحديثه عند تغيير العلامات ؛
  • حدد زر الكل ، الذي يجب تعطيله إذا تم تحديد جميع مربعات الاختيار بالفعل ؛
  • حدد زر بلا ، والذي يجب تعطيله إذا لم يتم تحديد مربعات الاختيار.

في ما يلي تطبيق بلغة HTML و CSS وجافا سكريبت الأساسية:



const captionText = document.getElementById('caption-text');
const checkAllButton = document.getElementById('check-all-button');
const uncheckAllButton = document.getElementById('uncheck-all-button');
const checkboxes = document.querySelectorAll('input[type="checkbox"]');

function updateSummary() {
  let numChecked = 0;
  checkboxes.forEach(function(checkbox) {
    if (checkbox.checked) {
      numChecked++;
    }
  });
  captionText.innerHTML = `${numChecked} of ${checkboxes.length} checked`;
  if (numChecked === 0) {
    checkAllButton.disabled = false;
    uncheckAllButton.disabled = true;
  } else {
    uncheckAllButton.disabled = false;
  }
  if (numChecked === checkboxes.length) {
    checkAllButton.disabled = true;
  }
}

checkAllButton.addEventListener('click', function() {
  checkboxes.forEach(function(checkbox) {
    checkbox.checked = true;
    checkbox.closest('tr').className = 'checked';
  });
  updateSummary();
});

uncheckAllButton.addEventListener('click', function() {
  checkboxes.forEach(function(checkbox) {
    checkbox.checked = false;
    checkbox.closest('tr').className = '';
  });
  updateSummary();
});

checkboxes.forEach(function(checkbox) {
  checkbox.addEventListener('change', function(event) {
    checkbox.closest('tr').className = checkbox.checked ? 'checked' : '';
    updateSummary();
  });
});

الصداع كما هو


لتنفيذ هذه الوظيفة باستخدام جافا سكريبت ، نحتاج إلى إعطاء المتصفح بعض الإرشادات التفصيلية. هذا وصف شفهي للرمز من المثال أعلاه.
في HTML لدينا ، نعلن بنية الصفحة الأصلية:
  • هناك أربعة عناصر صف (صف جدول ، قائمة) ، يحتوي كل منها على علامة. يتم التحقق من العلم الثالث.
  • يوجد نص "تم تحديد 1 من 4".
  • يوجد زر تحديد الكل قيد التشغيل.
  • يوجد زر تحديد بلا ، وهو معطل.

في JavaScript الخاصة بنا ، نكتب تعليمات حول ما يجب تغييره عند حدوث كل من هذه الأحداث:
عندما تتغير علامة من علامة غير مميزة إلى علامة:
  • ابحث عن الصف الذي يحتوي على مربع الاختيار وأضف فئة CSS المحددة إليه.
  • ابحث عن جميع العلامات في القائمة واحسب عدد العلامات المميزة وعددها.
  • ابحث عن النص وقم بتحديثه ، مع الإشارة إلى العدد الصحيح لعمليات الشراء المحددة وعددها الإجمالي.
  • ابحث عن زر تحديد بلا وقم بتشغيله إذا تم تعطيله.
  • إذا تم تحديد جميع مربعات الاختيار الآن ، فابحث عن الزر تحديد الكل وقم بإيقاف تشغيله.

عندما تتغير العلامة من علامة إلى غير مميزة:
  • ابحث عن الصف الذي يحتوي على العلم وأزل الفئة المحددة منه.
  • ابحث عن جميع مربعات الاختيار في القائمة واحسب عددها المحددة وعددها.
  • ابحث عن عنصر نص السيرة الذاتية وقم بتحديثه برقم تم التحقق منه وإجمالي.
  • ابحث عن الزر تحديد الكل وقم بتشغيله إذا تم تعطيله.
  • إذا كانت جميع المربعات غير محددة ، فابحث عن الزر تحديد بدون إيقاف تشغيل وإيقاف تشغيله.

عند الضغط على زر تحديد الكل:
  • ابحث عن جميع مربعات الاختيار في القائمة وضع علامة عليها.
  • ابحث عن جميع الصفوف في القائمة وأضف الفئة المحددة لها.
  • ابحث عن النص وقم بتحديثه.
  • ابحث عن الزر تحديد الكل وقم بإيقاف تشغيله.
  • ابحث عن زر تحديد بلا وقم بتشغيله.

عند الضغط على زر تحديد بلا:
  • ابحث عن جميع مربعات الاختيار في القائمة وامسح جميع مربعات الاختيار.
  • ابحث عن جميع الصفوف في القائمة وأزل الفئة المحددة منها.
  • ابحث عن عنصر نص السيرة الذاتية وقم بتحديثه.
  • ابحث عن الزر تحديد الكل وقم بتشغيله.
  • ابحث عن زر تحديد بلا وقم بإيقاف تشغيله.

واو ... هذا كثير ، أليس كذلك؟ حسنًا ، من الأفضل ألا ننسى كتابة رمز لجميع المواقف المحتملة. إذا نسينا أو أخطأنا في تنفيذ أي من هذه التعليمات ، فسوف نحصل على خطأ: لن تتطابق الإجماليات مع مربعات الاختيار ، أو سيتم تشغيل الزر الذي لا يفعل شيئًا عند النقر عليه ، أو سيحصل الصف المحدد على لون أو شيء خاطئ حتى الآن ، والتي لم نفكر فيها ولن نعرف حتى يشكو المستخدم.

لدينا بالفعل مشكلة كبيرة هنا: لا يوجد كيان يحتوي على معلومات كاملة عن الدولةمن طلبنا (في هذه الحالة ، هذا هو الجواب على السؤال "ما هي العلامات المميزة؟") وسيكون مسؤولاً عن تحديث هذه المعلومات. بالطبع ، تعرف العلامات إذا تم التحقق منها ، ولكن يجب أيضًا أن يكون رمز CSS لصفوف الجدول والنص وكل زر على علم بذلك. يتم تخزين خمس نسخ من هذه المعلومات بشكل منفصل في جميع أنحاء HTML ، وعندما تتغير في أي من هذه الأماكن ، يجب على مطور جافا سكريبت التقاط هذا وكتابة التعليمات البرمجية الضرورية للمزامنة مع التغييرات في أماكن أخرى.

ولا يزال هذا مثالًا بسيطًا على مكون صفحة صغيرة. حتى إذا كانت هذه المجموعة من التعليمات تبدو وكأنها صداع ، فتخيل مدى تعقيد وهشاشة تطبيق الويب الأكبر عندما تحتاج إلى تنفيذ كل هذا في جافا سكريبت. بالنسبة للعديد من تطبيقات الويب الحديثة والمعقدة ، لا يتغير هذا الحل من كلمة "تمامًا".

نحن نبحث عن مصدر الحقيقة


أدوات مثل React تسمح بالاستخدام التعريفي لجافا سكريبت. تمامًا كما أن HTML عبارة عن تجريد تعريفي حول تعليمات العرض في متصفح الويب ، فإن React هو تجريد تعريفي عبر JavaScript.

تذكر كيف تسمح لنا HTML بالتركيز على بنية الصفحة بدلاً من تفاصيل التنفيذ ، وكيف يعرض المستعرض هذه البنية؟ وبالمثل ، عندما نستخدم React ، يمكننا التركيز على البنية ، وتعريفها بناءً على البيانات المخزنة في مكان واحد. تسمى هذه العملية ربط أحادي الاتجاه ، ويطلق على موقع بيانات حالة التطبيق "المصدر الوحيد للحقيقة". عندما يتغير مصدر الحقيقة ، سيقوم React تلقائيًا بتحديث بنية الصفحة لنا. سيهتم بالخطوات المطلوبة وراء الكواليس ، كما يفعل متصفح الويب لـ HTML. على الرغم من استخدام React كمثال هنا ، يعمل هذا النهج أيضًا مع أطر أخرى مثل Vue.

دعنا نعود إلى قائمة خانات الاختيار الخاصة بنا من المثال أعلاه. في هذه الحالة ، "الحقيقة" التي نريد أن نعرفها موجزة إلى حد ما: ما هي العلامات التي يتم التحقق منها؟ التفاصيل الأخرى (على سبيل المثال ، النص ولون الخطوط والأزرار التي يتم تشغيلها) هي بالفعل معلومات تم الحصول عليها على أساس مصدر الحقيقة. ولماذا يجب أن يكون لديهم نسختهم الخاصة من هذه المعلومات؟ يجب عليهم ببساطة استخدام مصدر واحد للحقيقة للقراءة فقط ، ويجب على جميع عناصر الصفحة "مجرد معرفة" مربعات الاختيار المحددة والتصرف وفقًا لذلك. يمكنك القول أن صفوف الجدول والنص والأزرار يجب أن تكون قادرة على الاستجابة تلقائيًا لمربع اختيار بناءً على ما إذا كانت محددة أو غير محددة ("انظر ماذا يحدث هناك؟")

أخبرني بما تريد (ما تريده حقًا)


لتنفيذ هذه الصفحة باستخدام React ، يمكننا استبدال القائمة ببعض أوصاف الحقائق البسيطة:

  • توجد قائمة بالقيم true / false تسمى checkboxValues ​​التي تعرض الحقول التي تم وضع علامة عليها.
    • مثال: checkboxValues ​​\ u003d [false، false، true، false]
    • تظهر هذه القائمة أن لدينا أربعة أعلام ، يتم تعيين الثالث فقط.

  • لكل قيمة في خانة اختيار القيم الموجودة في الجدول ، هناك صف:
    • لديه فئة CSS تسمى .selected إذا كانت القيمة صحيحة ، و
    • يحتوي على علامة تم التحقق منها إذا كانت القيمة صحيحة.

  • هناك عنصر نصي يحتوي على النص "{x} من {y} selected" ، حيث {x} هو عدد القيم الحقيقية في checkboxValues ​​و {y} هو إجمالي عدد القيم في checkboxValues.
  • يوجد زر تحديد الكل الذي يتم تمكينه إذا كانت قيم خانة الاختيار قيمًا زائفة.
  • Select None, , checkboxValues ​​ true.
  • , checkboxValues.
  • Select All , checkboxValues ​​ true.
  • Select None checkboxValues ​​ false.

ستلاحظ أن الفقرات الثلاث الأخيرة لا تزال تعليمات ضرورية ("عندما يحدث ذلك ، افعل ذلك") ، ولكن هذا هو الرمز الأساسي الوحيد الذي نحتاج إلى كتابته. هذه ثلاثة أسطر من التعليمات البرمجية ، وكلها تقوم بتحديث مصدر واحد للحقيقة.

والباقي عبارة عن عبارات تعريفية ("هناك ...") ، وهي الآن مضمنة مباشرة في تعريف بنية الصفحة. للقيام بذلك ، نكتب التعليمات البرمجية لعناصرنا باستخدام ملحق بناء JavaScript خاص - JavaScript XML (JSX). يشبه HTML: يسمح لك JSX باستخدام بناء جملة يشبه HTML لوصف بنية الواجهة ، بالإضافة إلى JavaScript العادي. هذا يسمح لنا بخلط منطق JS مع بنية HTML ، بحيث يمكن أن تكون البنية مختلفة في أي وقت. كل هذا يتوقف على محتويات قيم خانة الاختيار.

نعيد كتابة مثالنا على React:



function ChecklistTable({ columns, rows, initialValues, ...otherProps }) {
  const [checkboxValues, setCheckboxValues] = React.useState(initialValues);
  
  function checkAllBoxes() {
    setCheckboxValues(new Array(rows.length).fill(true));
  }
  
  function uncheckAllBoxes() {
    setCheckboxValues(new Array(rows.length).fill(false));
  }
  
  function setCheckboxValue(rowIndex, checked) {
    const newValues = checkboxValues.slice();
    newValues[rowIndex] = checked;
    setCheckboxValues(newValues);
  }
  
  const numItems = checkboxValues.length;
  const numChecked = checkboxValues.filter(Boolean).length;
  
  return (
    <table className="pf-c-table pf-m-grid-lg" role="grid" {...otherProps}>
      <caption>
        <span>{numChecked} of {numItems} items checked</span>
        <button
          onClick={checkAllBoxes}
          disabled={numChecked === numItems}
          className="pf-c-button pf-m-primary"
          type="button"
        >
          Check all
        </button>
        <button
          onClick={uncheckAllBoxes}
          disabled={numChecked === 0}
          className="pf-c-button pf-m-secondary"
          type="button"
        >
          Uncheck all
        </button>
      </caption>
      <thead>
        <tr>
          <td />
          {columns.map(function(column) {
            return <th scope="col" key={column}>{column}</th>;
          })}
        </tr>
      </thead>
      <tbody>
        {rows.map(function(row, rowIndex) {
          const [firstCell, ...otherCells] = row;
          const labelId = `item-${rowIndex}-${firstCell}`;
          const isChecked = checkboxValues[rowIndex];
          return (
            <tr key={firstCell} className={isChecked ? 'checked' : ''}>
              <td className="pf-c-table__check">
                <input
                  type="checkbox"
                  name={firstCell}
                  aria-labelledby={labelId}
                  checked={isChecked}
                  onChange={function(event) {
                    setCheckboxValue(rowIndex, event.target.checked);
                  }}
                />
              </td>
              <th data-label={columns[0]}>
                <div id={labelId}>{firstCell}</div>
              </th>
              {otherCells.map(function(cell, cellIndex) {
                return (
                  <td key={cell} data-label={columns[1 + cellIndex]}>
                    {cell}
                  </td>
                );
              })}
            </tr>
          );
        })}
      </tbody>
    </table>
  );
};

function ShoppingList() {
  return (
    <ChecklistTable
      aria-label="Shopping list"
      columns={['Item', 'Quantity']}
      rows={[
        ['Sugar', '1 cup'],
        ['Butter', '½ cup'],
        ['Eggs', '2'],
        ['Milk', '½ cup'],
      ]}
      initialValues={[false, false, true, false]}
    />
  );
}

ReactDOM.render(
  <ShoppingList />,
  document.getElementById('shopping-list')
);


JSX تبدو غريبة. عندما واجهت هذا لأول مرة ، بدا لي أنه ببساطة كان من المستحيل القيام بذلك. كان رد فعلي الأولي: "ماذا؟ لا يمكن أن يكون HTML داخل رمز JavaScript! " ولم أكن الوحيد. ومع ذلك ، هذا ليس HTML ، ولكن جافا سكريبت ترتدي HTML. في الواقع ، هذا حل قوي.

هل تتذكر تلك التعليمات العشرين الحتمية أعلاه؟ الآن لدينا ثلاثة منهم. بقية التعليمات (الداخلية) الملحة تتفاعل شركة React نفسها من أجلنا وراء الكواليس - في كل مرة تتغير قيم خانة الاختيار.

باستخدام هذا الرمز ، لا يمكن أن يحدث الموقف عندما لا يتطابق نص أو لون الخط مع مربعات الاختيار ، أو عندما يكون الزر قيد التشغيل ، على الرغم من أنه يجب تعطيله. هناك فئة كاملة من الأخطاء التي لا يمكن أن تحدث ببساطة في تطبيق الويب الخاص بنا. تتم جميع الأعمال على أساس مصدر واحد للحقيقة ، ويمكننا نحن المطورين كتابة كود أقل والنوم بشكل أفضل في الليل. حسنًا ، مطورو جافا سكريبت ، على الأقل ...

جافا سكريبت هزم HTML: جوعا


مع زيادة تعقيد تطبيقات الويب ، أصبح الحفاظ على الفصل الكلاسيكي للمهام بين HTML و JavaScript أكثر إيلامًا. تم تصميم HTML في الأصل لصفحات الويب الثابتة. لإضافة وظائف تفاعلية أكثر تعقيدًا هناك ، من الضروري تنفيذ المنطق المناسب في جافا سكريبت الحتمية ، والذي يصبح مع كل سطر من التعليمات البرمجية أكثر إرباكًا وهشاشة.

مزايا النهج الحديث: القدرة على التنبؤ ، وإعادة الاستخدام والجمع


تعد القدرة على استخدام مصدر واحد للحقيقة أهم ميزة لهذا النموذج ، ولكن له مزايا أخرى. يعني تعريف عناصر صفحتنا في شفرة JavaScript أنه يمكننا إعادة استخدام المكونات (كتل فردية لصفحة ويب) ، مما يمنعنا من نسخ ولصق نفس شفرة HTML في عدة أماكن. إذا احتجنا إلى تغيير أحد المكونات ، فما عليك سوى تغيير رمزه في مكان واحد فقط. في هذه الحالة ، ستحدث تغييرات في جميع نسخ المكون (داخل واحد أو حتى في العديد من تطبيقات الويب ، إذا استخدمنا مكونات قابلة لإعادة الاستخدام فيها).

يمكننا أن نأخذ مكونات بسيطة ونجمعها معًا مثل مكعبات LEGO ، وننشئ مكونات أكثر تعقيدًا ومفيدة دون جعل منطقها مربكًا للغاية. وإذا استخدمنا مكونات تم إنشاؤها بواسطة مطورين آخرين ، فيمكننا بسهولة تحديث التحديثات أو إصلاح الأخطاء دون الحاجة إلى إعادة كتابة التعليمات البرمجية الخاصة بنا.

نفس جافا سكريبت ، في ملف التعريف فقط


هذه الفوائد لها جانب سلبي. هناك أسباب وجيهة تجعل الناس يقدرون الفصل بين HTML و JavaScript. كما ذكرت سابقًا ، يؤدي التخلي عن ملفات HTML العادية إلى تعقيد سير العمل لشخص لم يعمل مع JavaScript من قبل. أولئك الذين كان بإمكانهم في السابق إجراء تغييرات بشكل مستقل على تطبيق الويب ، يجب عليهم الآن اكتساب مهارات معقدة إضافية من أجل الحفاظ على استقلاليتهم ، أو حتى وضعهم في الفريق.

هناك أيضا عيوب فنية. على سبيل المثال ، بعض الأدوات ، مثل linters و parsers ، تقبل فقط HTML العادي كإدخال ، وقد يكون العمل مع مكونات JavaScript الإضافية الخارجية أكثر صعوبة بدلاً من ذلك. بالإضافة إلى ذلك ، ليست JavaScript هي أفضل لغة ، لكنها معيار موحد مقبول لمتصفحات الويب. الأدوات والميزات الجديدة تجعلها أفضل ، ولكن لا تزال هناك بعض المزالق التي تحتاج إلى معرفتها قبل العمل معها.

مشكلة أخرى محتملة: عندما يتم تقسيم البنية الدلالية للصفحة إلى مكونات مجردة ، قد يتوقف المطور عن التفكير في عناصر HTML التي سيتم إنشاؤها نتيجة لذلك. علامات HTML محددة مثل القسم والجانب، لها دلالات خاصة بها ، يتم فقدها عند استخدام علامات للأغراض العامة مثل div و span - حتى لو كانت تبدو بصريًا بنفس الشكل على الصفحة. هذا مهم بشكل خاص لضمان توفر تطبيق الويب لفئات مختلفة من المستخدمين.

على سبيل المثال ، سيؤثر هذا على سلوك قارئ الشاشة للمستخدمين ضعاف البصر. ربما هذه ليست معظم المهام مثيرة للاهتمام للمطور، ولكن يجب على مطوري جافا سكريبت نتذكر دائما أن الحفاظ على دلالات HTML في هذه الحالة هو أهم مهمة .

الحاجة الواعية مقابل الاتجاه اللاواعي


في الآونة الأخيرة ، أصبح استخدام الأطر في كل مشروع اتجاهًا. يعتقد بعض الناس أن الفصل بين HTML و JavaScript قديم ، ولكنه ليس كذلك. بالنسبة لموقع ويب ثابت بسيط لا يتطلب تفاعل مستخدم معقد ، فهذا صحيح تمامًا. قد يختلف معجبي رد الفعل المتحمسين معي هنا ، ولكن إذا كان كل ما تفعله جافا سكريبت هو إنشاء صفحة ويب غير تفاعلية ، فلا يجب استخدامها. لا يتم تحميل جافا سكريبت بسرعة HTML العادي. لذلك ، إذا لم تقم بتعيين المهمة لاكتساب خبرة تطوير جديدة أو تحسين موثوقية الكود ، فإن JavaScript هنا سوف تضر أكثر مما تنفع.

بالإضافة إلى ذلك ، ليست هناك حاجة لكتابة موقع الويب الخاص بك بالكامل في React. أو فيو! أو ماذا يوجد أيضًا ... كثير من الناس لا يعرفون ذلك ، لأن جميع البرامج التعليمية توضح بشكل أساسي كيفية استخدام React لتطوير موقع من البداية. إذا كان لديك عنصر واجهة تعقيد صغير واحد فقط على موقع ويب بسيط ، يمكنك استخدام React لمكون واحد . لا داعي للقلق دائمًا بشأن حزمة الويب أو Redux أو Gatsby أو أي شيء آخر يوصي به أحد الأشخاص باعتباره "أفضل الممارسات" هناك.

ولكن إذا كان التطبيق معقدًا تمامًا ، فإن استخدام نهج إعلاني حديث يستحق ذلك تمامًا. هل رد الفعل هو الحل الأفضل؟ لا. لديه بالفعل منافسين أقوياء. وبعد ذلك سيظهر المزيد والمزيد ... لكن البرمجة التصريحية لن تذهب إلى أي مكان ، وفي إطار جديد جديد ، ربما سيتم إعادة التفكير في هذا النهج وتطبيقه بشكل أفضل.


All Articles