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

تعرّف على أساسيات لغة جافا سكريبت من منظور عام


ابراهيم الخضور

سنلقي نظرة في هذا المقال على جافا سكريبت JavaScript من منظور عام ونجيب على أسئلة مثل "ما هي جافا سكريبت؟" و "ماذا تفعل هذه اللغة؟" لنتأكد أنك تملك الفهم الجيد لهذه اللغة بالعموم قبل الغوص في التفاصيل الأكثر تعقيدًا.

لن تحتاج أية معرفة مسبقة بلغة جافا سكربت لتتابع معنا، لكن عليك قبل البدء بقراءة هذا المقال أن تمتلك بعض المعرفة بالأمور التالية:

  1. معرفة ببعض أساسيات HTML و CSS، لهذا ننصحك بالاطلاع على بعض المقالات السابقة مثل:
  2. أساسيات HTML.
  3. أساسيات عمل CSS.
  4. عالم الويب ومعاييره.

ملاحظة: إن كنت تعمل على حاسوب أو جهاز لوحي أو أجهزة أخرى لا تسمح لك بإنشاء ملفات خاصة بك، يمكن تجريب معظم الأمثلة والشيفرات ضمن محرر برمجي عبر الإنترنت مثل JSBin أو Glitch.

ما هي لغة جافا سكريبت

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

01 three layers of web cake

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

تُبنى هذه الطبقات فوق بعضها بأناقة، ولنأخذ عنوان نصي بسيط كمثال. سنوصّف ذلك من خلال لغة HTML التي تعطيه الشكل وتصف الغاية منه:

<p>Player 1: Chris</p>

02 simple html struct

يمكننا بعد ذلك إضافة بعض تنسيقات CSS لكي نحسّن المظهر:

p {
  font-family: "helvetica neue", helvetica, sans-serif;
  letter-spacing: 1px;
  text-transform: uppercase;
  text-align: center;
  border: 2px solid rgb(0 0 200 / 0.6);
  background: rgb(0 0 200 / 0.6);
  color: rgb(255 255 255 / 1);
  box-shadow: 1px 1px 2px rgb(0 0 200 / 0.4);
  border-radius: 10px;
  padding: 3px 10px;
  display: inline-block;
  cursor: pointer;
}

03 simple css style

وأخيرًا يمكننا إعطاء ديناميكية للصفحة بإضافة شيفرة جافا سكريبت بسيطة على النحو التالي:

const para = document.querySelector("p");

para.addEventListener("click", updateName);

function updateName() {
  const name = prompt("Enter a new name");
  para.textContent = `Player 1: ${name}`;
}

جرّب أن تنقر على العنوان النصي بنسخته الأخيرة وراقب ما سيحدث.

ما تفعله جافا سكريبت حقيقة أكثر من ذلك بكثير، سنستعرض ذلك بتفاصيل أوفى في الفقرات التالية.

ما الذي تستطيعه جافا سكريبت حقيقةً؟

تتكون لغة جافا سكريبت التي تعمل من ناحية العميل من بعض الميزات البرمجية البنيوية التي تسمح لك بتنفيذ الكثير من الأشياء مثل:

  • تخزين قيم مهمة ضمن المتغيرات. فما فعلناه في المثال السابق مثلًا أننا طلبنا إدخال اسم جديد ثم خزّنا القيمة المُدخلة في متغيّر سميناه name.
  • العمل على جزء من نص وهو ما يعرف برمجيًا بالسلسلة النصية String فإذ أخذنا في المثال السابق السلسلة النصية " :Player1" وأضفنا إليها قيمة المتغيّر name  يمكننا إنشاء عنوان نصي كامل مثل "Player 1: Chris".
  • تنفيذ شيفرة برمجية استجابةً لحدث معين يقع في صفحة الويب، فقد استخدمنا في المثال السابق الحدث click لالتقاط عملية النقر على العنوان النصي ومن ثم نفذنا الشيفرة التي تُحدّث العنوان بعد إضافة الاسم عليه.
  • وهناك الكثير من الأشياء التي تقوم بها لغة جافا سكريبت أيضًا!

ولعل أكثر الأمور إثارة، هي القدرة الوظيفية الكبيرة لهذه اللغة من طرف العميل والتي تُعرف بواجهة التطبيق البرمجية Application programming Interface واختصارًا API والتي تعطي قوة كبيرة في استخدام الشيفرة.

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

وتصنّف واجهات API عمومًا ضمن فئتين أساسيتين:

  1. واجهات API الخاصة بالمتصفح
  2. واجهات API يقدمها طرف آخر  Third party API

04 categories of api

وسنشرح تاليًا آلية عمل كل منهما بمزيد من التفصيل.

واجهات API الخاصة بالمتصفح

وهي برمجيات مدمجة في بنية المتصفح، قادرة على التعامل مع البيانات في البيئة الحاسوبية أو أن تقوم ببعض العمليات المعقدة المفيدة مثل:

  • واجهة DOM (أو DOM API) وتسمح بالتعامل مع ملفات HTML و CSS كإنشاء وحذف وتغيير شيفرات HTML ديناميكيًا وتطبيق تنسيقات جديدة، فكل مرة ترى فيها نافذة منبثقة تُعرض على المتصفح أو ظهور محتوى جديد في الصفحة هي من فعل واجهة DOM.
  • واجهة الموقع الجغرافي (Geolocation API)  تستخلص برمجيات الواجهة معلومات جغرافية عن موقعك، لهذا يستطيع تطبيق خرائط جوجل العثور على موقعك وإظهاره على الخريطة.
  • واجهتا canvas و webGL: اللتان تساعدانك على إنشاء رسومات متحركة ثنائية وثلاثية الأبعاد، وتستطيع تنفيذ أشياء رائعة باستخدامهما.
  • واجهات الفيديو والصوتيات مثل HTMLMediaElement و WebRTC: التي تسمح لك بتنفيذ أشياء مميزة مع الوسائط المتعددة مثل تشغيل مقاطع الصوت والفيديو في صفحة الويب مباشرة أو التقاط بث كاميرا الويب وعرضها على حاسوب آخر.

ملاحظة: يُفضّل عند تجريب استخدام الواجهات البرمجية استخدام متصفحات حديثة مثل فايرفوكس أو كروم أو إيدج أو أوبيرا. كما عليك الأخذ بعين الاعتبار فكرة اختبار الشيفرة على اكثر من متصفح وخاصة عند الوصول إلى مرحلة تسليم شيفرة الإنتاج بعد إنهاء الشيفرة التجريبية.

واجهات API يقدمها طرف ثالث

لا تُبنى هذه الواجهات ضمن المتصفح افتراضيًا، وعادة ما تحصل على شيفرتها من الويب. ومن الأمثلة عليها

  • واجهة تويتر Twitter API: وتسمح لك بعرض آخر تغريداتك ضمن موقع الويب الخاص بك مثلًا وغيرها من الأشياء.
  • واجهة خرائط جوجل وواجهة OpenStreetMap API وتسمحان لك بإدراج خرائط ضمن موقعك الإلكتروني وغيرها من الوظائف.

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

ما الذي تفعله جافا سكريبت في صفحة الويب

سنلقي هنا نظرة على بعض الشيفرة، ونستعرض ما يحدث حقيقةً عندما تنفّذ شيفرة جافا سكريبت في صفحتك.

لنستذكر سريعًا ما يحدث عند تحميل صفحة ويب في متصفح . عندما تحمّل صفحة ويب في متصفحك فإنك تنفّذ شيفرتك (HTML و CSS وجافا سكريبت) ضمن بيئة تنفيذية (نافذة المتصفح)، وهذا أمر مماثل لمعمل يستقبل موادًا أولية (الشيفرة) ويخرج منتجًا (صفحة الويب).

05 javas html css

إن أكثر الاستخدامات شيوعًا لجافا سكريبت هو تعديل شيفرة HTML و CSS ديناميكيًا لتغيير الواجهة من خلال الواجهة البرمجية DOM API. ولاحظ أن شيفرة صفحات الويب تُحمّل عمومًا وتنفذ وفق ترتيب ظهورها في الصفحة. وقد تحدث أخطاء إن حُمّلت شيفرة جافا سكريبت ونُفِّذت قبل شيفرة HTML و CSS التي ستُعدّل. سنتعلم لاحقًا في مقالنا كيف نلتف على الموضوع.

أمان المتصفح

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

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

ترتيب تنفيذ شيفرة جافا سكريبت

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

const para = document.querySelector("p");

para.addEventListener("click", updateName);

function updateName() {
  const name = prompt("Enter a new name");
  para.textContent = `Player 1: ${name}`;
}

نختار في السطر الأول مقطعًا نصيًا ثم نضيف مترصّد للحدث (مستمع للحدث) في السطر الثالث كي تُنفّذ شيفرة الكتلة البرمجية ()updteName (الأسطر من 5-8). تسأل الكتلة البرمجية ()updateName (يُدعى هذا النوع القابل للاستخدام المتكرر من الكتل البرمجية دوال functions) أن يُدخل المستخدم اسمًا جديدًا ومن ثم تضع الاسم ضمن الفقرة النصية وتحدّث ما يُعرض على الشاشة. فإن بدلت ترتيب أول سطرين، لن تعمل الشيفرة، بل ستحصل على خطأ تعرضه طرفية المطوّر في المتصفح وهي typeError: para is undefined. ويعني هذا أن الكائن para غير موجود بعد، ولا يمكن إضافة مترصّد أحداث إليه.

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

الشيفرة المفسّرة والمصرّفة

ربما سمعت بالمصطلحين "مفسّر interpreted" و "مصرّف compiled" في سياق تعلمك للبرمجة. ففي اللغات المفسّرة تنفّذ الشيفرة من الأعلى إلى الأسفل وتُعاد نتيجة تنفيذ الشيفرة مباشرة، ولا حاجة لنقل الشيفرة إلى شكل آخر قبل أن يُنفّذها المتصفح. إذ يستقبل الشيفرة بشكلها النصي المفهوم من قبل المبرمج ثم يعالجها مباشرة. بينما تحوّل الشيفرة في اللغات المصرّفة إلى شكل آخر قبل أن يُنفّذها الحاسوب. إذ تحوّل مثلًا شيفرة لغتي C أو ++C إلى لغة الآلة التي ينفذها الحاسوب بعد ذلك. وينفّذ البرنامج انطلاقًا من صيغته الثنائية التي تنتج عن تصريف شيفرته المصدرية.

جافا سكريبت هي لغة برمجة مفسّرة خفيفة الحجم، يتلقى المتصفح شيفرتها بشكلها النصي وينفّذه. وإذا أردنا الحديث تقنيًا يمكننا القول أن مفسرّات جافا سكريبت الحديثة تستخدم تقنية تّدعى التصريف عند التنفيذ Just-in-time compiling لتحسين الأداء. إذ تُصرّف شيفرة جافا سكريبت المصدرية إلى شكل ثنائي أسرع في نفس الوقت الذي تُنفّذ فيه الشيفرة وهذا ما يجعل التنفيذ أسرع ما يمكن. مع ذلك لا تزال جافا سكريبت في عداد اللغات المفسّرة لأن التصريف يجري أثناء التنفيذ بدلًا من تصريف الشيفرة مسبقًا. ولكلا نوعي اللغات ميزاته، لكن لن نناقش هذا الموضوع الآن.

شيفرة طرف العميل موازنة مع شيفرة طرف الخادم

لربما سمعت أيضًا بمصطلحي "طرف الخادم server-side" و "طرف العميل client-side" وخاصة في سياق تعلم تطوير الويب. تُنفّذ شيفرة طرف العميل على حاسوب العميل أو المستخدم، فما يحدث عند استعراض صفحة الويب هو أن المتصفح سينزّل شيفرة طرف العميل ثم ينفذها ويعرضها. وما سنتحدث عنه في سلسلة مقالات جافا سكريبت هو استخدام جافا سكريبت من طرف العميل فقط.

تُنفّذ شيفرة طرف الخادم بالمقابل على الخوادم ثم تُنزّل نتيجة التنفيذ وتُعرض في المتصفح. ومن لغات ويب التي تعمل من طرف الخادم نذكر PHP و Python و Ruby و ASP.NET وكذلك لغة جافا سكريبت. إذ يمكن استخدام جافا سكريبت كلغة برمجة من طرف الخادم في بيئة Node.js الشهيرة.

الشيفرة الديناميكية موازنة مع الشيفرة الساكنة

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

عندما لا تُحدَّث صفحة الويب ديناميكيًا بمحتوى جديد ندعوها ساكنة static، فهي تعرض نفس المحتوى دائمًا.

كيف تضيف شيفرة جافا سكريبت إلى صفحتك؟

تُضاف شيفرة جافا سكريبت إلى صفحة HTML بنفس الأسلوب الذي تُضاف به شيفرة CSS. إذ تستخدم CSS العنصر <link> لتطبيق ورقة تنسيق خارجية و العنصر <style> لتطبيق ورقة تنسيق داخلية على شيفرة HTML، بينما لا تحتاج جافا سكريبت سوى العنصر <script>. لنلق نظرة على عمله.

شيفرة جافا سكريبت داخلية

  1. قبل كل شيء، أنشئ نسخة من الملف apply-javascript.html على جهازك وخزّنها في مكان مناسب.
  2. افتح الملف في متصفحك وضمن المحرر النصي في نفس الوقت. سترى أن شيفرة HTML قد أنشأت صفحة ويب بسيطة تضم زرًا يمكن النقر عليه.
  3. اضف الشيفرة التالية ضمن الترويسة في المحرر النصي وقبل وسم النهاية <head/>:
<script>
  // JavaScript goes here
</script>
  1. سنضيف الآن بعض شيفرة جافا سكريبت ضمن الوسم <script> وتحت عبارة "JavaScript goes here//" لنجعل الصفحة أكثر حيوية:
document.addEventListener("DOMContentLoaded", () => {
  function createParagraph() {
    const para = document.createElement("p");
    para.textContent = "You clicked the button!";
    document.body.appendChild(para);
  }

  const buttons = document.querySelectorAll("button");

  for (const button of buttons) {
    button.addEventListener("click", createParagraph);
  }
});
  1. احفظ الملف وحدّث المتصفّح، وستلاحظ ظهور فقرة نصية تحت الزر عند النقر عليه.

ملاحظة: إن رأيت أن المثال لا يعمل كما هو مطلوب، راجع الخطوات السابقة بتأنٍ وتحقق أنك فعلت كل شيء بالشكل الصحيح. هل خزنت الملف بلاحقة html.؟ هل وضعت الوسم <script> قبل وسم النهاية <head/>؟ هل أدخلت شيفرة جافا سكريبت كما هي تمامًا؟ وانتبه إلى أن جافا سكريبت حساسة لحالة الأحرف وعليك إضافة الشيفرات كما هي تمامًا وإلا لن تعمل.

شيفرة جافا سكريبت خارجية

تعمل الشيفرة السابقة جيدًا، لكن ماذا لو أردت أن تضع تلك الشيفرة في ملف خارجي منفصل؟

  1. أنشئ ملفًا جديدًا في نفس المكان الذي خزّنت فيه ملف HTML ثم سمّه script.js. تأكد أن لاحقة الملف هي js. لأنها الطريقة التي يُعرف بها ملف جافا سكريبت.
  2. استبدل الوسم <script> بالوسم التالي:
<script src="script.js" defer></script>
  1. ضع الشيفرة التالية في ملف script.js:
function createParagraph() {
  const para = document.createElement("p");
  para.textContent = "You clicked the button!";
  document.body.appendChild(para);
}

const buttons = document.querySelectorAll("button");

for (const button of buttons) {
  button.addEventListener("click", createParagraph);
}
  1. احفظ الملف وحدّث المتصفّح وسترى الشيء ذاته، لكن شيفرة جافا سكريبت في هذه الحالة موجودة في ملف خارجي. وهذا عمومًا أمر جيد من ناحية تنظيم الشيفرة وجعلها قابلة للاستخدام ضمن جميع صفحات الموقع، إضافة إلى أن ملفات HTML أسهل قراءة في هذه الحالة دون وجود قطع من الشيفرة مزروعةً ضمنها.

معالجات جافا سكريبت السطرية

قد تصادف في بعض الحالات شيفرة جافا سكريبت ضمن شيفرة HTML، وسيبدو الأمر مشابهًا لما يلي:

function createParagraph() {
  const para = document.createElement("p");
  para.textContent = "You clicked the button!";
  document.body.appendChild(para);
}
<button onclick="createParagraph()">Click me!</button>

جرب هذه النسخة في المحرر التفاعلي:

لهذه النسخة العمل ذاته كما في النسختين السابقتين، إلا أن العنصر <button> يضم معالجًا سطريًا هو onclick يفعّل عمل الدالة عند النقر على الزر.

ننصحك بأن لا تفعل ذلك، فمن السيء أن تلوّث شيفرة HTML يشيفرة جافا سكريبت، إضافة إلى أنها طريقة غير فعّالة أن تضيف السمة "()onclick="createParagraph في كل زر تريده أن ينفّذ الوظيفة ذاتها.

استخدام الدالة addEvenetListerer

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

const buttons = document.querySelectorAll("button");

for (const button of buttons) {
  button.addEventListener("click", createParagraph);
}

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

ملاحظة: جرّب أن تعدّل في شيفرة الملف apply-javascript.html بإضافة بضعة أزرار إضافية، سترى عندها وبعد تحديث الصفحة أن النقر على أي زر منها سينشئ فقرة نصية.

استراتيجيات تحميل السكربتات في صفحات الويب

تصادفنا بعض المشاكل تتعلق بتوقيت تحميل السكربتات في صفحة الويب. فلا شيء بالبساطة التي يبدو عليها. ومن المشاكل الشائعة هي تحميل شيفرة HTML كاملة وبالترتيب الذي تظهر عليه ضمن الملف. فإن استخدمت جافا سكريبت للتعامل مع عناصر الصفحة (أو شجرة DOM بدقة)، لن تعمل الشيفرة إن حُّملت وفُسِّرت قبل أن يُحمّل عنصر HTML الذي تستهدفه.

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

لاحظ الأسلوب المستخدم في مثال الشيفرة الداخلية:

document.addEventListener("DOMContentLoaded", () => {
  // …
});

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

وفي مثال الشيفرة الخارجية، نستخدم ميزة أكثر حداثة لجافا سكريبت لحل المشكلة من خلال السمة defer التي تخبر المتصفح أن عليه إكمال تحميل شيفرة HTML عندما يصل إلى السمة <script>:

<script src="script.js" defer></script>

ستُحمّل شيفرة HTML و جافا سكريبت بالتوازي في هذه الحالة وستعمل الشيفرة جيدًا.

ملاحظة: لا حاجة لاستخدام الحدث DOMContentLoaded في الشيفرة الخارجية لأن السمة defer تحل المشكلة. ولم نستخدم السمة defer في الشيفرة الداخلية لأنها تعمل فقط مع السكربت الخارجي.

ومن الحلول القديمة التي استخدمت لحل لهذه المشكلة هو وضع شيفرة جافا سكريبت في نهاية الملف وقبل الموسم <body/> وبالتالي تُحمّل الشيفرة بعد إنتهاء تحميل وتفسير عناصر HTML. أما مشكلة هذا الحل هو إيقاف عمل شيفرة جافا سكريبت حتى يكتمل تحميل شجرة DOM الخاصة بملف HTML، وهذا ما يسبب مشكلة أداء كبيرة في مواقع الويب الأكبر، وسيبطئ الموقع.

السمة async والسمة defer

توجد في الواقع طريقتان عصريتان لتفادي مشكلة حجب الشيفرة باستخدام السمتين async و defer، وسنلقي نظرة عليهما.

ستُحمّل السكربتات باستخدام async دون إيقاف تحميل الصفحة أثناء تقدم تحميل السكربت. لكن بمجرد اكتمال تحميل السكربت سيُنفَّذ هذا السكربت مما يمنع تصيير الصفحة، ولن تضمن بأي شكل تنفيذ السكربتات بترتيب محدد. ومن الأفضل استخدام هذه السمة عندما لا تتعلق السكربتات في الصفحة ببعضها البعض ولا بأي سكربت آخر في الصفحة.

وبالنسبة للسكربتات التي تُحمّل باستخدام defer ستُحمّل بالترتيب الذي تظهر فيه ضمن الصفحة، ولن تعمل حتى يكتمل تحميل الصفحة، وهذا مفيد في السكربتات التي تتطلب اكتمال تكوين شجرة DOM الخاصة بالملف (وكمثال عليها السكربتات التي تعدّل عنصر أو أكثر في الصفحة).

إليك تمثيلًا بصريًا لأساليب تحميل السكربتات وما الذي تعنيه لصفحتك:

06 scripting order

فلو كان لديك مثلًا عناصر <script> التالية:

<script async src="js/vendor/jquery.js"></script>

<script async src="js/script2.js"></script>

<script async src="js/script3.js"></script>

لا يمكنك الاعتماد على ترتيب تحميل العناصر السابقة، فقد يُحمّل jquery.js قبل أو بعد script2.js و script3.js، وإن حدث ذلك، ستوّلد أية دالة ضمن السكربتين الأخيرين خطأً إن اعتمدت على السكربت jquery لأنه قد لا يكون معرّفًا عند تنفيذها.

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

وإن أردت تنفيذ السكربتات وفق تسلسل ظهورها (كما في الأسفل)، استخدم السمة defer، وستُنفَّذ حالما يُحمّل السكربت ومحتوى الصفحة:

<script defer src="js/vendor/jquery.js"></script>

<script defer src="js/script2.js"></script>

<script defer src="js/script3.js"></script>

نضمن في المثال الثاني أن jquery.js سيُحمّل قبل script2.js الذي يُحمّل قبل script3.js. ولن تُنفَّذ السكربتات حتى يكتمل تحميل الصفحة، وهذا أمر مفيد إن اعتمدت السكربتات على وجود شجرة DOM جاهزة وفي مكانها.

باختصار:

  • تخبر السمتان async و defer المتصفح أن يحمّل السكربتات في خيط منفصل بينما تحمّل بقية محتويات الصفحة في خيط مختلف في نفس الوقت وبالتالي لن يُحجب عرض محتوى الصفحة أثناء عملية إحضاره.
  • تُنفّذ السكربتات التي تستخدم السمة async حالما ينتهي تحميلها، وسيحجب هذا عرض محتوى الصفحة أثناء التنفيذ ولا يمكن أن تضمن ترتيب السكربتات التي ستُنفَّذ.
  • تُحمّل السكربتات التي تستخدم السمة defer بالترتيب الذي تظهر فيه وتُنفَّذ بمجرد انتهاء تحميل كل شيء.
  • إن كان لابد من تنفيذ السكربت مباشرة بعد تحميله ولا يتعلق تنفيذه بسكربتات أو عناصر أخرى يفضّل استخدام async.
  • إن كان لا بد من الانتظار حتى ينتهي تفسير الملف واعتمد السكربت على سكربتات أخرى أو على تكوين شجرة DOM الخاصة بالملف، استخدم defer وضع السكربتات (العناصر <script>) بالترتيب الذي تريده حتى يُنفذها المتصفح بنفس الترتيب.

التعليقات في جافا سكريبت

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

يُنصح باستخدام التعليقات ما أمكن فهي مفيدة وخاصة في التطبيقات الضخمة، وهنالك طريقتين لإدراج التعليقات:

  • على شكل سطر وحيد بعد إشارتي شرطة أمامية //.
// I am a comment
  • أسطر متعددة مكتوبة بين النصين */ و /*.
  /*
    I am also
    a comment
  */

فمثلًا، يمكن إضافة التعليقات التالية إلى آخر مثال شرحناه:

// Function: creates a new paragraph and appends it to the bottom of the HTML body.

function createParagraph() {
  const para = document.createElement("p");
  para.textContent = "You clicked the button!";
  document.body.appendChild(para);
}

/*
  1. Get references to all the buttons on the page in an array format.
  2. Loop through all the buttons and add a click event listener to each one.

  When any button is pressed, the createParagraph() function will be run.
*/

const buttons = document.querySelectorAll("button");

for (const button of buttons) {
  button.addEventListener("click", createParagraph);
}

ملاحظة: كثرة التعليقات أفضل عادة من التعليقات القليلة، لكن انتبه إن رأيت نفسك تكتب تعليقات كثيرة لتشرح المتغيرات مثلًا (والتي يجب أن تكون واضحة وبديهية) أو لتشرح عمليات بسيطة (عندها قد تكون شيفرتك معقدة).

خلاصة

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

ترجمة -وبتصرف- لمقال What's JavaScript

اقرأ أيضًا


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

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

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



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

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

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

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   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.


×
×
  • أضف...