Bian Alabras

الأعضاء
  • المساهمات

    16
  • تاريخ الانضمام

  • تاريخ آخر زيارة

السُّمعة بالموقع

7 Neutral

1 متابع

  1. مقدمة تعلمنا في المقال السابق طريقة الوصول إلى العناصر في DOM عن كيفية استخدام التوابع الملحقة بالكائن document بهدف الوصول إلى عناصر html بإحدى الطرق التالية: معرف العنصر ID، صف العنصر class، اسم الوسم tag name، أو محددات الاستعلام query selectors. كما شرحنا في مقال البنية الشجرية لـ DOM عن العقدة الأب لـ DOM الممثلة بالكائن document، كما تطرقنا إلى شرح مفصل عن العقد الأبناء التي تبنى من خلالها الشجرة وعن أنواعها (العناصر، التعليقات، والنصوص). ولكننا نحتاج غالبًا للانتقال بين عقد شجرة DOM بدون المرور على جميع العقد التي تسبق العقدة المطلوبة، لذلك سنتحدث في هذه المقالة عن كيفية التنقل في شجرة DOM من الأعلى إلى الأسفل وبالعكس، إضافة إلى التنقل بين أفرع الشجرة من خلال باستخدام تعليمات الجافا سكربت و html. الإعداد: لنبدأ أولًا بإنشاء ملف nodes.html والذي يحوي التعليمات التالية: <!DOCTYPE html> <html> <head> <title>Learning About Nodes</title> <style> * { border: 2px solid #dedede; padding: 15px; margin: 15px; } html { margin: 0; padding: 0; } body { max-width: 600px; font-family: sans-serif; color: #333; } </style> </head> <body> <h1>Shark World</h1> <p>The world's leading source on <strong>shark</strong> related information.</p> <h2>Types of Sharks</h2> <ul> <li>Hammerhead</li> <li>Tiger</li> <li>Great White</li> </ul> </body> <script> const h1 = document.getElementsByTagName('h1')[0]; const p = document.getElementsByTagName('p')[0]; const ul = document.getElementsByTagName('ul')[0]; </script> </html> عند فتح هذا الملف من خلال متصفح الانترنت، سنشاهد الصفحة التالية: في صفحة الويب هذه لدينا مستند html يحوي على عدد قليل من العناصر وأساسيات css مرفقة به من خلال الوسم style من أجل تحسين طريقة إظهار العناصر، كما قمنا ببناء عدد قليل من المتحولات باستخدام تعليمات الجافا سكربت والتي ذكرت ضمن الوسم script حيث ستساعدنا بالوصول إلى العناصر. كما نلحظ وجود عنصر واحد من العناصر التالية h1، p، ul لذا يمكن الوصول إليها من خلال الدليل الأول index للتابع getElementsByTagName. عقدة الجذر Root Node يعتبر الكائن doucment العقدة الجذر root node لجميع العقد في DOM. ولكن في الحقيقة كائن document هو إحدى خصائص الكائن window والذي يمكن تعريفه بأنه كائن عام global وذو مستوى عالي top-level object حيث يمثل تبويب المتصفح الذي يظهر فيه صفحة الويب. يمكننا من خلال كائن window أن نصل إلى معلومات عن شريط الأدوات، طول وارتفاع النافذة، الرسائل الظاهرة في المتصفح، والإنذارات، في حين أن كائن document يتضمن كل الأحداث والخصائص الأخرى الموجودة داخل window. يتضمن الجدول المرفق عناصر الجذر التي يمتلكها كل document حتى لو كان ملف html المحمل إلى المتصفح فارغ وهي عبارة عن 3 عقد سيتم إضافتها وتفسيرها في DOM. table { width: 100%; } td, th { border: 1px solid #dddddd; text-align: left; padding: 8px; } tr:nth-child(even) { background-color: #dddddd; } الخاصية العقدة نوع العقدة document #document DOCUMENT_NODE document.documentElement html Element_NODE getElementsByTagName() head Element_NODE querySelector() body Element_NODE وبما أن عناصر html، head، body شائعة جدًا فإنها تمتلك الخصائص الخاصة بها في المستند. سنقوم بفتح تبويب console ضمن أدوات المطورين DevTools حتى نختبر هذه الخصائص الأربع من خلال كتابتها في console ومشاهدة النتائج. كما يمكننا أيضًا اختبار العناصر h1، p، و ul. عقد الآباء Parent Nodes لدينا في DOM ثلاث أنواع من العقد معرفة حسب نوع العلاقة فيها بينها وهي الآباء parents، الأبناء children، والشقيقة siblings. تعرف العقدة الأب parent بأنها أي عقدة تمتلك عقدًا أقل في مستوى level أقل منها في التدرّج الهرمي للـ DOM، أو يمكن تعريفها بأنها العقد الأقرب لعقدة الجذر document. يمكن الوصول دومًا للعقدة الأب بواسطة إحدى الخاصيتين parentNode أو parentElement. Gets Property ParentNode parentNode ParentElementNode parentElement في مثالنا nodes.html نلاحظ أن: html هي العقدة الأب لكل من عقد head، body، و script العقدة body هي العقدة الأب لكل من h1، h2، و ul ولكنها ليست العقدة الأب لـ li لأنها في المستوى الأقل منها بمستويين. يمكننا اختبار طريقة الوصول إلى العقدة الأب التي ذكرناها سابقًا، حيث سنقوم بمعرفة أب العنصر p من خلال الخاصية parentNode، وكما نذكر أننا قمنا ببناء المتحول p في التعليمات السابقة وإسناد القيمة document.getElementsByTagName('p')[0] وللوصول للأب نكتب التعليمة التالية في تبويب console > p.parentNode; وسيكون الخرج: Output ► <body>...</body> ويمكن استعمال parentNode مرتين للوصول إلى جد p. يمكن الاستعانة بالعديد من الخصائص التي تمكننا من الوصول إلى العقدة الأب ولكن يوجد فيما بينها القليل من الاختلافات كما سنبينها الآن > // Assign html object to html variable > const html = document.documentElement; > > console.log(html.parentNode); // > #document > console.log(html.parentElement); // > null إن الأب لأي عقدة هو من نوع عقدة العنصر element nodes بينما لايمكن للعقد من نوع نص أو تعليقات أن تكون أب لأي عقدة أخرى وبما أن العقدة الأب لـ html هي العقدة الجذر document node لذلك نلاحظ أن القيمة المرجعة هي Null في السطر الأخير من التعليمات. بشكل عام إن استخدام الخاصية parentNode شائع أكثر في الانتقال ضمن DOM. العقد الأبناء Children Nodes إن أبناء أي عقدة هي جميع العقد الموجودة في المستوى الذي يليه مباشرة أما العقد الموجود في المستوى الذي يلي مستوى الأبناء تسمى العقد الأحفاد. Gets Property Child Nodes childNodes First Child Node firstChild Last Child Node lastChild Element Child Nodes children First Child Element Node firstElementChild Last Child Element Node lastElementChild إن خاصية ChildNode ستعيد قائمة بأبناء العقدة. على سبيل المثال في ملف nodes.html السابق نلاحظ أن عنصر ul لديه 3 عناصر أبناء من li وبالتالي عند إدخال التعليمة: > ul.childNodes; وسيكون الخرج: Output ► (7) [text, li, text, li, text, li, text] نلاحظ أننا حصلنا على قائمة بأبناء العنصر ul والتي تحوي العناصر li الثلاث التي ذكرناها بالإضافة إلى عُقد النصوص text nodes ويعود السبب في ذلك لأننا كتبنا ملف html بطريقة يدوية ولم يتم توليده بواسطة الجافا سكربت. مع العلم أن كل ما يوجد بين العناصر يعتبره DOM عقدة نص text node، ولكن يعمل تبويب Elements الموجودة في أدوات التطوير الخاصة بالمتصفح DevTools بحذف الفراغات البيضاء من النص وبالتالي لا يعتبرها عقد نصوص. مثلًا إذا حاولنا تغيير لون الخلفية للابن الأول باستخدام خاصية firstChild سنفشل لأن أول عقدة هي نص. > ul.firstChild.style.background = 'yellow'; وستكون رسالة الخطأ هي Output > Uncaught TypeError: Cannot set property 'background' of undefined لذلك فإن الخصائص children، firstElementChild، و lastElementChild وجدت لكي نستطيع الحصول على العقدة من نوع عنصر element node فقط، أي في حال كتابة ul.children سنحصل على مصفوفة تحوي 3 عقد من نوع عنصر هي li. باستخدام الخاصية firstElementChild سنقوم بتغيير لون الخلفية للعنصر الأول li التي هي ابن للعقدة ul > ul.firstElementChild.style.background = 'yellow'; وعند تنفيذ هذه التعليمة سيتغير لون الخلفية عند معالجة شجرة DOM تظهر بعض الخصائص المفيدة للعناصر element properties. في تطبيقات الويب التي تم توليدها باستخدام الجافا سكربت الأكثر احتمالًا، هو استخدام الخصائص التي تختار جميع العقد، وفي هذه الحالة الخطوط والمساحات البيضاء لن تكون موجودة. بالعودة للمثال السابق يمكن استخدام حلقة for ... of من أجل تطبيق اللون الأصفر في الخلف على جميع العناصر الأبناء children. for (let element of ul.children) { element.style.background = 'yellow'; } بتطبيق هذه التعليمات سيظهر اللون الأصفر في خلفية جميع الأبناء وبما أن العنصر p يمتلك نوعي عقد من الأبناء وهي العناصر والنصوص في داخله، فإنه يمكن للخاصية childNodes أن تكون مفيدة في الوصول إلى لهذه المعلومات. for (let element of p.childNodes) { console.log(element); } حيث سيكون الخرج عبارة عن ثلاثة أسطر كل سطر يمثل ابن للعقدة p Output "The world's leading source on " <strong>shark</strong> " related information." إن خاصيتي children و childNode تعيد مصفوفة ولكنها لاتمتلك جميع خصائص وتوابع المصفوفات، ولكنها تظهر بشكل مشابه للمصفوفات في الجافا سكربت. ولكن يمكن الوصول إلى العقد من خلال رقم الدليل index أو من خلال خاصية طول المصفوفة length document.body.children[3].lastElementChild.style.background = 'fuchsia'; التعليمة السابقة هي عبارة عن إضافة اللون الفوشي لخلفية العقدة الابن الأخيرة (li) التابعة للعنصر الابن رقم 3 (ul) والتي هي بدورها ابن للعقدة body. إن استخدام خصائص الأب والابن تساعد في الوصول إلى أي عقدة ضمن شجرة DOM. العقد الشقيقة Sibling Nodes العقد الشقيقة sibling of nodes هي العقد الموجودة في نفس المستوى في شجرة DOM ويمكن أن تكون من أنواع مختلفة من العقد سواء عنصر، نص أو تعليق Gets Property Previous Sibling Node previousSibling Next Sibling Node nextSibling Previous Sibling Element Node previousElementSibling Next Sibling Element Node nextElementSibling إن خصائص العقد الشقيقة تعمل بنفس الطريقة التي تعمل فيها عند العقد الأبناء، حيث نجد مجموعة من الخصائص للتنقل بين العقد بكل أنواعها وهي previousSibling و nextSibling ومجموعة أخرى تساعد على التنقل بين العقد من نوع عناصر فقط وهي previousElementSibling و nextElementSibling. في مثالنا nodes.html سنختار الابن الأوسط للعنصر ul const tiger = ul.children[1]; وبما أننا بنينا DOM الخاص بنا من الصفر وليس بناء على تطبيق ويب باستخدام الجافا سكربت فإننا نحتاج لاستخدام خصائص العناصر الأشقاء للوصول إلى عقد العناصر السابقة واللاحقة مع العلم أن الفراغات البيضاء موجودة في DOM كعقد من نوع text tiger.nextElementSibling.style.background = 'coral'; tiger.previousElementSibling.style.background = 'aquamarine'; وبتنفيذ التعليمات السابقة سنلاحظ أن لون الخلفية عند Hammerhead وGreat White قد تغير ملخص تحدثنا في هذه المقالة عن كيفية الوصول إلى جميع عناصر مستند HTML وكيفية التحرك بين العقد في شجرة DOM من خلال خصائص العقد الأب، الابن، والشقيقة. وبهذا ستكون قادرًا على الوصول إلى أي عقدة ضمن شجرة DOM في أي موقع ويب. هذه المقالة ترجمة للمقالة How To Traverse the DOM للكاتبة Tania Rascia
  2. مقدمة تحدثنا في المقال السابق عن البنية الشجرية لـ DOM وعن العقد Nodes المكونة لها وهي عبارة عن كائنات objects من الممكن أن تكون نصوص أو تعليقات أو عناصر. في الغالب يمكن الوصول إلى محتوى DOM من خلال عقد عناصر html، ولمعرفة كيفية الوصول إلى عناصر DOM بشكل احترافي من الضروري امتلاك معلومات كافية عن قواعد وأساسيات css، لذلك سنقوم في هذه المقالة بتعلم كيفية الوصول إلى عناصر DOM من خلال ID والصف class والوسم tag، ومحددات الاستعلام query selectors. نظرة عامة سنستعرض في هذا المقال خمس توابع methods هي: الطرق محدد بناء الجملة يحصل على getElementById() #demo ID getElementsByClassName() .demo Class getElementsByTagName() demo Tag querySelector() Selector (single) querySelectorAll() Selector (all) من المهم عند دراستنا ل DOM أن تقوم بتطبيق الأمثلة على حاسبك للتأكد من فهم جميع المعلومات بشكل جيد. سنبدأ بإنشاء ملف access.html في مجلد المشروع والذي سنقوم بتطبيق جميع أمثلتنا عليه في هذه المقالة. <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Accessing Elements in the DOM</title> <style> html { font-family: sans-serif; color: #333; } body { max-width: 500px; margin: 0 auto; padding: 0 15px; } div, article { padding: 10px; margin: 5px; border: 1px solid #dedede; } </style> </head> <body> <h1>Accessing Elements in the DOM</h1> <h2>ID (#demo)</h2> <div id="demo">Access me by ID</div> <h2>Class (.demo)</h2> <div class="demo">Access me by class (1)</div> <div class="demo">Access me by class (2)</div> <h2>Tag (article)</h2> <article>Access me by tag (1)</article> <article>Access me by tag (2)</article> <h2>Query Selector</h2> <div id="demo-query">Access me by query</div> <h2>Query Selector All</h2> <div class="demo-query-all">Access me by query all (1)</div> <div class="demo-query-all">Access me by query all (2)</div> </body> </html> في ملف html هذا نلاحظ أن لدينا العديد من العناصر التي يمكن الوصول إليها من خلال توابع method الخاصة بـ document وعند فتح هذا الملف في المتصفح سيكون مشابه لهذه الصفحة: سنستخدم العديد من التوابع methods التي ذكرناها في المقال سابقًا للوصول إلى العناصر المتاحة في هذا الملف. الوصول للعناصر باستخدام ID أسهل طريقة للوصول إلى عنصر محدد في DOM هو المعرف الخاص بها ID(Identification). حيث يمكن الوصول إلى العنصر من خلال ID باستخدام التابع getElementById() مع العنصر document. document.getElementById(); ولكن للحصول على هذه الخاصية في الوصول إلى العنصر من خلال id يجب أولًا إضافة الصفة id للعنصر. مثلًا سنضيف المعرف demo للعنصر div <div id="demo">Access me by ID</div> الآن في تبويب console سنقوم بالوصول إلى العنصر واسناده للمتحول demoId > const demoId = document.getElementById('demo'); في حال تمرير المتحول demoId إلى تابع log سنحصل على عنصر html كاملًا. > console.log(demoId); سيكون الخرج عندها العنصر كاملًا <div id="demo">Access me by ID</div> للتأكد من وصولنا إلى العنصر الصحيح سنقوم بتغيير حدود العنصر border property إلى اللّون البنفسجي > demoId.style.border = '1px solid purple'; وعند تنفيذ هذه التعليمات سنلاحظ أن حدود العنصر قد تغيرت إلى اللّون البنفسجي: إن الوصول إلى أي عنصر من خلال ID الخاص به هي أكثر طريقة فعالة وسريعة للوصول إلى عنصر ضمن DOM، ومع ذلك هذه الطريقة لديها عدة عيوب وهي أن ID دائمًا يجب أن يكون متفردًا في الصفحة ولذلك لا يمكن الوصول إلا إلى عنصر واحد فقط من خلال التابع getElementById. ولذلك في حال الحاجة إلى إضافة تابع لأكثر من عنصر في الصفحة فإن إضافته باستخدام id سيؤدي إلى تكرار كتابة التابع لكل عنصر على حدى. الوصول للعناصر باستخدام class تستخدم خاصية class للوصول إلى عنصر أو أكثر في DOM وذلك من خلال التابع getElementByClassName() document.getElementsByClassName(); ونستطيع من خلال الخاصية class الوصول إلى أكثر من عنصر، كما في هذا المثال حيث سنعطي لعنصرين نفس اسم الصف demo <div class="demo">Access me by class (1)</div> <div class="demo">Access me by class (2)</div> الآن في تبويبة console سنبني متحول demoClass ونسند له العناصر التي استطعنا الوصول إليها من خلال اسم الصف demo > const demoClass = document.getElementsByClassName('demo'); والآن أصبح بالإمكان الوصول إلى العناصر وتعديلها باستخدام class كما فعلنا في المثال السابق باستخدم ID. سنقوم الآن بتغيير خاصية الحدود border من خلال المتحول demoClass، demoClass.style.border = '1px solid orange'; ولكن ستظهر لنا رسالة خطأ بأنه لا يمكن تحديد العنصر Output Uncaught TypeError: Cannot set property 'border' of undefined والسبب في هذا الخطأ أن المتحول demoClass لايحوي عنصرًا واحدًا فقط وإنما مصفوفة كائنات من هذه العناصر للتأكد من ذلك سنكتب التعليمة التالية لمعرفة عدد عناصر المصفوفة المُسند إلى deomClass console.log(demoClass); والخرج سيكون هو عدد العناصر في المصفوفة Output (2) [div.demo, div.demo] حتى نستطيع الوصول إلى العناصر بشكل صحيح يجب أن نتعامل مع المتحول demoClass على أنه مصفوفة جافا سكربت يتم الوصول إليها من خلال رقم دليل العنصر index number. الآن نستطيع تغيير حدود كل العنصر الأول في المصفوفة باستخدام رقم الدليل 0 demoClass[0].style.border = '1px solid orange'; بشكل عام للوصول إلى العناصر من خلال الصف calss سنقوم بتغيير جميع العناصر التي تمتلك نفس اسم الصف باستخدام حلقة for التي تقوم بالمرور على جميع العناصر التي تحويها المصفوفة for (i = 0; i < demoClass.length; i++) { demoClass[i].style.border = ‘lpx solid orange’; } وعند تنفيذ هذه التعليمات سيصبح شكل صفحة الويب إذًا استطعنا الوصول إلى جميع العناصر التي تمتلك الصف demo وتغيير خاصية حدودها border إلى اللّون البرتقالي. الوصول للعناصر باستخدام Tag طريقة الوصول للعنصر من خلال اسم الوسم html tag name هو أقل الطرق تخصيصًا حيث يمكننا الوصول إلى العديد من العناصر باستخدام تابع getElementsByTagName() document.getElementsByTagName(); سنستخدم كمثال هنا العنصر article للوصول إليه من خلال اسم الوسم، نلاحظ العنصرين الذين يحملان اسم الوسم article <article>Access me by tag (1)</article> <article>Access me by tag (2)</article> وبنفس الطريقة التي وصلنا للعناصر من خلال اسم الصف class فإن التابع getElementsByTagName تعيد لنا مصفوفة array من العناصر حيث يمكن تعديل كل tag في المستند من خلال حلقة for const demoTag = document.getElementsByTagName(‘article’); for (i = 0; i < demoTag.length; i++) { demoTag[i].style.border = ‘1px solid blue’; } وبمجرد تنفيذ هذه التعليمات سيصبح شكل صفحة الويب بالشكل وهكذا قمنا بتعديل خاصية الحدود border لجميع العناصر article إلى اللّون الأزرق. محددات الاستعلام Query Selector في حال كان لديك خبرة سابقة في jQuery API ربما ستكون لديك معرفة سابقة مع توابع jQuery التي تستطيع الوصول لعناصر DOM من خلال محددات css $('#demo'); // returns the demo ID element in jQuery يمكننا الحصول على نفس النتيجة في الجافا سكربت من خلال استخدام التوابع querySelector() و querySelectorAll() document.querySelector(); document.querySelectorAll(); للوصول إلى عنصر واحد نستخدم تابع querySelector. فمثلًا يمكننا الوصول إلى العنصر الذي لديه المعرف demo-query من خلال التابع querySelector() <div id="demo-query">Access me by query</div> حيث نمرر للتابع المعرف id مع إضافة الرمز #، وسنقوم بإسناد العنصر للثابت demoQuery const demoQuery = document.querySelector('#demo-query'); ولكن في حالة استخدمنا التابع السابق مع المحددات التي تعطينا أكثر من عنصر واحد مثل class أو tag فإن querySelector() سيعيد لنا العنصر الأول فقط الذي يتطابق مع الاستعلام، ولكن نستطيع استخدام التابع querySelectorAll() من أجل الحصول على جميع العناصر المتطابقة مع الاستعلام. في مثالنا نلاحظ أن لدينا عنصرين يملكان اسم الصف demo-query-all <div class="demo-query-all">Access me by query all (1)</div> <div class="demo-query-all">Access me by query all (2)</div> إن اسم المحدد للخاصية class يجب أن يسبق بنقطة عند تمريره للتابع querySelectorAll() أي سنمرر في هذا المثال .demo-query-all const demoQueryAll = document.querySelectorAll('.demo-query-all'); باستخدام التابع forEach() يمكننا تطبيق اللّون الأخضر على حدود هذه العناصر deomQueryAll.forEach(query => { query.style.border = ‘1px solid green’; }); تعتبر الفاصلة , في حال وضعناها بين القيم للتابع querySelector() كعملية OR مثلاً إذا قمنا بكتابة التابع بالشكل querySelector(‘div, article’) أي تعني أن يجد لنا العنصر div أو article بغض النظر عمن سيظهر أولًا في الملف. أما في حالة وجود الفاصلة بين القيم للتابع querySelectorAll فإنها تعني العملية AND أي في حال كتبنا التابع querySelectroAll(‘div, article’) فإنها تعني إعادة العناصر التي تحوي القيم articl و div الموجودة ضمن المستند. إن استخدام توابع محددات الاستعلامات يعطينا القدرة العالية في البرمجة للوصول إلى أي عنصر أو مجموعة عناصر ضمن DOM بنفس المحددات التي نستخدمها في ملف css. وفي هذه المقالة يوجد قائمة بجميع المحددات الخاصة بال css التي جمعت بواسطة شبكة مطوري Mozilla. تعليمات الجافا سكربت كاملة سأذكر هنا التعليمات التي كتبناها بلمف access.js بشكل كامل. حيث يمكن إضافة ملف js إلى ملف html قبل إغلاق body. // Assign all elements const demoId = document.getElementById('demo'); const demoClass = document.getElementsByClassName('demo'); const demoTag = document.getElementsByTagName('article'); const demoQuery = document.querySelector('#demo-query'); const demoQueryAll = document.querySelectorAll('.demo-query-all'); // Change border of ID demo to purple demoId.style.border = '1px solid purple'; // Change border of class demo to orange for (i = 0; i < demoClass.length; i++) { demoClass[i].style.border = '1px solid orange'; } // Change border of tag demo to blue for (i = 0; i < demoTag.length; i++) { demoTag[i].style.border = '1px solid blue'; } // Change border of ID demo-query to red demoQuery.style.border = '1px solid red'; // Change border of class query-all to green demoQueryAll.forEach(query => { query.style.border = '1px solid green'; }); وسيكون الشكل النهائي لملف html هو <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Accessing Elements in the DOM</title> <style> html { font-family: sans-serif; color: #333; } body { max-width: 500px; margin: 0 auto; padding: 0 15px; } div, article { padding: 10px; margin: 5px; border: 1px solid #dedede; } </style> </head> <body> <h1>Accessing Elements in the DOM</h1> <h2>ID (#demo)</h2> <div id="demo">Access me by ID</div> <h2>Class (.demo)</h2> <div class="demo">Access me by class (1)</div> <div class="demo">Access me by class (2)</div> <h2>Tag (article)</h2> <article>Access me by tag (1)</article> <article>Access me by tag (2)</article> <h2>Query Selector</h2> <div id="demo-query">Access me by query</div> <h2>Query Selector All</h2> <div class="demo-query-all">Access me by query all (1)</div> <div class="demo-query-all">Access me by query all (2)</div> <script src="access.js"></script> </body> </html> ملخص في هذه المقالة تعلمنا 5 طرق للوصول إلى عناصر html الموجودة في DOM وهي من خلال المعرف ID، الصف class، الوسم html tag name، ومن خلال المحددات selector. التوابع التي يمكن استخدامها للحصول على عنصر أو مجموعة عناصر تعتمد على مدى دعم المتصفح المستخدم لها وعدد العناصر التي تتم معالجتها. والآن يمكنك الوصول إل عناصر html الموجودة في المستند باستخدام الجافا سكربت و DOM. هذه المقالة هي ترجمة للمقالة How To Access Elements in the DOM وكاتبتها Tania Rascia. table { width: 100%; } td, th { border: 1px solid #dddddd; text-align: left; padding: 8px; } tr:nth-child(even) { background-color: #dddddd; }
  3. مقدمة عندما نتكلم عن DOM فإننا نتكلم عن بنية شجرية تحوي العديد من الكائنات objects التي تدعى العقد nodes. لقد تكلمنا في المقال السابق (مدخل إلى DOM) عن تعريف DOM وكيفية الوصول إلى الكائن document وطريقة تعديل خصائصه من خلال console بالإضافة إلى إيضاح الفرق بين ماهية HTML و DOM. في هذه المقالة فسنتحدث عن مصطلحات HTML التي تعتبر قواعد أساسية للتنسيق برمجة موقع الويب الذي يتضمن html، الجافا سكربت ومفاهيم DOM. حيث سنتعلم من خلال هذا المقال كيفية بناء شجرة DOM و كيفية إضافة العقد الخاصة بها Nodes حسب نوعها، أخيرًا سنقوم ببناء برنامج باستخدام الجافا سكربت بدلًا من استخدام console وذلك لتعديل DOM. مصطلحات HTML إن فهم مصطلحات Html و الجافا سكربت تعتبر أمرًا ضروريًا لفهم كيفية العمل مع DOM. ولذلك سنقوم بمراجعة بعض مصطلحات html سنبدأ أولًا بالنظر إلى عنصر html التالي <a href="index.html">Home</a> إن عنصر html السابق a هو عبارة عن عنصر يُضاف لربط صفحة الويب الخاصة بنا بصفحة أو محتوى آخر، في هذا المثال لتحقيق إمكانية الوصول إلى صفحة index.html a هو الوسم tag href هو الصفة attribute index.html هو قيمة الصف home هو النص الذي نضيفه للعنصر كل ماهو موجود بين علامتي <> هو عبارة عن عنصر html سنعمل على صفحة index.html التي بنيناها بالمقالة السابقة <!DOCTYPE html> <html lang="en"> <head> <title>Learning the DOM</title> </head> <body> <h1>Document Object Model</h1> </body> </html> إن الطريقة الأسهل للوصول إلى عنصر عبر الجافا سكربت هي استخدام الصفة id ويمكننا ربط أي عنصر في html بـ id خاص به، فمثلًا سنقوم بإضافة id خاص بالعنصر a في المثال السابق وقيمتها هي nav ... <body> <h1>Document Object Model</h1> <a id="nav" href="index.html">Home</a> </body> ... الآن سنقوم بتحميل إو إعادة تحميل صفحة index.html للتأكد بتعديل DOM الخاص بصفحتنا التي عدلناها. سنستخدم التابع getElementById() للوصول إلى العنصر كاملًا من خلال كتابة التعليمة التالية في تبويبة console document.getElementById('nav'); عندها سيكون الخرج في تبويبة console بالشكل <a id="nav" href="index.html">Home</a> حيث نلاحظ أننا حصلنا على العنصر كاملآ من خلال استخدام تابع getElementById() ، ولكن يمكننا إسناد عنصر html إلى متحول variable للوصول إليه بشكل أسرع من استخدام التابع السابق. let navLink = document.getElementById('nav'); وهكذا أصبح navLink هو عبارة عن متحول يحوي على عنصر a الخاص وبالتالي يمكننا تعديل الصفات attribute التي يحويها وقيمها بسهولة، فمثلًا يمكننا تعديل قيمة الصفة href بالشكل التالي navLink.href = 'https://www.wikipedia.org'; كما يمكننا تعديل المحتوى النصي للمتحول من خلال إعادة إسناد قيمة نصية جديدة للخاصية textContent navLink.textContent = 'Navigate to Wikipedia'; الآن عندما سنستعرض العنصر a إما من خلال console أو من خلال تمرير الفأة على الوسم a سنشاهد كيف تم تعديل العنصر navLink; وسيكون الخرج هو Output <a id="nav" href="https://www.wikipedia.org/">Navigate to Wikipedia</a> كما سنشاهد أن هذه سينعكس على شكل واجهة الموقع ولكن عند تحديث الصفحة سيتم التراجع عن كل التعديلات التي قمنا بها. وبنهاية هذه الفقرة يجب أن نكون قد تعلمنا كيفية التعامل مع توابع document وطريقة الوصول إليها وإسناد العنصر إلى متحول وتغيير الصفات الخاصة بالعنصر من خلال استخدام المتحول المُسند إليه. شجرة DOM والعقد المكونة لها تعرف جميع العناصر التي تنتمي لل DOM كعقد nodes ولها أنواع متعددة لكن يوجد 3 أنواع هي الأكثر استخداما عقد العنصر Element nodes عقد النص Text nodes عقد التعليقات Comment nodes عندما يتم تمثيل عنصر html كعنصر داخل DOM سنشير له بأنه عقدة العنصر element nodes، وأي نص خارج هذا العنصر سنشير له بأنه عقدة النص text node، وأخيرًا التعليقات التي نكتبها داخل html سنشي لها في DOM بأنها عقد التعليقات Comment node. بالإضافة إلى هذه الأنواع الثلاثة تعتبر document بأنها عقدة قائمة بذاتها تسمى document node والتي تعتبر بأنها جذر العقد الأخرى كافة التي يحتويها ملف DOM. إذًا يتضمن DOM بنية شجرية تحوي العديد من القعد المتداخلة والتي غالبًا ما يشار لها بشجرة DOM أو DOM tree وتشبه بنيتها إلى حد كبير بنية شجرة العائلة التي تضمن الآباء، الأبناء والأشقاء وتلك هي الحال أيضًا بالنسبة للعلاقة بين عقد شجرة DOM. لنرى هذه العلاقات بين عقد شجرة DOM بشكل عملي سنقوم ببناء ملف nodes.html والتي يحوي على أنواع العقد الثلات: عقد النص text، التعليقات comment والعناصر element <!DOCTYPE html> <html> <head> <title>Learning About Nodes</title> </head> <body> <h1>An element node</h1> <!-- a comment node --> A text node. </body> </html> عقدة العنصر html هي العقدة الأب parent node أما عقد العناصر head و body فهي عقد أشقاء وأبناء للقعدة html. أما عقدة body فهي تملك 3 عقد أبناء وهي جميعها عقد أخوة، مع العلم أن نوع العقدة لايؤثر على مستواها. ملاحظة: {.underline} عند العمل مع DOM المولد من قبل html فإن كثرة الفراغات المضافة إلى تعليمات html سيؤدي إلى خلق العديد من عقد النصوص text nodes الفارغة. والتي لاتظهر في تبويبة "Elements" الموجودة في DevTools في chrome. تمييز نوع العقدة كل العقد في المستند document تملك نوع مخصص والتي يمكن الحصول عليها من خلال الخاصية nodeType. قامت شبكة مطوري Mozilla بتحديث قائمتها لـ ثوابت نوع العقدة. وسنذكر هنا قائمة بأكثر أنواع العقد الشائعة وكيفية التعامل معها في هذه المقال نوع العقدة القيمة مثال عقدة العنصر ELEMENT_NODE 1 العنصر < body > عقدة النص TEXT_NODE 3 أي نص ليس جزء من العنصر عقدة التعليق COMMENT_NODE 8 < !--- html comment --- > في تبويبة "Elemnets" الموجودة في أدوات المطوريين قد تلاحظ أنه في حال قمت بالضغط على أي عنصر في DOM وتم تظليله فستلاحظ أنه سيظهر بجانبه القيمة ==$0 ولذلك فإن أحد الطرق السهلة للوصول إلى العنصر النشيط من خلال أدوات التطوير هو كتابة $0. في تبويبة "console" الخاصة بالصفحة nodes.html سنقوم بالضغط على أول عنصر موجود في body وهو h1 الآن سنحصل على نوع العقدة المفعلة حاليًا وذلك من خلال الوصول إليها عبر خاصية nodeType لذلك ندخل التعليمة التالية في console $0.nodeType; وسيكون عندها الخرج هو 1 بالشكل التالي Output 1 وجدنا أن الخرج هو 1 المرتبط بالعنصر المختار h1 والذي يشير إلى نوع ELEMENT_NODE. وبتجربة التعليمة السابقة على نص أو تعليق في ملف HTML فإننا سنحصل على الخرج 3 و 8 بالترتيب. كما يمكننا الحصول على نوع العقدة من دون الحاجة إلى تظليل العنصر في DOM قبل معرفته وذلك من خلال التعليمة document.body.nodeType; حيث سيكون الخرج هو 1 أيضًا. بالإضافة إلى الخاصية nodeType، يمكن استخدام الخاصية nodeValue للحصول على القيمة أو التعليق في عقد النص والتعليق، كما أن الخاصية nodeName تساعدنا في الحصول على اسم الوسم الخاص بالعنصر. تعديل DOM باستخدام الأحداث تعرفنا إلى الآن إلى كيفية تعديل DOM من خلال console ولكن هذا التعديل مؤقت فبمجرد تحديث صفحة الويب ستُلغى هذه التعديلات. في المقالة مدخل إلى DOM استخدمنا console من أجل تعديل لون خلفية الشاشة، الآن يمكن الجمع بين ما تعلمناه سابقًا مع المعلومات في هذه المقالة لبناء زر تفاعلي عندما يتم الضغط عليه. بالعودة إلى ملف index.html سنضيف زر من خلال العنصر button ونضيف له id كما أننا سنضيف رابط جديد لملف جافا سكربت موجود في المجلد js/scripts.js <!DOCTYPE html> <html lang="en"> <head> <title>Learning the DOM</title> </head> <body> <h1>Document Object Model</h1> <button id="changeBackground">Change Background Color</button> <script src="scripts.js"></script> </body> </html> يعرف الحدث event في الجافا سكربت بأنه الفعل الذي يقوم به المستخدم كمثال عندما يقوم المستخدم بتمرير الفأرة فوق عنصر، الضغط على عنصر، أو الضغط على زر معين في لوحة المفاتيح. في هذا المثال نريد للزر الذي بنيناه أن ينتظر ويكون مستعدًا لتلقي الفعل من قبل المستخدم من خلال استخدام event listener للزر. أولًا نقوم ببناء ملف scripts.js ونحفظه في مجلد js ثم سنضيف تعليمات الجافا سكربت التي تقوم بإيجاد العنصر وإسناده إلى متحول let button = document.getElementById('changeBackground'); ثم نضيف التابع addEventListener الذي يعمل على جعل الزر ينتظر حتى يتم الضغط عليه من أجل تنفيذ التابع function الذي يقوم بالفعل في هذا المثال الفعل هو تغيير لون الخلفية. ... button.addEventListener('click', () => { // action will go here }); حيث سنكتب داخل التابع function التعليمة الخاصة بتغيير لون الخلفية إلى لون fuchsia ... document.body.style.backgroundColor = 'fuchsia'; حيث ستكون التعليمات بالترتيب كما يلي let button = document.getElementById('changeBackground'); button.addEventListener('click', () => { document.body.style.backgroundColor = 'fuchsia'; }); وحالما نقوم بحفظ هذا الملف وإعادة تحديث ملف index.html ثم الضغط على زر الموجود في الشاشة فإن الحدث event الذي صممناه لتغير لون الخلفية سوف يعمل مباشرة. ملخص في هذه المقالة قمنا باستذكار المصطلحات التي تساعدنا على فهم وتعديل DOM كما تعرفنا على البنية الشجرية لل DOM وأنواع العقد المستخدمة في إنشائها مثل عناصر html، النصوص، والتعليقات. كما قمنا في النهاية بإنشاء سكربت يسمح للمستخدم بتعديل شكل الموقع من دون الحاجة إلى إدخال التعليمات يدويًا إلى تبويبة console. هذه المقالة هي ترجمة للمقالة Understanding the DOM Tree and Nodes وكاتبتها Tania Rascia
  4. dom

    مقدمة إن نموذج تمثيل المستند ك جسم أو كائن Document Object Model والذي يشار له اختصارا ب DOM يعتبر أحد الطرق الأساسية في بناء مواقع متفاعلة فيما بينها، حيث تُعتبر هذه الطريقة واجهة تسمح للغات البرمجة بمعالجة محتوى المواقع وهيكليتها. أحد اللغات المرتبطة بالـ DOM في المتصفحات هي الجافا سكربت وذلك لأنها لغة برمجة تعمل في مواقع الويب من جهة المستخدم client-side. حيث يمكن الاستفادة من مفاهيم DOM في بناء مواقع ويب متفاعلة مثل إضافة عرض صور للموقع من خلال شاشة عرض بطريقة تدوير الصور، أو إظهار لافتة تنبّه المستخدم إلى وقوعه في خطأ عند محاولته إدخال معلومات ناقصة ضمن الحقول المطلوبة، أو التبديل في قوائم التصفح الخاصة بالموقع ويتم تنفيذ هذه العمليات الثلاث من خلال لغة الجافاسكربت ولكن من خلال معالجة DOM. في هذا المقال سنتعلم ماهو DOM وكيفية التعامل معه من خلال تعريف كائن object هو document والتمييز بين أسطر التعليمات المكتوبة بلغة HTML وبين DOM. ملاحظة: لاتعتبر DOM لغة برمجة كما الحال في لغات البرمجة الاعتيادية كالجافا أو الجافا سكربت... حيث يتم تنفيذ وتطبيق مفاهيمها من خلال لغات برمجة أخرى وهنا سنستخدم لغة الجافا سكربت. المتطلبات الأساسية لفهم كيفية تطبيق مفاهم DOM بشكل فعال وتنفيذه في تطبيقات الويب من المهم أن تكون لديك معرفة سابقة بـ HTML و CSS بالإضافة إلى معرفة القواعد الأساسية حول طريقة كتابة تعليمات الجافا سكربت وهيكليتها. ما هي DOM للبدء ببناء أي موقع ويب مهما كان بسيط سنبدأ أولًا بإنشاء مستند HTML، حيث يقوم برنامج المتصفح الذي يستخدمه الزائر لمشاهدة الموقع بتفسير تعليمات html و CSS وتحويلهم إلى المحتوى، الهيكلية والتصميم الذي نشاهده أمامنا في الصفحة النهائية. بالإضافة لذلك يقوم المتصفح ببناء تمثيل للمستند يُعرف بأنه نموذج كائن المستند Document Object Model ويسمح هذا النموذج للجافا سكربت بالوصول إلى المحتوى المُعبّر عنه كنص text أو كعناصر element ضمن المستند ورؤيتها على شكل أغراض objects. ولسهولة فهم هذا المفهوم الجديد سنتعرف عليه من خلال مثال عملي يبدأ بتطوير موقع بسيط وذلك بإنشاء ملف جديد يسمى index.html ثم حفظه ضمن مجلد المشروع project directory <!DOCTYPE html> <html lang="en"> <head> <title>Learning the DOM</title> </head> <body> <h1>Document Object Model</h1> </body> </html> إن أسطر التعليمات السابقة هي أساسيات HTML لبناء موقع ويب. سنستخدم هنا متصفح Chrome ولكن يمكنك الوصول إلى نفس الخرج من خلال المتصفحات الحديثة الأخرى. أولًا سنقوم بفتح ملف index.html الذي قمنا ببنائه من خلال متصفح chrome عندها سيظهر أمامك صفحة ويب فارغة وتحوي فقط عنوان هو "Document Object Model" ومن خلال النقر بالزر اليميني في أي مكان بالصفحة ستظهر لدينا قائمة نختار منها "Inspect" والتي ستفتح لنا على جانب الصفحة أدوات التطوير، سيظهر لدينا DOM تحت تبويب "Elements" في هذه الحالة نلاحظ أن DOM الذي قمنا بإظهاره مطابق تمامًا لتعليمات html التي كتبناها سابقًا لبناء الموقع، وعند تمرير السهم فوق العنصر سنلاحظ أن مايقابله من صفحة الويب المفتوحة أمامنا ستُظلّل باللون الأزرق، كما أن السهم الموجود على جانب كل عنصر يسمح بتوسيع العناصر المكتوبة بالداخل. كائن المستند Document كائن المستند document هو عبارة عن كائن مُدمج يملك عدد من الخصائص properties والطرق methods التي يمكن استخدامها للوصول إلى الموقع وتعديله. لفهم كيفية عمل DOM يجب أولًا فهم كيف تعمل الكائنات objects في الجافا سكريبت، ويمكن ذلك من خلال الإطلاع على مقالة برمجة الكائنات Objects في جافاسكريبت في أدوات التطوير التي أظهرناها سابقًا بجانب ملف index.html ننتقل إلى التبويبة "Console" ونكتب document داخل console ثم نضغظ زر Enter حيث نلاحظ أن الخرج هو نفسه الخرج الموجود في تبويبة "Elements" document; Output #document <!DOCTYPE html> <html lang="en"> <head> <title>Learning the DOM</title> </head> <body> <h1>Document Object Model</h1> </body> إن كتابة المستند document أو العمل مباشرة في تبويب console ليست أمرًا شائعًا نقوم به خارج debugging ولكنه يساعد في ترسيخ مفهوم كائن المستند document وكيفية تعديله ومعرفه العناصر الأخرى المدرجة ضمنه. ماهو الفرق بين DOM وتعليمات HTML حاليًا في المثال السابق الذي طرحناه تبدو لنا DOM كما لو أنها تعليمات HTML نفسها ولكن يوجد أمثلة يقوم فيها المتصفح بتوليد DOM مختلف عن تعليمات HTML مثل: تعديل DOM من خلال تعليمات الجافا سكربت والتي يتم تنفيذها في جانب المستخدم. قيام المتصفح بتصحيح الأخطاء الموجودة في التعليمات HTML المكتوبة سابقًا بشكل تلقائي. سنقوم الآن باكتشاف آلية تعديل DOM من خلال استخدام الجافا سكربت التي تُطبق في جانب المستخدم. أولًا ندخل في console التعليمة document.body; عندها سيكون الخرج: Output <body> <h1>Document Object Model</h1> </body> سنلاحظ هنا أن document هو عبارة عن كائن أما body فهو خاصية property لهذا الكائن لذلك من للوصول إلى هذه الخاصية نكتب اسم الكائن ثم نقطة ثم الخاصية document.body عندها سيكون الخرج هو جميع عناصر body الموجودة في المستند document. نستطيع من خلال console تغيير بعض الصفات الظاهرة في الكائن body في هذا الموقع فمثلًا يمكن تغيير صفات style الخاصية بالـ body مثل تغيير لون الخلفية ويتم ذلك من خلال التعليمة document.body.style.backgroundColor = 'fuchsia'; بعد كتابة هذه التعليمة وإدخالها سنلحظ تغير لون خلفية الموقع للون الفوشيا: بالانتقال إلى تبويبة "Elements" أو من خلال كتابة تعليمة document.body في console مرة أخرى سنلاحظ أن DOM قد تغير Output <body style="background-color: fuchsia;"> <h1>Document Object Model</h1> </body> ملاحظة: رأينا في المثال السابق عند تغيير لون الخلفية أن خاصية لون الخلفية في CSS والذي يكتب بالشكل background-color تمت كتابته بالشكل backgroundColor في الجافا سكربت وبنفس هذا الترتيب فإن أي خاصية في CSS يمكن كتابتها في الجافا سكربت بطريقة camelCase والتي تعني أن الحرف الأول من الكلمة الأولى صغير بينما الحرف الأول من الكلمة الثانية كبير. عند الضغط بالزر اليميني على الصفحة واختيار "View Page Source" سنلاحظ أن التعليمات الظاهرة لاتحوي على الصفة attribute الجديدة للون الخلفية الذي أضفناه من خلال الجافا سكربت وذلك لأن التعليمات الأساسية الموجودة في جانب الخادم Server التي تم بناء الموقع من خلالها لاتتأثر بأي تعليمات كتبت في جانب المستخدم بلغة الجافا سكربت، ولذلك في حال قمنا بتحديث الصفحة فإن الخاصية التي أضفناها ستُلغى. بالنسبة للحالة الأخرى التي ذكرناها عن اختلاف DOM و تعليمات HTML وهي عندما يتم تصحيح الأخطاء المكتوبة في التعليمات source code آليًا من قبل المتصفح، كمثال شائع فإن الوسم tbody يجب أن يرافق الوسم table دائمًا ولكن غالبًا لايقوم المطورون بتضمين هذه الوسوم بالشكل الصحيح ضمن HTML وعندها يقوم المتصفح تلقائيًا بتصيح هذا الخطأ وإضافة الوسم tbody وبالتالي يتم تغيير DOM. بالإضافة إلى ذلك دائمًا يصحح DOM الوسوم التي لايتم إغلاقها. ملخص عرضنا في هذه المقالة تعريف للـ DOM واستطعنا الوصول إلى كائن المستند document باستخدام الجافا سكربت وconsole من أجل تغيير خصائص تابعة للكائن document، كما تعرفنا على الفرق بين HTML و DOM. أما في المقالة التالية سنقوم باستعراض معلومات مهمة عن HTML وشجرة DOM وكيفية التعامل مع عقدها Nodes وماهي الأنواع الشائعة منها. ترجمة بتصرف للمقال Introduction to DOM وكاتبتها Tania Rascia
  5. تحدثنا في الدرس السابق عن انتقال وتحول العناصر باستخدام CSS3، وفي هذا الدرس سنتحدث عن التّحريك: التحريك Animation تقوم خاصية الانتقالات transition في CSS3 بعمل عظيم من خلال بناء التفاعلات البصرية عند الانتقال من حالة إلى أخرى وهي مثالية من أجل هذا النوع من التّغييرات المبنية على تغيّر وحيد، ولكن عند الحاجة إلى مزيد من التّحكم مثل الحاجة إلى الانتقال بين عدة حالات عندها يتم استخدام التحريك animation. تحديد إطارات العمل الرئيسية Keyframes للبدء بعملية التحريك باستخدام CSS3 يجب أولًا تحديد عدة نقاط أساسية يمر بها العنصر بشكل إجباري، ولتنفيذ ذلك نستخدم القاعدة @keyframes والتي تتضمن اسم التحريك animation name ونقاط التحريك الأساسية وخصائصهم المساهمة في تحريك العنصر. @keyframes slide { 0% { left: 0; top: 0; } 50% { left: 244px; top: 100px; } 100% { left: 488px; top: 0; } } ملاحظة: لابد من استخدام البادئات التي تدعم المتصفحات vendor prefixing مع القاعدة keyframe، كما هو الحال في جميع خصائص الانتقالات والتحريك، حيث سيكون شكل البادئات بالشكل التالي: @-moz-keyframes @-webkit-keyframes @-o-keyframes نلاحظ أنه تمّ تعريف عنصر الحركة animation بالإسم slide وذكر اسمه مباشرة بعد اسم القاعدة keyframes@ كما تم تحديد الإطارات المختلفة لهذا التحريك من خلال تحديد عدة نقاط أساسية ضمن الإطار هي النسب المئوية ابتداءًا بالقيمة 0% إلى القيمة 100% مع ذكر 50% كقيمة وسطية، أما الكلمات المفتاحية From وto فتُستخدم للتبديل بين مكاني الـ %0 و %100 كما نريد. كما أنه يمكن استخدام نقاط متوسطة إلى جانب النقطة الموجودة عند الـ %50. وقد تم إدراج خصائص العنصر الذي نقوم بتحريكه كقائمة داخل كل نقطة من نقاط التحريك كما فعلنا في المثال السابق حيث اعتبرنا أن left و top هي الخصائص. وتتم عملية التحريك animation من خلال تطبيق الانتقال transition بين النقاط الأساسية التي حددنا في الأعلى من خلال النسب المئيوة ولكن لأكثر من مرة (في هذه الحالة نطبق انتقال أول بين 0% و50% ثم آخر إلى 100%) سنقوم بتطبيق التحريك على الكرة الخضراء والتي يتم بناؤها في html: <div class="stage"> <figure class="ball"></figure> </div> والنّتيجة كما في الشّكل التّالي: وسنشرح الآن بالتفصل طريقة إضافة خصائص العناصر للوصول إلى عملية التحريك السابقة. خاصية الاسم Animation Name الآن بعد أن حددنا الإطار الأساسي للتحريك، نحتاج إلى إسناد هذا التّحريك المعرف للعنصر، ولفعل ذلك نستخدم الخّاصية animation-name التي تقوم على تعريف القاعدة keyframe@ كقيمة لهذه الخاصية، مع العلم أن هذا التّعريف يتم على العنصر الذي نريد تطبيق الحركة عليه. .stage:hover .ball { animation-name: slide; } نلاحظ أننا أسندنا الإطار الرّئيسي لعملية التّحريك slide الّذي عرفنّاه في الأعلى إلى كلا الصّفّين المحددين لرسم الكرة stage و ball ولكن تحديد قيمة animation-name فقط ليس كافٍ بل يجب تحديد خاصية animation-duration مع قيمتها لإخبار المتصفح الوقت الذي يحتاجه لإنهاء الحركة animation. مدة التحريك animation duration، تابع التوقيت Timing Function والتأخير Delay عندما نقوم بالتصريح عن الخاصية animation-name لعنصر ما فإن طريقة التّحريك ستكون مشابهة بشكل كبير للانتقال transition، حيث يحتاج لإكمال تعريفه إلى خصائص تحديد الفترة الزّمنية، تابع التوقيت، والتأخر الممكن أن يحصل. لبدء عملية التّحريك نحتاج إلى تعريف الخاصية animation-duration والّتي تشبه خاصية الفترة الزّمنية المستخدمة في الانتقالات transition حيث نحدد هذه الفترة باستخدام الثّانية او أجزاء الثّانية. .stage:hover .ball { animation-name: slide; animation-duration: 2s; } كما يمكن تحديد تابع التّوقيت animation-timing-function وقيمة التّأخير animation-delay على التّتالي. وتشبه هذه الخصائص مثيلاتها من الخصائص المستخدمة في الانتقالات، إن قيمة هذه الخّاصيات تعمل بشكل مشابه لعملها في الانتقالات transitions. .stage:hover .ball { animation-name: slide; animation-duration: 2s; animation-timing-function: ease-in-out; animation-delay: .5s; } في المثال القادم تقوم خاصية التحريك على جعل الكرة ترتد مرة خلال الحركة نحو اليسار، وهذا التصرف يحدث فقط في حال تم تمرير المؤشر فوق stage. أولًا نبين الكرة من خلال التعليمات: <div class="stage"> <figure class="ball"></figure> </div> أما تعليمات التحريك في CSS3 فهي: @keyframes slide { 0% { left: 0; top: 0; } 50% { left: 244px; top: 100px; } 100% { left: 488px; top: 0; } } .stage { height: 150px; position: relative; } .ball { height: 50px; position: absolute; width: 50px; } .stage:hover .ball { animation-name: slide; animation-duration: 2s; animation-timing-function: ease-in-out; animation-delay: .5s; } ونتيجة هذه التعليمات تظهر حركة الكرة بالشكل تخصيص التحريك: يتيح التّحريك إمكانية تخصيص الطّريقة التي يتصرف فيها العنصر، مثلًا، عدد مرات تكرار التّحريك والجّهة التي ينتهي إليها التحريك. تكرار التحريك: افتراضيًا يتم تنفيذ التحريك المعرّف مرة واحدة فقط من بدايته لنهايته، ولجعل هذا التّحريك يعيد نفسه عددًا من المرات نستخدم خاصية animation-iteration-count، حيث أن القيمة المعطاة لهذه الخّاصية ممكن أن تكون عدد صحيح محدد أو infinite والتي تعني استمرار التنفيذ عدد لانهائي من المرات. .stage:hover .ball { animation-name: slide; animation-duration: 2s; animation-timing-function: ease-in-out; animation-delay: .5s; animation-iteration-count: infinite; } نلاحظ أننا وضعنا قيمة التّكرار لانهاية وبالتّالي سيتم التّكرار بشكل دائم. اتجاه التحريك: بالإضافة إلى امكانية تحديد عدد مرات تكرار تحريك العنصر، يمكن أيضًا تحديد اتجاه الحركة الكلي باستخدام خاصية animation-direction والتي تأخذ القيم: Normal: والتي تقوم بتشغيل التحريك كما هو محدد من البداية للنهاية Reverse: وتقوم بتشغيل التحريك عكس المعرف من خلال القاعدة @keyframes أي ستكون البداية من 100% ثم تعمل بالعكس وصولًا إلى نقطة التعريف 0% Alternate: وتقوم بتشغيل التحريك نحو الأمام أي من النقطة 0% إلى النقطة 100% ثم العودة إلى الخلف من النقطة 100% إلى 0% ويمكن تحديد عدد مرات تكرار هذه الطريقة من خلال الخاصية animation-iteration-count التي يمكن أن تكون عدد صحيح من المرّات ويبدأ العد من الرقم 1. ولكن هذه الخاصية ستعمل بالعكس عند تشغيل أي تابع في خاصية animation-timing-function أي في حال استخدمنا ease-in فسيكون اتجاه الحركة من 0% إلى 100% أمّا إذا استخدمنا ease-out فعندها سيكون التحريك من 100% إلى 0%. Alternate-reverse: تجمع بين alternate و reverse حيث يكون اتجاه الحركة عند تنفيذ التحريك هي بالعكس أي من 100% إلى 0% ثم العودة مرة أخرى 100%. .stage:hover .ball { animation-name: slide; animation-duration: 2s; animation-timing-function: ease-in-out; animation-delay: .5s; animation-iteration-count: infinite; animation-direction: alternate; } بناءً على التعليمات السابقة سيتم التحريك من البداية نحو النهاية بحسب قيمة خاصية الاتجاه alternate وسيتم التكرار عدد لانهائي من المرات، أما شكل تابع الحركة فهو ease-in-out حالة تحريك العنصر: إن خاصية animation-play-state تتيح تشغيل وإيقاف التّحريك باستخدام القيم running وpaused بالتتالي، حيث أن طريقة عمل هذه الخاصية أنه عندما نشغل عنصر حركة وهو بحالة ايقاف paused، فإنه سيستمر من الحالة الحالية بدلًا من أن يبدأ من البداية من جديد. في هذا المثال، خاصية animation-play-state ستضبط عند paused، عند تفعيل حالة الحركة لدى الدائرة بالضغط عليها سنلاحظ كيف يتوقف عنصر التحريك حتى نقوم بتحرير المؤشر. .stage:hover .ball { animation-name: slide; animation-duration: 2s; animation-timing-function: ease-in-out; animation-delay: .5s; animation-iteration-count: infinite; animation-direction: alternate; } .stage:active .ball { animation-play-state: paused; } وتظهر النتيجة كما في الشكل: خاصية Fill Mode: تحدد خاصية animation-fill-mode هيئة العنصر قبل وبعد تشغيل التحريك.إن هذه الخاصية تقبل القيم: none أي لا يتم تطبيق أي تغيير على العنصر قبل أو بعد تشغيل التحريك. forwards ستحتفظ بالهيئة المحددة للعنصر بآخر إطار keyframe كان داخله العنصر وبالتالي سنلاحظ أن هذه الحالة تتأثر بقيم خصائص أخرى، هي خاصية اتجاه الحركة animation-direction وعدد مرات التكرار animation-iteration-count. backwards ستطبق الهيئات عند أول إطار رئيسي مباشرة عند تعريف هذه الخاصية قبل بدء تنفيذ التحريك. وهذا يتضمن تطبيق هذا الشكل في أي وقت قد يكون تم ضبطه من خلال خاصية التأخير. مع العلم أن هذه القيمة تتأثر بخاصية الاتجاه animation-direction. both تجمع بين القيمتين forwards و backwards معًا. .stage:hover .ball { animation-name: slide; animation-duration: 2s; animation-timing-function: ease-in-out; animation-delay: .5s; animation-fill-mode: forwards; } .stage:active .ball { animation-play-state: paused; } وسيظهر شكل حركة الدّائرة هكذا: اختزال تعليمات التحريك: لحسن الحظ يمكن تحديد صيغة مختصرة لعناصر التحريك، كما هو في الانتقالات. ويتم ذلك باستخدام الخاصية animation حيث يمكن ترتيب القيم التابعة للخصائص الأخرى داخل الخاصية animation بالشكل التالي: animation-name animation-duration animation-timing-function animation-delay animation-iteration-count animation-direction animation-fill-mode animation-play-state حيث يمكن اختزال التعليمات في الأمثلة السابقة إلى الشكل: .stage:hover .ball { animation: slide 2s ease-in-out .5s infinite alternate; } .stage:active .ball { animation-play-state: paused; } وكما نلاحظ أنه لايتم الفصل بين قيم الخصائص بفاصلة أبدًا. ترجمة-بتصرف- لمقال: Transition & Animation
  6. أهم التّطورات التي ظهرت في CSS3 هي القدرة على نقل العنصر من شكل أو مكان لآخر بالإضافة إلى تحريكها ضمن مجموعة من الخطوات المتسلسلة. منذ عدة سنوات يطالب المبرمجون العاملون في تطوير واجهات الإنترنت بإدخال ميزة القدرة على إدخال تفاعلات وتحريك العناصر من خلال html و CSS من دون الحاجة للدخول في الجافاسكربت أو الفلاش، وقد أصبحت هذه الإمكانية ممكنة الآن في CSS3. طريقة عمل انتقال العناصر transitions هي من خلال تغيير طريقة ظهور أو هيئة العنصر نفسه عند وقوع حدث معين مثل النقر على العنصر أو مرور المؤشر عليه مثلًا أي هو تغير حالة العنصر إلى حالة أخرى، أما طريقة التحريك Animation فهي تغيير مكان العنصر أو هيئته لأكثر من مرة ويتم من خلال اختيار مجموعة من النقاط الممكنة ضمن الإطار الرئيسي للصفحة ويتم تغيير مظهر أو حالة العنصر. الانتقالات Transition: كما ذكرنا سابقًا يتم تنفيذ عملية الانتقال للعنصر من خلال تغيير حالة العنصر، حيث يجب تعريف كل حالة والتصميم style الذي سيُطبق على العنصر في هذه الحالة، وأسهل طريقة لتحديد الحالة التي يقع فيها العنصر الآن والتصميم الذي يجب أن يأخذه من خلال استخدام صفوف اللاحقة pseudo-classes وهي :target - :active - :focus - :hover ويوجد أربع خصائص مرتبطة بالانتقال transition بشكل عام وهي transition-property، transition-duration، transition-timing-function و transition-delay مع ملاحظة أنه يمكن استخدام البعض منها فقط لبناء عملية الانتقال. سنستعرض في المثال التالي طريقة الانتقال الّتي ستتم لمدة ثانية واحدة من خلال تغيير لون خلفية المربع المرسوم عند تمرير المؤشر فوقه: نبني المربع ككتلة div من خلال تعليمة html <div class="box">Box</div> و لتنفيذ الانتقال على المربع المرسوم يتم ذلك من خلال تعليمات CSS فقط وهي: .box { background: #2db34a; transition-property: background; transition-duration: 1s; transition-timing-function: linear; } .box:hover { background: #ff7b29; } حيث يظهر المربع باللون الأخضر وعند تمرير المؤشر فوقه يتغير لون خلفية المربع وتم تحديد ذلك من خلال الخاصية transition-property لمدة ثانية واحدة فقط وتم تخصيص الزمن من خلال الخاصية transition-duration ويمكن معاينة المثال بشكل مباشر من الرابط. ومن الأفضل كتابة التعليمات من خلال إضافة vendor prefixes والتي تعمل على تأمين دعم كافة المتصفحات .box { background: #2db34a; -webkit-transition-property: background; -moz-transition-property: background; -o-transition-property: background; transition-property: background; -webkit-transition-duration: 1s; -moz-transition-duration: 1s; -o-transition-duration: 1s; transition-duration: 1s; -webkit-transition-timing-function: linear; -moz-transition-timing-function: linear; -o-transition-timing-function: linear; transition-timing-function: linear; } .box:hover { background: #ff7b29; } خاصية transition-property تحدد خاصية transition-property خصائص العنصر التي سوف يتم تعديلها تزامنًا مع تنفيذ خصائص الانتقال الأخرى، ولايتم تغييير قيمة أي خاصية أخرى للعنصر غير مذكورة ضمن هذه الخاصية. في المثال السابق تم تغير قيمة background التابعة للعنصر لأنها ذكرت كقيمة للـ transition-property خلال زمن قدرة ثانية واحدة، في حين أن الخصائص الأخرى للعنصر ستبقى محافظة على قيمتها ولن تتأثر بالقيم المعطاة للـ transition-duration وtransition-timing-functionفي حال كنا نريد تغيير قيمة أكثر من خاصية عند تطبيق الانتقال يمكن إدراجها في الخاصية نفسها transition-property مع وضع فواصل فيما بينها. .box { background: #2db34a; border-radius: 6px transition-property: background, border-radius; transition-duration: 1s; transition-timing-function: linear; } .box:hover { background: #ff7b29; border-radius: 50%; } نلاحظ أن الخصائص التي نريد تغييرها عند الانتقال هيَّ background و border-radius وتم تحديد الانتقال بـ .box:hover حيث يتم تنفيذها كما في الّشكل: خصائص العنصر القابلة للانتقال ليست كل خصائص العنصر قابلة للتّغيير وإنما فقط تلك العناصر التي يمكن ملاحظة التّغيير الذي يطرأ عليها مثل الألوان، والحجم. حيث يمكن أن تتبدل من قيمة إلى أخرى. مثلًا لا يمكن تغيير الخاصية display لأنها لاتمتلك نقطة تعريف يمكن ملاحظة التغيير الذي يحصل من خلالها. أهم الخصائص التي يمكن تطبيق الانتقال عليها: background-color background-position border-color border-width border-spacing bottom clip color crop font-size height left letter-spacing line-height margin max-height max-width min-height min-width opacity outline-color outline-offset outline-width padding right text-indent text-shadow top vertical-align visibility width word-spacing z-index خاصية transition-duration يتم تعيين المدة الزمنية التي تتم فيها عملية الانتقال باستخدام خاصية transition-duration وتحديد قيمتها من خلال استخدام وحدات الزمن العامة بما في ذلك الثانية (s) والميلي ثانية (ms) كما يمكن أن تكون القيمة عبارة عن كسور مثل أجزاء من الثانية (0.2s). عندما يُطبق الانتقال على أكثر من خاصية للعنصر يمكن أن يتم تطبيق قيمة فترة زمنية محددة لكل خاصية، أي كما تحتوي خاصية transition-property على أكثر من قيمة يمكن أن تحتوي خاصية transition-duration أيضًا على أكثر من قيمة، وكل خاصية تأخذ المدة الزمنية حسب ترتيب قيم الخصائص (في المثال الذي سنستعرضه ستكون الفترة الزمنية 0.2s تابعة لخاصية background، أما خاصية border-radius فستكون لمدة ثانية واحدة) ويمكن أيضًا أن نُعطي مدة زمنية واحدة لجميع الخصائص المراد تغييرها. .box { background: #2db34a; border-radius: 6px; transition-property: background, border-radius; transition-duration: .2s, 1s; transition-timing-function: linear; } .box:hover { background: #ff7b29; border-radius: 50%; } والنتيجة تكون واضحة كما في الصورة: خاصية سرعة الانتقال Transition Timing تُستخدم خاصية transition-timing-function لضبط سرعة الانتقال. حيث يمكننا تحديد المدة الزمنية من خلال الخاصية transition-duration. ويمكن إعطاء خاصية transition-timing-function عدة قيم هي: liner: عند إعطاء الخاصية المذكورة هذه القيمة فإن الانتقال بسرعة ثابتة خلال المدة الزمنية المحددة. ease-in: تعني هذه القيمة أن الانتقال يبدأ ببطئ ويستمر بالتسارع طول فترة الانتقال. ease-out: تعني أن الانتقال يبدأ بسرعة ويستمر بالتباطؤ طوال فترة الانتقال. ease-in-out: الانتقال يبدأ ببطئ ويستمر بالتسارع حتى يصل إلى الوسط عندها يبدأ بالتباطؤ مرة أخرى حتى انتهاء المدة المحددة للانتقال. إن تابع الانتقال يُحدّد كتابع رياضي لمنحنى مكعب بيزيير، هذه التوابع الزمنية هي تابعة لمنحنى بيزيير ويمكن رسمها من خلال القيم (x1, y1, x2, y2) بالإضافة إلى قيمتَي نقطة البداية ونقطة النّهاية، أو من خلال الخطوات المحددة بشكل مميز، من خلال عدد الخطوات واتجاه الحركة. عندما يمتلك الانتقال عدة خصائص فإنه يتم تحديد عدة توابع لطريقة الانتقال، ففي مثالنا خاصية background كان تابعها هو linear أما خاصية border-radius فإن تابع الانتقال الخاص بها هو ease-in .box { background: #2db34a; border-radius: 6px; transition-property: background, border-radius; transition-duration: .2s, 1s; transition-timing-function: linear, ease-in; } .box:hover { background: #ff7b29; border-radius: 50%; } كما هو واضح في الصورة، أو يمكن رؤية المعاينة المباشرة من هنا. التأخير في الانتقال Transition Delay يمكن أيضًا تعريف خاصية transition-delay بأنها تتحكم بتأخير تحول العنصر، فمن خلالها يتم تحديد الزمن الذي سيتم تأخير تحول العنصر بمقداره، ويحدد بالثواني أو الملي. وكما هو الحال في جميع الخصائص الأخرى يمكن تحديد أكثر من قيمة منفصلة خاصة بالتأخير من خلال الفصل بينها بالفاصلة فقط. .box { background: #2db34a; border-radius: 6px transition-property: background, border-radius; transition-duration: .2s, 1s; transition-timing-function: linear, ease-in; transition-delay: 0s, 1s; } .box:hover { background: #ff7b29; border-radius: 50%; } نلاحظ عند تنفيذ التعليمات السابقة أن لون الخلفية تغير مباشرة بدون أي تأخير زمني، وأن قيمة التأخير الأولى المقابلة للخلفية هي 0 ثانية، بينما شكل الحدود وانحنائها تغير بعد ثانية واحدة. اختزال تعليمات الانتقال من الممكن أن يصبح ملف التعليمات كبيرًا جدًا في حال أضفنا تعليمات الانتقال بشكل فردي، وسيكون الوضع أسوأ لو أضفنا البادئات الخاصة بدعم المتصفحات vendor prefixes. ولحسن الحظ يوجد خاصية الاختزال لخصائص الانتقال، مع الاحتفاظ بالقدرة على احتواء كل الخصائص وقيمها. ويتم ذلك من خلال استخدام الخاصية transition فقط ونكتب فيها قيم الخصائص بالتّرتيب التّالي: transition-property transition-duration transition-timing-function transition-delay ولا يتم وضع فاصلة بين هذه القيم إلا إذا كنت تريد تعريف أكثر من انتقال. فمثلًا يمكن كتابة التعليمات من المثال السابق بشكل مختزل، بحيث نذكر الانتقال الأول وهو تغير لون الخلفية خلال 0.2 جزء من الثانية والحركة تتسارع صعودًا، ثم وضعنا فاصلة لذكر تفاصيل الانتقال الثاني وهو تغيير شكل حدود المربع لتصبح دائرية. .box { background: #2db34a; border-radius: 6px; transition: background .2s linear, border-radius 1s ease-in 1s; } .box:hover { color: #ff7b29; border-radius: 50%; } يوجد العديد من الأمثلة التي تبين طريقة استخدام CSS3 في الانتقالات وإضفاء طابع الحركة على العناصر من دون الحاجة إلى استخدام جافا سكربت، من هذه الأمثلة طريقة إنشاء زر يعطي انطباع الضغط عند النقر عليه. أولًا نبني الزر من خلال html <button>Awesome Button</button> ومن ثم نضيف تعليمات الانتقال على الزر من خلال CSS button { border: 0; background: #0087cc; border-radius: 4px; box-shadow: 0 5px 0 #006599; color: #fff; cursor: pointer; font: inherit; margin: 0; outline: 0; padding: 12px 20px; transition: all .1s linear; } button:active { box-shadow: 0 2px 0 #006599; transform: translateY(3px); } وتظهر المعاينة كمافي الصورة: ويمكن استخدام خاصية التحول لقلب العناصر إلى الاتجاه الآخر أيضًا، مثل قلب صورة إلى الجزء الخلفي منها. أولًا نكتب تعليمات بناء بطاقة الصورة من خلال html <div class="card-container"> <div class="card"> <div class="side"><img src="https://academy.hsoub.com/uploads/monthly_2016_01/SiteLogo-346x108.png.dd3bdd5dfa0e4a7099ebc51f8484032e.png" alt="أكاديمية حسوب"></div> <div class="side back">أكاديمية حسوب</div> </div> </div> ثم نبدأ بكتابة تعليمات تحريك البطاقة وقلبها إلى الجزء الآخر من خلال CSS3 .card-container { height: 108px; perspective: 600; position: relative; width: 346px; background: #444; } .card { height: 100%; position: absolute; transform-style: preserve-3d; transition: all 1s ease-in-out; width: 100%; } .card:hover { transform: rotateY(180deg); } .card .side { backface-visibility: hidden; height: 100%; position: absolute; width: 100%; } .card .back { transform: rotateY(180deg); } حيث تُقلب البطاقة إلى الوجه الآخر عند مرور المؤشر فوقها، ويمكن رؤية المعاينة من الرابط المباشر ترجمة-بتصرف- لمقال: Transition & Animation
  7. مستطيلات داخل مستطيلات هذا هو التصميم المعتمد عند الغالبية في بناء صفحات الويب الخاصة بنا، ولكننا نحاول الآن كسر هذه الصورة النمطية عن أشكال CSS من خلال استخدام أشكال هندسية جديدة، ولكن هذه الأشكال Shapes لا تتفاعل أبدًا مع محتوى الشكل أو مع العناصر الأخرى داخل الصفحة. يتم الآن وضع تخصيصات جديدة للأشكال في CSS لتغيّر من هذا الجمود في الأشكال. ففي منتصف عام 2012 وضعت شركة Adobe هدفًا جديدًا أمامها ألا وهو تزويد مصممي الويب بطريقة جديدة تغير من الطريقة النمطية في انسياب المحتوى داخل وحول الأشكال المعقدة - وهو أمر جديد تمامًا لم نكن قادرين في تطبيقه حتى باستخدام JavaScript. على سبيل المثال، ستلاحظ في التصاميم الجديدة التي تعتمد على الأشكال المتعددة انسياب النص حول الصور الدائرية بشكل سلسل وجميل، ولكن بدون هذه الأشكال سيتوضع النص بشكل مستطيل من دون أي تأثيرات إضافية، وبالتالي نجد أن هذه الطريقة الجديدة في التعامل مع الأشكال ستأخد التصاميم إلى مستوى جديد من التطور. دعم المتصفحات إن المتصفحات التي تدعم الأشكال CSS Shapes Module 1 بالنسبة لنسخة الحاسب حتى نهاية عام 2017 كانت Chrome، Firefox، Opera و (Safari(WebKit، بينما لايقدم متصفح Internet Explorer هذا الدعم. ويختلف الأمر بالنسبة لنسخة المتصفحات الخاصة بالموبايل حيث أن متصفح Safari هو فقط من يدعم خاصية الأشكال. ومع ذلك فقد وصلت تقنية الأشكال في CSS المرحلة الأولى منها إلى أن جميع المتصفحات تتعرف على طريقة كتابة تعريف الأشكال Syntax الخاصة بها وتخصيصها وبالتالي تعتبر برمجة الأشكال مستقرة جدًا ولن يكون الوقت طويلًا حتى يتم تنفيذها بشكل كامل على جميع المتصفحات. إن المرحلة الأولى من تطوير الأشكال في CSS يركز على الخصائص التي تغير من طريقة انسياب المحتوى حول الشكل أي أنها تركز على خاصية shape-outside بالإضافة إلى الخصائص الأخرى المتعلقة بها. ومن المتوقع أن استخدام هذه الميزة الجديدة في الأشكال عند CSS ودمجها مع الميزات الأخرى المتطورة مثل الإخفاء والقص Clipping and Masking، طريقة معالجة العنصر قبل عرضه CSS Filters، و مزج وتركيب العناصر معًا Compositing and Blending سيسمح لنا ببناء الأشكال وتصميمها بشكل احترافي متطور من دون الحاجة إلى المحررات المستخدمة في التصميم كالفوتوشوب و InDesign. سيركّز بناء الأشكال في CSS مستقبلًا على طريقة التفاف المحتوى داخل الشكل نفسه أيضًا. فعلى سبيل المثال، من السهل اليوم بناء المعين باستخدام CSS حيث يتوجب علينا فقط تدوير العنصر بزاوية 24 درجة ثم تدوير المحتوى داخله وبالتالي يعود المحتوى ليتوضع أفقيًا ضمن الصفحة. ولكن المعين لن يكون هو الأب الحاوي container للمحتوى، وبالتالي سيبقى المحتوى مستطيل الشكل. ولحل هذه المشكلة يمكن استخدام الخاصية shape-inside والتي تقوم بجعل المحتوى يأخذ شكل معين داخل التصميم أيضًا. بناء شكل باستخدام CSS يمكن تطبيق شكل على أي عنصر element من خلال استخدام خاصية الأشكال shape property. حيث نمرر خاصية الشكل كتابع shape function يمرر مجموعة من المعاملات parameters التي تعرف الشكل الذي نريد تطبيقه مثل نقطة المركز ونصف القطر إذا كان الشكل دائرة أو مجموعة من النقاط على المحيط إذا كان الشكل مضلعًا. من الأشكال التي يمكن بناؤها باستخدام التوابع التالية ()circle ()ellipse ()inset ()polygon حيث يعرف كل شكل من خلال مجموعة من النقاط. فبعض التوابع تمرر هذه النقاط كمعاملات، وبعضها الآخر يمرر نقطة واحدة ومقدار الإزاحات ولكن في النهاية جميعها ترسم الأشكال من خلال مجموعة من النقاط. حيث سنقوم بتعريف هذه المتحولات الممررة عند بنائنا للأشكال في المثال القادم من خلال هذه التوابع. كما يمكن تعريف الشكل من خلال استخراجه من صوة باستخدام قناة ألفا وذلك عند تمرير الصورة لخاصية الشكل حيث سيقوم المتصفح باستخراج الشكل بالاعتماد على shape-image-threshold. يُعرف أي شكل من خلال البكسلات التي تحوي قيمة ألفا أكبر من القيمة البدائية كما أن الصورة يجب أن تكون متوافقة مع شروط CORS وبالتالي في هذه الحالة إذا لم يتم إظهار الصورة في الصفحة لأي سبب (مثل أن تكون غير موجودة أو محذوفة) عندها ستيم إظهار شكل الإطار الخاص بها. خصائص الشكل shape proprties التي تقبل أن تمرر التوابع التي ذُكرت في الأعلى كقيمة لها هي: shape-outside: تقوم هذه الخاصية بتخصيص طريقة التفاف المحتوى حول الشكل من الخارج. shape-inside: تقوم هذه الخاصية بتخصيص طريقة التفاف المحتوى داخل الشكل. كما يمكن استخدام خاصية shape-outside بالتزامن مع استخدام خاصية shape-margin من أجل إضافة هامش حول الشكل الذي نخصص طريقة انسياب المحتوى حوله وبالتالي بناء فراغ صغير بين المحتوى والشكل. وبنفس الطريقة يمكن استخدام خاصية shape-padding مع خاصية shape-inside من أجل إضافة هامش داخلي بين المحتوى داخل الشكل وحدود الشكل. باستخدام خصائص الشكل وتوابعه يمكن تعريف الشكل كعنصر element من خلال إضافة سطر واحد من تعليمات CSS. .element { shape-outside: circle(); /* content will flow around the circle defined on the element */ } أو من خلال التعليمة التالية حيث ندخل لها رابط الوصول إلى الشكل الذي ستستخرج منه الشكل المطلوب. .element { shape-outside: url(path/to/image-with-shape.png); } ولكن عند تطبيق هذا السطر من تعليمات CSS على الشكل لن يظهر الشكل المطلوب إلا إذا تحقق الشرطين التاليين: يجب أن يكون العنصر element عائمًا floated حيث أنه من الممكن مستقبلًا أن نحدد الأشكال على العناصر غير العائمة ولكن ليس الآن. يجب أن يكون العنصر لديه أبعاد واضحة لأنه سيتم استخدام الارتفاع والعرض لبناء العنصر ضمن نظام الإحداثيات. يتم تعريف الأشكال من خلال مجموعة من النقاط لأنها تملك إحداثيات ديكارتية حيث أن نظام الإحداثيات الديكارتية هو الذي يُعرف من خلاله مواقع العناصر ضمن المتصفح لذلك عند تعريف العنصر element في المثال في الأعلى يتوجب علينا إضافة الارتفاع والعرض بشكل محدد. .element { float: left; height: 10em; width: 15em; shape-outside: circle(); } مع العلم أن إضافة هذه الأبعاد لا تؤثر على طريقة استجابة الشكل نفسه. وبما أن كل شكل يتم تعريفه بواسطة مجموعة من النقاط التي يتم وضعها باستخدام زوج من الإحداثيات فإن تغيير إحداثيات نقطة ما سيؤثر بشكل مباشر على الشكل الذي تم إنشاؤه. فمثلًا يمكننا إنشاء مضلع مسدس الشكل من خلال استخدام تابع ()polygon حيث يتكون الشكل من ست نقاط ولكن عند تغيير إحداثيات إحدى النقاط الأفقية (النقطة الملونة باللون البرتقالي) عندها سيتغير الشكل الناتج إلى شكل آخر وبالتالي سيؤثر على طريقة تدفق المحتوى داخل الشكل وخارجه. المربع المرجعي للأشكال يتم تعريف وبناء أي شكل يُرسم باستخدام CSS داخل ما يسمى بالمربع المرجعي الذي يستعمل لرسم الشكل على العنصر. يمتلك أي عنصر ارتفاع وعرض بالإضافة إلى مربع هامش الذي يحدد المسافة بين العنصر وباقي العناصر في الصفحة margin-box، مربع المحتوى content-box، مربع الهامش الداخلي الذي يحدد المسافة بين المحتوى وحدود الشكل padding-box، مربع الحدود border-box. حيث تُستخدم إحدى هذه المربعات كمرجع لرسم الشكل على العنصر. افتراضيًا يُستخدم مربع الهامش margin-box كنقطة البداية الأساسية لأي عنصر وبالتالي إذا أردنا تطبيق الشكل على العنصر سيتم أولًا إزاحة الشكل إلى الأسفل ثم تمديده من أسفل زاوية الهامش إلى باقي مربع الهامش margin-box. كما يمكن استخدام قيمة مربع أخرى كمرجع بالإضافة إلى مربع الهامش ويتم ذلك من خلال تمرير اسم المربع بجانب تابع الشكل ()circle إلى خاصية الشكل المُستخدمة shape-outside. shape-outside: circle(250px at 50% 50%) padding-box; الكلمة المفتاحية padding-box هي التي خصصت بأن الشكل سيتم تطبيقه على العنصر بالنسبة إلى منطقة الهامش الداخلية للعنصر، أما تابع ()circle فعرّف الشكل الدائري المراد رسمه من خلال ذكر حجمه ومكان توضعه. تعريف الأشكال باستخدام التوابع سنبدأ بمثال عن طريقة التفاف النص حول صورة شخصية لمستخدم دائرية الشكل مثل تلك الصور المستخدمة في الصفحات التعريفية عن الأشخاص حيث ستكون التعليمات في ملف HTML لبناء الصورة وكتابة المحتوى <img src="http://api.randomuser.me/0.3.2/portraits/men/7.jpg" alt="profile image" /> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Harum itaque nam blanditiis eveniet enim eligendi quae adipisci?</p> <p>Assumenda blanditiis voluptas tempore porro quibusdam beatae deleniti quod asperiores sapiente dolorem error! Quo nam quasi soluta reprehenderit laudantium optio ipsam ducimus consequatur enim fuga quibusdam mollitia nesciunt modi.</p> أما ضمن ملف CSS فسنستخدم تابع ()circle من أجل تطبيق الشكل الدائري على الصورة الشخصية التي وضعناها في ملف HTML. سنستخدم من أجل تدوير الصورة الخاصية border-radius حيث لا تمتلك هذه الخاصية أي تأثير على طريقة انسياب المحتوى داخل أو حول الصورة التي نطبق عليها الشكل. وبمعنى آخر لا تمتلك هذه الخاصية التأثير على منطقة المحتوى content area المتواجدة داخل العنصر element الذي قمنا ببنائه ولا على المحتوى الخارجي حول العنصر، وإنما يكون تأثيرها فقط على شكل الحدود الخاصة بالعنصر وخلفيته إن وُجدت. أي سيبقى المحتوى داخل العنصر مستطيل الشكل والمحتوى الموجود خارج العنصر سينظر ويتعامل مع العنصر نفسه كما لوكان مستطيل الشكل. أي أننا نقوم باستخدام الخاصية border-radius من أجل جعل الصورة فقط دائرية الشكل. img { float: left; width: 150px; height: 150px; border-radius: 50%; margin-right: 15px; } تبين الصورة السابقة الشكل الذي سيظهر به المحتوى حول الصور الدائرية في المتصفحات القديمة التي التدعم الأشكال في CSS، ولتغيير هذا الشكل المربع في الانسياب حول الصورة الدائرية سنقوم بتعديل التعليمات بما يتوافق مع الشكل الذي أضفناه من خلال استخدام خصائص الشكل img { float: left; width: 150px; height: 150px; border-radius: 50%; shape-outside: circle(); shape-margin: 15px; } حيث سنرى في صفحة الويب عند استخدام هذه التعليمات شكلًا دائريًا مُطبّقًا على الصورة وسيظهر المحتوى ملتفًا حول الدائرة كما في أول صورة شاهدناها في المثال. الطريقة الأساسية في استخدام تابع الدائرة هي circle() = circle( [<shape-radius>]? [at <position>]? ) إن علامة الاستفهام ? في التعليمة السابقة تشير إلى أن هذه المعاملات الممررة اختيارية ولكن في حال عدم تمريرها سيأخذ التابع القيمة الافتراضية الموجودة في المتصفح وهي رسم الشكل ابتدءًا من مركز العنصر الذي نطبق عليه الشكل. يتم تحديد طول نصف قطر الدائرة بأحد وحدات الطول (البكسل px، النقطة pt…) ويقوم المتصفح برسمه ابتداءً من نقطة المركز وصولًا إلى إحدى أضلاع المستطيل المرجع ويحدد ذلك الخاصية خاصية closest-side: وهي الخاصية الافتراضية وتعني رسم نصف القطر وصولًا إلى أقرب ضلع من أضلاع المستطيل. خاصية furthest-side: وتعني أن المتصفح سيرسم نصف القطر وصولًا إلى أبعد ضلع من أضلاع المستطيل يمكن تحديد هذه الخاصية وتمريرها كمعامل لتابع رسم الدائرة عند خاصية shape-outside shape-outside: circle(farthest-side at 25% 25%); /* defines a circle whose radius is half the length of the longest side, positioned at the point of coordinates 25% 25% on the element’s coordinate system*/ shape-inside: circle(250px at 500px 300px); /* defines a circle whose center is positioned at 500px horizontally and 300px vertically, with a radius of 250px */ يعمل تابع رسم الإهليلج (القطع الناقص) ()ellipse فهو يعمل بنفس الطريقة التي يعمل فيها تابع ()circle وبنفس القيم ماعدا أنه بدلًا من تمرير تابع واحد لنصف القطر يجب تمرير اثنين أحدهما من أجل طول نصف القطر على محور الإحداثيات X والآخر لنصف القطر على محور الإحداثيات Y ellipse() = ellipse( [<shape-radius>{2}]? [at <position>]? ) في حيث أن تابع ()inset يُستخدم لرسم شكل مستطيل مدور الزوايا ويمكن أن نجعل المحتوى ينساب حول هذه الزوايا بشكل دائري أيضًا. ونمرر لتابع ()inset: أربع قيم إزاحة تحدد قيمة إزاحة الحواف بالنسبة لصندوق المرجع نحو داخل العنصر. معامل اختياري وهو قيمة تدوير الزوايا round حيث يتم تحديد القيمة من خلال border-radius بنفس طريقة استخدامها في تدوير الدائرة التي شرحناها سابقًا، ولكن هنا يجب تمرير أربع قيم. inset() = inset( offset{1,4} [round <border-radius>]? ) من خلال التعليمات التالية سنقوم برسم مستطيل دائري الزاويا على عنصر عائم floated element .element { float: left; width: 250px; height: 150px; shape-outside: inset(0px round 100px) border-box; } تابع الأشكال الأخير الذي سنتحدث عنه هو ()polygon الذي يعرف مجموعة معقدة من الأشكال الهندسية من خلال تحديد عدد من النقاط المعرفة بإحداثياتها الديكارتية (point(x,y والتي من خلالها يتحدد موقع النقطة ديكارتيًا على المتصفح. في المثال التالي نشاهد صورة عائمة في يمين الصورة وتغطي ارتفاع كامل مساحة العرض المتاحة لها، ونريد أن نظهر النص الذي على يسارها بشكل انسيابي حول الساعة الرملية الموجودة داخل الصورة ولذلك سنستخدم تابع ()polygon من أجل تعريف هذا الشكل غير المنتظم على الصورة. تعليمات CSS التي ستقوم بهذه العملية هي img.right { float: right; height: 100vh; width: calc(100vh + 100vh/4); shape-outside: polygon(40% 0, 100% 0, 100% 100%, 40% 100%, 45% 60%, 45% 40%); } يمكن تعيين إحداثيات النقط التي تعرف الشكل من خلال وحدات الطول أو من خلال النسب المئوية التي استخدمتها. ستُنتج التعليمات السابقة الشكل الذي شاهدناه في الأعلى حيث أنها لا تؤثر على باقي أجزاء الصورة الموجودة خارج الشكل المرسوم كما نلاحظ، لأن تطبيق شكل العنصر فقط يؤثر على منطقة تدفق المحتوى من دون أن يغيّر أي شيء في الخلفيات والحدود. ومن أجل إظهار شكل المضلع الذي رسمناه فإننا بحاجة إلى قص أجزاء من الصورة خارج الشكل وذلك من خلال استخدام خاصية clip-path الموجودة في نموذج الإخفاء CSS Masking Module. تقوم خاصية clip-path على أخذ نفس شكل التابع المستخدم والقيم الممررة له. وبالتالي إذا استخدامنا نفس الشكل المضلع الذي مررناه للخاصية shape-outside فإن هذه الخاصية ستعمل على قص كل أجزاء الصورة خارج الشكل المحدد img.right { float: right; height: 100vh; width: calc(100vh + 100vh/4); shape-outside: polygon(40% 0, 100% 0, 100% 100%, 40% 100%, 45% 60%, 45% 40%); /* clip the image to the defined shape */ clip-path: polygon(40% 0, 100% 0, 100% 100%, 40% 100%, 45% 60%, 45% 40%); } وستكون النتيجة النهائية لهذه التعليمات كما في صورة في الوقت الحالي يتم دعم خاصية clip-path من خلال إضافة بادئة إليها أولًا، مثلًا ستعمل هذه الخاصية مع Chrome إذا أضفنا لها -webkit-. إن خاصية clip-path هي أفضل إضافة مع خصائص الأشكال الأخرى لأنها تساعد في إظهار الأشكال المُنشأة من خلال قص أي جز من العناصر خارج الشكل. تابع()polygon يأخذ أيضًا خيارًا آخر هو إما nonzero أو evenodd والتي تحدد كيفية التعامل مع المناطق داخل الشكل المضلع التي تتقاطع مع نفسها ولمعرفة المزيد عن هذه الخصائص يمكن الإطلاع على SVG fill-rule تعريف شكل باستخدام صورة لتعريف شكل باستخدام صورة نحتاج إلى صورة من نمط ألفا والتي يمكن للمتصفح أن يحللها. يُعرّف الشكل بأنه مجموعة من البكسلات التي تمتلك قيمة ألفا أكبر من القيمة الحدّية والتي هي افتراضيًا القيمة 0 (أي شفافة تمامًا) أو يمكن تحديد قيمتها صراحة من خلال الخاصية shape-image-threshold.وبالتالي سيتم استخدام أي بكسل ليس شفافًا كجزء من الشكل المُعرّف من قبل الصورة. في مراحل قادمة من تعريف أشكال CSS قد يتم استخدام بيانات الإضاءة من الصورة بدلًا من استخدام بيانات ألفا. وفي حال حدوث هذا فإن خاصية shape-imgae-threshold سيتم توسيعها لتستخدم مع الإضاءة أو ألفا. الآن سنقوم باستخدام الصورة التالية من أجل تعريف شكل على عنصر ومن ثم تحديد طريقة التفاف النص حول الشكل: باستخدام الخاصية shape-outside قيمة()url التي تشير إلى الصورة نستطيع جعل المحتوى ينساب حول العنصر الذي يحمل شكل الورقة. .leaf-shaped-element { float: left; width: 400px; height: 400px; shape-outside: url(leaf.png); shape-margin: 15px; shape-image-threshold: 0.5; background: #009966 url(path/to/background-image.jpg); mask-image: url(leaf.png); } وبالطبع في حال أردنا تطبيق الصورة كخلفية في العنصر فإنه يجب قص الصورة الموجودة خارج الشكل من خلال الخاصية mask-image حيث أنه لايمكن استخدام خاصية clip-path مع الصور صاحبة القيمة ألفا، والنتيجة ستكون بالشكل التالي وفي حال قمنا ببناء أشكال معقدة ونريد تعريفه باستخدام صورة. فإنه يمكن استخدام الصور ذات قناة ألفا من خلال الفوتوشوب بدلًا من تعريفها يدويًا. كما يمكن استخدام الصورة بدلًا من تابع الشكل عندما يكون لديك عدة مناطق عائمة أو مناطق مستبعدة داخل العنصر نفسه ولكنه لايمكن تعريف عدة أشكال في العنصر نفسه ولكن إذا كانت الصورة تحوي على عدة مناطق يقوم المتصفح باستخراج هذه المناطق من الصورة واستخدامهم. تفاعل الأشكال في CSS مع التصميم المُتجاوب هل تستطيع الأشكال المبنية باستخدام CSS تتناسب مع التصميم المتجاوب؟ التخصيص الحالي لخاصية shape-outside تستطيع العمل مع التصميم المتجاوب وذلك لأنه يسمح بتحديد أبعاد العنصر من خلال النسب المئوية أو أحد وحدات الطول، ويمكن تحديد نقاط الشكل الممررة كمعاملات لتابع الشكل. وهذا يعني أن خاصية العنصر shape-outside ستكون متجاوبة responsive بشكل كامل ولكن خاصية shape-inside ليست متجاوبة responsive إلى الآن ولكن سيتم إدخالها في المرحلة الثانية حتى يتم حل بعض الحدود. الأدوات المستخدمة لبناء أشكال CSS إن بناء الأشكال المعقدة بالاعتماد على تابع Shape يعد مهمة شاقة خصوصًا عند بناء العديد من الأشكال المضلعة المعقدة من خلال تمرير الإحداثيات الديكارتية لعدة نقاط من الشكل باستخدام التابع ()polygon ولكن لحسن الحظ فإن Adobe وفرّت العديد من الأدوات التفاعلية التي تقوم بهذا العمل بشكل أسهل. هنا يوجد عدة أدوات تسمح لنا ببناء الأشكال المضلعة من خلال الرسم ثم تتولى الأداة توليد تابع الأشكال الخاص بها. ولكن يوجد بعض المحدوديات في هذه البرامج إذا أردنا رسم الشكل بالاعتماد على صورة محددة لأنه لايوجد طريقة لإدخال الصورة إلى الأدوات ومن ثم إنشاء الشكل من خلالها. الأداة الأكثر تطورًا في هذا المجال لرسم الأشكال التفاعلية المتطورة بناها فريق تطوير الويب التابع لمنصة Adobe وتم وضعها كإضافة لمحرر brackets المجاني الخاص بالشركة. مستقبل الحالات المبعدة من المعالجة في CSS لبناء أي شكل في CSS يجب أن يكون خاضعًا لعدد من المواصفات المحددة، فمثلًا لا يمكن تعريف الخاصيتين shape-inside و shape-outside إلا لأشكال مخصصة ولكن الحالات المقصاة هذه سيتم تعريف خصائص تسمح بالتفاف المحتوى حول العناصر مهما كان شكلها حتى لو لم تكن عائمة في المرحلة التالية من تطوير الأشكال في CSS وسيصبح بالإمكان التفاف النص على كامل الشكل من اتجاهات مختلفة كما في المثال الموضح بالصورة ترجمة –وبتصرّف- للمقال CSS Shapes 101 لصاحبته Sara soueidan
  8. قمنا مؤخرًا بتحديث تصميم صفحة "?Why Should You Attend" التي كانت ماتزال تحتفظ بالتصميم القديم للموقع وقد احتجنا إلى أن نوائمها مع باقي الموقع. وعندما بدأنا العمل عليها قررنا أن نحسّن تصميم هذه الصفحة بأحدث التقنيات المستخدمة في التصميم حاليًا ألا وهي: الأشكال العائمة غير المستطيلة non-rectangular float shapes وميزة الكشف المباشر من قبل المتصفح عن قدرته على تطبيق تعليمات css وهذا مايعرف بـ feature queries. ولكن ليكن واضحًا بأننا لم نقم ببناء هذا المثال المتطور من دون أن يزودنا Mike Pick صاحب Monkey Do بالتصميم حيث أدركنا بأن رؤيته تتوافق بشكل جميل مع ميزات CSS الحديثة وقد كنا سعداء جدًا بالنتائج التي حصلنا عليها من خلال هذه التقنيات الحديثة لذلك أردنا مشاركتها معكم. تصميم الفقاعات styling bubbles هنا يوجد بعض المقتطفات من تصميمنا الأولي (التصميم النهائي لم يتم إنشاؤه كبطاقة صور لذلك لايمكنني عرض الشكل النهائي ولكن هذا الشكل قريب جدًا). مايهمني في هذا المثال هو طريقة استخدام الصور الدائرية، التي كنا نشير إليها باسم "الكُوّة portholes" ولكن بعد التفكير أفضل تسميتها بـ "الفقاعات". عندما بدأت التحضير لتنفيذها من خلال التعليمات البرمجية عدت بالتفكير إلى ما قالته جين سيمون عن الاتجاه الفني الحقيقي في الويب. وبالتحديد كنت أفكر حول الأشكال في CSS وكيف يمكن أن أكون قادرًا على استخدامهم بحيث تكون أسطر الكتابة مرتبة حول محيط الدائرة بشكل انسيابي. تقوم طريقة بناء هذا التنسيق على دمج مجموعة من التقنيات المستخدمة في التعامل مع الأشكال في CSS وهي Ragged Float وفكرتها تقسيم الصورة المنحنية إلى مجموعة من الشرائط مستطيلة الشكل ثم عرضها بالتسلسل لتظهر الشكل النهائي المنحني. و Sliced Sandbags التي تقوم على مبدأ بسيط هو بناء مجموعة من div التي تتوضع فوق الصورة الأساسية وبالتالي هذه الأقسام لاتكون الصورة الحقيقية التي سيتوضع النص حولها وإنما عبارة عن مجموعة من تعليمات php. الآن نمتلك الأشكال العائمة float shapes حيث يمكننا أن نعرّف دائرة أو مضلع ثم نقوم بتوصيف كيفية انسياب النص حول الشكل. أعلم ستقول بأنك لم تسمع أبدًا عن دعم هذه الأشكال في المتصفحات، بالتأكيد هذا صحيح حيث أن المتصفحات التي تدعمها إلى الآن هي WebKit/Blink family—Chrome, Safari, and Opera ولكن ذلك لايشكل عائقًا أمام هذه التقنية لأن المتصفحات التي لاتدعم الأشكال العائمة float shapes ستنفذ الطريقة القديمة boxy float في التعامل مع هذه الأشكال وذلك من خلال عرضها كألبوم صور. من أجل إضافة فقاعة سيكون الشكل الأساسي لتعليمات CSS هو: img.bubble.left { float: left; margin: 0 40px 0 0 ; shape-outside: circle(150px at 130px 130px); } img.bubble.right { float: right; margin: 0 0 0 40px; shape-outside: circle(150px at 170px 130px); } وبالمناسبة هذه الصور الفقاعة هي عبارة عن صور مربعة أبعادها 260px سوف يتم عرضها على سطح المكتب بهذا الحجم ولكن عند تصغير العرض إلى مساحات أصغر سيتم تحجيمها بنسبة 30% لتتناسب مع العرض الجديد. طريقة توضع الشكل لنفهم طريقة إعداد شكل الفقاعة النهائي سنقوم بحساب عدد بكسلات توضع الصورة، أولًا أبعاد الصورة الفقاعة هو 260×260 بكسل ونقوم بإضافة 40 بكسل عند الهامش الأيمن للصورة وبالتالي يتشكل لدينا مربع يحوي الصورة وأبعاده هي 300 بكسل بالعرض و 260 بكسل بالطول وتشغل الصورة الأساسية القسم اليساري من هذا المربع. إذًا وعند القيام بحساب بسيط نجد مركز الدائرة هو عند النقطة 130px 130px ونصف قطر الصورة الدائرية الفقاعة هو 130 بكسل ونمدد المحيط الخارجي للفقاعة 20 بكسل فيصبح نصف قطر الدائرة النهائي هو 150 بكسل. وبنفس الطريقة نبني الفقاعات الموجودة على الجانب الأيمن، حيث تنزاح نقطة المركز إلى 170px 130px لأننا أضفنا 40 بكسل كهامش أيسر للصورة، وستشرح الصورة كيفية توضع مركز كل دائرة من أجل كل صورة سنلاحظ مايلي: الصندوق الأزرق الفاتح يُظهِر العنصر نفسه المعرف بالصف img. المربع البرتقالي الفاتح هو منطقة الهامش الأساسية وعرضها 40 بكسل. الدائرة البنفسجية والتي تمّ تعريفها في تعليمات css بالمعرف shape-outside. بالإمكان ملاحظة كيفية انسياب النص إلى المنطقة البرتقالية حيث يصل إلى أعلى الدائرة البنفسجية وهذا هو تأثير خاصية shape-outside. المناطق خارج هامش الشكل يكون طريقة عرض النص فيها عادي. نلاحظ أن الدائرة البنفسجية تمتد خارج منطقة الهامش وذلك لأنه باستخدام خاصية shape-outside يتم قص الدائرة بحسب الأبعاد المعطاة بغض النظر عن مربع الهامش، لذلك فإنه إذا قمنا بزيادة نصف قطر الدائرة مثلًا 400 بكسل فهذا يعني أن الصورة ستغطي نصف الصفحة مع أن التصميم الأساسي للنص سيبقى حول حواف هامش الصورة العائمة كما لو أنه لايوجد أي شكل على الإطلاق. استجابة الأشكال Being Responsive حتى الآن طريقة التصميم جيدة فالنص ينساب حول الشكل العائم بطريقة سلسلة في متصفحات chrome /safari / opera ويتعامل مع الأشكال كما لو أنها مربع شكل عادي في Firefox /Edge وستبقى هذه طريقة تعامل المتصفحات مع الأشكال جيدة طالما أنه لم يتم تصغيير نافذة المتصفح وتتسبب في التفاف النص بين الفقاعات ولكن بالطبع يمكن حدوث ذلك في هذه الحالة بالنسبة للصور العائمة على اليمين لن يكون الوضع سيئًا على عكس الصور اليسارية التي لن يكون الأمر جميلًا بالنسبة لها. ففي بعض الحالات سيكون الالتفاف مقبولًا كما شاهدنا في الصورة السابقة وذلك في حالة كون النص عبارة عن عدة أسطر، أما في حالة كان النص فقط كلمة أو كلمتين وعند حدوث الالتفاف لهما سيكون شكلهما غير مقبول قليلًا ولذلك من الأفضل تغيير طريقة إعداد الهوامش في النصوص بحيث لايتم الالتفاف حول الفقاعات المرافقة للنص. على سبيل المثال: .complex-content div:nth-child(even):not(:last-child) p { margin-right: 20%; } .complex-content div:nth-child(odd):not(:last-child) p { margin-left: 20%; } أي أنه من كل الكتل div الأبناء زوجية الأرقام (وليست الابن الأخير) نضيف 20% كهامش على المحتوى ونقوم بنفس الأمر من أجل الكتل الأبناء أصحاب الأرقام الفردية. بإضافة هذه التعليمات الجديدة سيظهر شكل النصوص عند تصغيير نافذة المتصفح بشكل جيد في Chrome حيث سيتم التفاف النص على طول الفقاعة وسيتم إدخال النصوص إلى داخل هوامش الصورة بقيم معقولة ولكن في متصفح firefox الذي لايزال يمتلك النظام القديم boxy float في التعامل مع الصور لن يكون هناك التفاف في النص ودفع إلى الداخل وإنما سيتم إظهار شريط التمرير على طول الصفحة ومن جهة أخرى فإن زيادة قيمة الهامش من أجل اصطفاف السطور كما في firefox (الهامش كان بنسبة 33%) لامعنى له في الأشكال العائمة float shape في chrome وذلك لأن النص لن يصل أبداً حتى النصف السفلي من الدوائر. دعم ميزة Querying feature تشغيل ميزة feature query يتم من خلال إضافة سطر supports@ إلى التعليمات حيث نستطيع من خلال هذه الطريقة معرفة المتصفحات التي لاتدعم الأشكال العائمة التي أضفناها فتقوم تعليمة support@ بتعديل الهوامش إلى 33% كما أنها تقلل هذه الهوامش في حال كانت المتصفحات تستطيع التعامل مع هذه الأشكال، ويتم هذا من خلال إضافة تعليمات: .complex-content div:nth-child(even):not(:last-child) p { margin-right: 33%; } .complex-content div:nth-child(odd):not(:last-child) p { margin-left: 33%; } @supports (shape-outside: circle()) { .complex-content div:nth-child(even):not(:last-child) p { margin-right: 20%; } .complex-content div:nth-child(odd):not(:last-child) p { margin-left: 20%; } } وبهذا سيظهر تصميم العناصر بشكل جيد في جميع المتصفحات، بالرغم من وجود بعض الأشياء الصغيرة جدًا التي يمكن إضافتها. ولكن بشكل عام طريقة العرض في جميع الحالات التي تدعم الأشكال العائمة أو لا تبعث على السرور في الفيديو الأول طريقة العرض في متصفح chrome تحميل الفيديو الأول والفيديو الثاني يظهر طريقة العرض في متصفح firefox الذي لايدعم الأشكال العائمة تحميل الفيديو الثاني بالأخير إنها نعمة وجود ميزة مثل feature queries تسمح للمتصفحات مثل firefox و MS Edge الحصول على دعم لإظهار الأشكال العائمة. ومع أنه لايوجد تحسينات قريبة للمتصفحات ولكن يتم العمل بشكل دائم على إدخال التحسينات على CSS نفسها بحيث سيصبح شعارها قريبًا "صمم وانسى"، كما يمكن القول بأن التعديل الأساسي في CSS هو طريقة التعامل مع الأشكال وتحسين عمليه استجابتها من دول وجود الدعم الكافي في المتصفحات لها. ترجمة –وبتصرّف- للمقال A Redesign with CSS Shapes لصاحبه Eric Meyer
  9. class هو تجريد للغرض object أي هو مجموعة الأغراض التي تحمل نفس الصفات العامة ويستخدم this للتأشير على الغرض ونحن في داخله عند البناء بشكل عام لتجنب حالات الغموض وخصوصًا في حالات برمجة الصفوف التي تحوي inner classes للتعرف على المزيد من طريقة عمل التعليمة السابقة بشكل خاص https://www.quora.com/In-Android-coding-what-does-MainActivity-this-do-and-what-are-MainActivity-and-this-separately-class-keyword-etc
  10. لقد أصبح التصميم الشبكي Grid Layout في CSS يتطابق تمامًا مع اسمه، حيث يمكن من خلال CSS بناء تصميم شبكة ببعدين عمودي وأفقي يمكن أن يتم توزيع التصماميم والأغراض الأخرى على العمود والسطر. سنستعرض في هذا الدرس العديد من الأمثلة على التصميم الشبكي، ولكن لنبدأ أولًا بحل المشاكل التي واجهتنا عندما حاولنا بناء flexbox بشكل شبكي. سنبدأ أولًا بتطبيق مثال نقوم فيه ببناء ثلاثة أعمدة ضمن الشبكة، من خلال بناء div يحمل اسم الصف example ونضيف فيه قائمة غير مرقمة ul اسم الصف الخاص بها cards ونضيف بداخلها عناصر من خلال الوسم li كل عنصر هو عبارة عن بطاقة card من البطاقات التي سننظم عرضها بمخطط شبكي grid layout على الشاشة (كود المثال على GitHub) لوضع البطاقات الخمسة ضمن الشبكة السابقة سنضيف مجموعة من تعليمات css للصف cards الذي يحوي البطاقات الخمسة: نضيف خاصية الشبكة لطريقة عرض الحاوية container من خلال التعليمة display:grid. لبناء ثلاثة أعمدة متساوية في العرض نضيف الخاصية grid-template-columns، وهنا سنستعرض وحدة جديدة يمكن استخدامها عند إنشاء الشبكة تسمى وحدة الطول المرن flexible-length unit ونشير إليها بـ fr حيث تمثل أجزاء الفراغ الموجود في الحاوية. في هذا المثال سنقسم الفراغ إلى ثلاثة أعمدة متساوية لذلك نضع 3 أجزاء fr قيمة كل واحد منها 1 والتي تعني تقسيم الفراغ إلى ثلاثة أجزاء متساوية. .cards { margin: 0 -10px; display: grid; grid-template-columns: 1fr 1fr 1fr; } (كود المثال على GitHub) وهذا كل مانحتاجه للحصول على ابن للحاوية يظهر بشكل شبكي، فعلى عكس طريقة بناء flexbox لانحتاج هنا إلى أي قواعد أخرى لإضافتها لخلايا الأبناء المكونة للشبكة حيث تقوم جميع الخلايا بوراثة كل خصائص الأب مباشرة. كما نرى فالعناصر ضمن الشبكة تشكل تصميم متماسك لايحتاج إلى أي تعديلات في عرضهم وبذلك نكون قد وجدنا حلًا لأحد المشاكل التي كانت تظهر لدينا في تصميم flexbox grid باستخدام الخصائص المعرفة للشبكة. الآن في حال أردنا إضافة فجوات بين العناصر المرنة داخل الشبكة في المثال السابق يمكن إضافة هوامش بين العناصر ولكن نحتاج أيضا لإضافة هوامش سلبية لحاوية الشبكة من أجل تصحيح الهوامش على اليمين واليسار غير المرغوب بها. في التصميم الشبكي لـ CSS يوجد خاصية تسمى grid-gap يمكن إضافتها من أجل إعطاء هوامش للعناصر داخل الشبكة. وهي تعبر عن خاصيتين في داخلها هما grid-columns-gap و grid-row-gap التي يمكن أيضًا إعطاؤهما قيم بشكل فردي في حال أردنا الهوامش بين الأعمدة والأسطر مختلفة. لنطبق هذه الخصائص عمليًا ونكتشف طريقة عملها معًا، سأقوم بحذف الهوامش المعطاة للعناصر وستحصل على نفس التصميم الذي أظهرناه في الأعلى، ولكن من دون الفوضى التي تحدثها الهوامش والهوامش السلبية .cards { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-gap: 20px; } ملاحظة: بمجرد طباعة الكتاب الذي تم اقتباس هذا المقال منه، قامت إحدى مجموعات العمل على CSS بتغيير اسم الخصائص المتعلقة بـ grid-gap حيث سيتم تغيير اسم خاصية grid-column-gap إلى column-gap وخاصية grid-row-gap إلى row-gap أما خاصية grid-gap التي تجمع بين الخاصيتين السابقتين ستتغير إلى gap. بالإضافة إلى أنه سيتم تغيير تعريف الخصائص التي تحدد أبعاد مخطط المربع الإظهار box alignment وبالتالي يمكن دعم وجود فجوات داخل flexbox كما في الشبكة. ولأن المتصفحات قد تم تحميلها بهذه الخصائص، لذلك سيتم تغيير اسم الخصائص ذات الشكل grid-* إلى الشكل الجديد بالمستقبل القريب. حتى وقت كتابة هذا الدرس لم يقدم أي متصفح دعم لأسماء الخصائص الجديدة، لذلك سأبقي على الأسماء القديمة في هذا المثال ولكن لامانع في حال أردت التأكد يمكن أن تكتب كلا الشكلين من الخاصية في مثالك .cards { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-gap: 20px; gap: 20px; } طريقة توضع العناصر حول الشبكة نستطيع الوصول إلى مستويات أكثر تطورًا في طريقة توزيع العناصر ضمن الشبكة مما كان مسموحًا في flexbox من خلال الاستفادة من ميزات الشبكة ثنائية الأبعاد وطريقة توضع العناصر داخلها. الطريقة الأكثر الأساسية هي استخدام أرقام الأسطر. حيث أنه تم ترقيم أسطر وأعمدة الشبكة ورقم البداية هو 1، حيث أن بداية الترقيم تكون حسب اتجاه الكتابة في المستند فعندما يكون العمل داخل الصفحة باللغة الانجلزية مثلًا أي توضع الكتابة من اليسار إلى اليمين LTR عندها العمود رقم 1 هو العمود الموجود في الجهة اليسرى والسطر رقم 1 هو السطر الموجود في الأعلى. أما عندما تكون الكتابة من اليمين إلى اليسار RTL كما في اللغة العربية عندها سيكون العمود رقم 1 هو العمود الموجود في يمين الشبكة. كما ستكون أقصى زاوية في الشبكة (الزاوية اليمينة في اللغات التي يكون اتجاه الكتابة فيها LTR والزاوية اليسارية في اللغات التي اتجاهها RTL) ممثلة بالرقم 1- . لتوضيح هذه الطريقة سنقوم إضافة اسم صف إلى كل عنصر li داخل مستند Html يمثل رقم البطاقة card1, card2… ثم داخل ملف css سنغير خصائص كل صف لتصبح بالشكل. .cards { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-gap: 20px; } .card1 { grid-column: 1 / 3; grid-row: 1; } .card2 { grid-column: 3; grid-row: 1; } .card3 { grid-column: 1; grid-row: 2 / 4; } .card4 { grid-column: 2 / 4; grid-row: 2; } .card5 { grid-column: 2 / 4; grid-row: 3; } (كود المثال على GitHub) نستطيع أن نشاهد قوة تنظيم المخطط الشبكي هنا، حيث يمكننا زيادة اتساع الأعمدة والأسطر وهو شيء كان صعبًا حدوثه في المنهج السابق المتبع في التصميم. بالنسبة للون الخلفية للبطاقات نلاحظ أنها مطبقة مباشرة حتى لو كان المحتوى قصير، كما أنه من السهولة تغيير مدى توسع كل كتلة كما يمكننا ترك كتل فارغة فمثلًا إذا قمت بتغيير البطاقة الثالثة card3 لتبدأ عند السطر 3 بدلًا من السطر الثاني عندها سنحصل على خلية فارغة ولايمكن لأي خلية أخرى ضمن الشبكة أن تنزاح إلى الأعلى لتملأ الفراغ وهنا يمكن الاختلاف عن floats التي تحاول أن تطفو إلى الأعلى لتملأ الفراغات المتاحة. كما يوجد طريقة أخرى لتغيير توضع العناصر ضمن الشبكة من خلال تسمية المناطق، حيث يُسمح لك بتوصيف مخططك كما تريد. سنشرح هذه الطريقة من خلال مثالنا، أولًا سنعطي كل بطاقة اسم من خلال الخاصية grid-area. .card1 { grid-area: a; } .card2 { grid-area: b; } .card3 { grid-area: c; } .card4 { grid-area: d; } .card5 { grid-area: e; } ثم نضيف الخاصية grid-template-areas إلى الحاوية للشبكة cards بحيث توصف القيمة المعطاة لهذه الخاصية كيفية توضع العناصر ضمن المخطط فمثلا في حال وصفنا التوضع بالشكل. .cards { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-gap: 20px; grid-template-areas: "a a b" "c d d" "c e e"; } (كود المثال على GitHub) سيظهر لدينا ترتيب البطاقات ضمن الشبكة بالشكل. ولكن هناك بعض الملاحظات من المهم تذكرها حول خاصية grid-template-areas وهي: في حال أردنا أن نمدد البطاقة على مساحة أكثر من خلية نقوم بتكرار اسم المنطقة، مثلًا تمتد البطاقة الأولى card1 على مساحة عمودين لذلك قمنا بتكرار المنطقة a مرتين حيث أن شكل المنطقة هو مستطيل (لا نستطيع إلى الآن بناء منطقة على شكل حرف L). لترك مساحات فارغة يتوجب علينا ترك مكان الخلية فارغًا، ويتم ذلك من خلال استخدام محرف النقطة "." مثلًا إذا استبدلنا أول c بنقطة عندها ستبقى خلية فارغة في المخطط. .cards { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-gap: 20px; grid-template-areas: "a a b" ". d d" "c e e"; } يمكنك تسمية المناطق بأكثر من محرف في حال كان عدد الأسطر كبير مثلًا كما أنه يمكن أن تمثل الخلية الفارغة بأكثر من نقطة ".." بشرط ألا يفصل بين المحارف أي فراغ. وأخيرًا وجدت أن هذه الطريقة للعمل على مخطط الصفحات تعتبر سهلة جدًا لتحريك العناصر والاستمتاع بوضع النماذج الأولية لصفحاتك أكثر من القلق هو طريقة تنفيذ التصاميم والحصول عليها حيث يمكنك اكتشاف أفضل طريقة لتمثيل شكل الواجهة ثم العودة لبناء محتويات الصفحة والترتيب المنطقي لعرضها. وبهذه الأمثلة التي طرحناها اليوم، تكون قد اكتسبت معرفة كافية تسمح لك باستخدام التصميم الشبكي grid layout لتقرر طريقة عرضك للمحتويات، ولكن تذكر هناك الكثير من الطريق لتخصيص العمل الذي تقوم به حيث يمكنك القيام بالكثير من خلال استخدام CSS. ترجمة للمقال The New CSS Layout, An Excerpt للكاتبة Rachel Andrew
  11. يعتبر نظام مودل Moodle أحد أنظمة إدارة المحتوى مفتوحة المصدر ومجانية تخضع لسياسة اتفاقية GPL وقد صمم هذا النظام بلغة PHP وفق نظريات علم التربية. يستخدم نظام مودل لبناء مواقع للتعليم الالكتروني المستخدم في مشاريع المدارس والجامعات e-learning بالإضافة إلى التعليم عن بعد. كما أن هذا النظام يقدم للمستخدم ميّزات تخصيص إضافية تمكنه من بناء مواقع خاصة تحوي على العديد من الدورات التعليميه عبر الإنترنت. كلمة Moodle هي اختصار للكلمات modular object-oriented dynamic learning environment والتي تعني أن النظام مبني بتقنيات البرمجة غرضية التوجه ليؤمن بيئة تعليمية ديناميكية نبذة تاريخية صُمّم نظام موديل من قبل مارتن دوغماس بهدف مساعدة المعلِّمين في تقديم دورات تعليمية على الإنترنت، مع الحرص على بناء المحتوى بشكل تفاعلي وتعاوني بالإضافة إلى تطوير محتوى هذه الدورات بشكل مستمر حيث تم إطلاق أول نسخة من مودل في 20 آب من العام 2002. أما في الوقت الحالي فإن شركة Moodle HQ هي التي تقود هذا المشروع، وهي شركة استرالية مكونة من 50 مطورًا ويتم دعمها ماليًا من خلال شبكة مكونة من 48 شركة حول العالم، كما أن المبرمجين في البرامج مفتوحة المصدر ساهموا أيضًا في تطوير نظام مودل. طريقة تثبيت نظام مودل لتثبيت أي نظام إدارة محتوى على جهازك يجب أن يكون لديك خادوم أولًا، وقد شرحت طريقة تثبيت خادوم ‏WAMP‏ هنا ‏سابقًا.‏ بعد أن قمت بتركيب الخادوم أبدأ بعملية تثبيت نظام مودل وذلك وفق الخطوات التالية:‏ يجب أن ننتبه إلى أن الخادوم ‏WAMP‏ يعمل، من خلال التأكد من وجود أيقونه الخادوم في شريط المهام باللون الأخضر نفتح المتصفح على صفحة التحميل في الموقع الرسمي لنظام مودل https://download.moodle.org/ ونختار النسخة 3.4 ونقوم بتحميلها نحتاج أولًا إلى تغيير نسخة PHP التي يعمل الخادوم عليها لتتطابق مع نسخة النظام الذي قمنا بتحميله ويتم ذلك من خلال النقر على زر أيقونة الخادوم في سطر البدء ثم نختار مجلد PHP ثم Versions ونختار النسخة الأخيرة 7.1.9 نقوم بالتأكد من بعض إعدادات WAMP لذلك نفتح ملف PHP.ini من خلال الضغط على أيقونة الخادوم ثم أختار PHP ثم الملف PHP.ini ابحث عن التعليمة الموجودة في الصورة وتأكد من عدم وجود الفاصلة المنقوطة ; أمامها بناء قاعدة بيانات خاصة بنظام مودل من خلال الانتقال إلى http://localhost/PHPmyadmin/ وندخل اسم المستخدم root ونترك كلمة المرور فارغة ملاحظة: تُطلب اسم المستخدم وكلمة المرور مرة واحدة فقط عند أول تسجيل دخول إلى إعدادات الخادوم خلال الجلسة. لبناء قاعدة البيانات من صفحة إعدادات الخادوم التي تظهر لدينا ننقر على زر new ثم ندخل اسم قاعدة البيانات ولتكن moodle ثم نختار ترميز المحارف utf8_unicode_ci وفي النهاية ننقر على create لتبنى لدينا قاعدة البيانات نفتح مجلد www الموجود ضمن مجلدات WAMP من خلال الضغط على أيقونة الخادوم ثم اختيار www directory نعود إلى ملف ZIP الخاص بنظام مودل والذي قمنا بتحميله في الخطوة رقم 2 حيث نقوم بنسخه إلى مجلد www ونقوم بفك ضغطه داخله ندخل إلى صفحة إعدادات النظام من خلال http://localhost/moodle حيث نبدأ بالتثبيت تظهر لدينا صفحة اختيار لغة واجهة التحكم بالنظام، نختار اللغة الانجليزية ثم ننقر على زر next ستظهر لدينا صفحة تأكيد لرابط الوصول إلى الموقع ومسارات حفظ بيانات الموقع على الخادوم سنقر على next مباشرة بعدها ستظهر صفحة اختيار نوع قاعدة البيانات نختار MySQL وهي نوع قاعدة البيانات التي قمنا بإنشائها في خطوة سابقة وننقر على next ستظهر لدينا الآن صفحة إعدادات قاعدة البيانات، نضيف اسم المستخدم Database user وهو root وننقر على زر next ستظهر لدينا صفحة تذكر شروط استخدام النظام عليها وفي حال الموافقة نضغط على continue ستظهر لدينا صفحة تحوي على معلومات كاملة عن حالة التثبيت، في حالتنا نجد أنه لايوجد أخطاء أثناء التثبيت لذلك يمكننا المتابعة بالنقر على continue سيبدأ الآن عملية التثبيت على الخادوم والذي هو الحاسب الشخصي، وقد تستغرق هذه العملية القليل من الوقت عند الانتهاء من عملية التثبيت سيعطي النظام قائمة بالعمليات التي حدثت أثناء العملية وتم تنصيبها بنجاح، يمكننا المتابعة إلى الموقع مباشرة من خلال الضغط على زر continue بعدها ستظهر قائمة لتخصيص المستخدم الرئيسي للموقع حيث ندخل اسم المستخد admin وكلمة المرور والبريد الالكتروني ثم ننقر على update profile وبذلك نكون قد انتهينا من عملية تثبيت نظام مودل ويمكننا البدء بنشر محتوى دورات تعليمية عليه. ملاحظة: عند محاولة التسجيل والدخول إلى الموقع كـ admin من خلال http://localhost/moodle قد تظهر لديك مشكلة نص رسالتها " the page doesn’t open at localhost." ويبقى المتصفح يحاول إعادة تحميل الصفحة ولكن دون جدوى. لحل هذه المشكلة نقوم بما يلي نذهب إلى المسار C:\wamp64\www\moodle\admin ونفتح الملف index.PHP ونقوم بالبحث عن التعليمة ونقوم بوضع رمز التعليق “//” عليها ننتقل الآن إلى المسار C:\wamp64\moodledata\sessions ونقوم بحذف جميع الملفات الموجودة فيها وبذلك تحل مشكلة فتح الموقع. والآن عند محاولة فتح الموقع مرة أخرى سيظهر لدي شاشة تسجيل الدخول بناء محتوى باستخدام نظام مودل إن عملية بناء محتوى يعني بالضرورة بناء مواد تعليمية وتقديمها إلى متصفحي الإنترنت من خلال منصة مودل. ومن المهم معرفة أن نظام مودل يستند في بنائه إلى مجموعة من النظريات التعليمية المطروحة في أصول التربية، ويغطي مجموعة من أنماط التعليم الالكتروني منها blended learning والذي يقوم على الدمج بين التعليم التفاعلي والتعليم التقليدي، التعليم عن بعد distance education، و flipped classroom. بعد الدخول إلى الموقع ستظهر لدينا لوحة التحكم سنختار منها site home من أجل إضافة محتوى على الصفحة الرئيسية، حيث يظهر لدينا عند النقر على الرابط الصفحة الرئيسية التي يمكن من خلالها إضافة دورة تعليمية وعند اختياره ستظهر لدينا صفحة إضافة دورة جديدة، هذه الصفحة هي أهم مايميز نظام مودل حيث نلاحظ الخيارات الكثيرة التي يمكننا من خلال ملئ بياناتها ورفع المواد التعليمية من خلالها إلى بناء الدورة بشكل كامل وإضافتها إلى موقعنا ومن الجدير بالذكر أن أكثر استخدام لمنصة مودل هو بناء دورات خاصة بين الطلاب والأساتذة حيث لايمكن لأي شخص على الإنترنت الحصول على سماحية الوصول إليها أو مشاهدتها إذا لم يكن يملك هذا الامتياز، ولكن تم بناء بعض المواقع العامة للتعليم المفتوح مثل موقع التعليم المفتوح المجاني Open Learn
  12. يوفر بوتستراب بيئة عمل جيدة لبناء واجهات صفحات الانترنت بشكل احترافي وسهل الاستخدام من قبل زوار الموقع، بالإضافة إلى التصاميم الجذابة المريحة للعين في التصفح والانتقال ضمن الموقع. سنقوم اليوم ببناء قائمة شجرية قابلة للتوسع أو الطي collapse tree grid ضمن القائمة الجانبية للموقع، والتي تعد أحد الأعمدة الأساسية عند بناء المواقع القائمة في ترتيب صفحاتها على التصنيف ضمن بنية شجرية. يمكن الاستخدام في بناء القائمة الشجرية إضافة بنيت من قبل Pomazan Max ونشرها على GitHub وتخضع هذه الإضافة لشروط اتفاقية MIT من خلال استخدام ملفي jquery.treegrid.js و jquery.treegrid.css سنقوم الآن بتخصيص بناء هذه الشجرة وإكمالها. أولًا من المهم إضافة ملفات css التي نستخدمها لبناء الشجرة وهي الملفات الخاصة بنا Main ملف الخاص بالقائمة الشجرية jquery.treegrid.css وملفات البوتستراب <link rel="stylesheet" href="css/bootstrap.min.css"> <link rel="stylesheet" href="css/bootstrap-theme.min.css"> <link rel="stylesheet" href="css/main.css"> <link rel="stylesheet" href="css/jquery.treegrid.css"> نقوم ببناء panel-group لنضمن داخله العقد الثلاث. المعرف الخاص id والذي يملك القيمة accordion هو أحد معرفات bootstrap ويفيد من أجل التبديل بين العقد المفتوحة أو المطويّة <div class="panel-group" id="accordion"> </div> نضيف عنوان للقائمة الجانبية <h3>Try Tree Gird Sidebar</h3> لبناء العقدة الأولى node1 نضيف التعليمات حيث أضفنا node1 كعنوان للقائمة التي تحته node1-1... ولذلك ضمناه تحت اسم الصف panel-heading أما بالنسبة للقائمة التي تحته فقد تم بناؤها كقائمة حيث يضاف إلى كل عنص من القائمة صف list-group-item وبنفس الطريقة قمنا بإضافة قائمة فرعية ضمن عنصر القائمة node1-3 من أجل تغيير شكل العنوان لكل عقدة رئيسية node1، node2، node3 من خلال إضافة أحد الصفوف panel-info والتي تعطي اللون الأزرق panel-danger وتعطي اللون الأحمر و panel-success وتعطي اللون الأخضر <div class="panel panel-info"> <div class="panel-heading"> <div class="panel-title"> <a data-toggle="collapse" data-parent="#accordion" href="#node1">Node1</a> </div> </div> <div id="node1" class="panel-collapse collapse in"> <div class="panel-body"> <div class="list-group-item">Node1-1</div> <div class="list-group-item">Node1-2</div> <div class="list-group-item"> <div class="panel-title"> <a data-toggle="collapse" href="#node1-3"> Node1-3 <span class="glyphicon glyphicon-chevron-down"></span> </a> </div> <div id="node1-3" class="panel-collapse collapse"> <ul class="list-group"> <li class="list-group-item">node1-3-1</li> <li class="list-group-item">node1-3-2</li> <li class="list-group-item">node1-3-3</li> </ul> </div> </div> </div> </div> </div> وبنفس الطريقة السابقة نبني العقد node2 و node3 في حال أردت أي تغيير للقائمة تستطيع القيام بذلك: لإضافة عقدة جديدة وعنوان جديد يتم من خلال إضافة panel جديد ضمن panel-group لإضافة عنصر تابع لـ panel يتم إضافته كـ list-group-item يمكن إضافة لكل من العقد الداخلية رابط للتتمكن من الولوج إلى صفحة مختلفة من خلال وضع اسم العقدة ضمن رمز الرابط <a>node1-1</a> وفي نهاية ملف html نضيف ملفات الجافات سكربت التي نستخدمها في البوتستراب والخاص ببناء القائمة الشجرية jquery.treegrid.js <script src="js/vendor/jquery-1.11.2.min.js"></script> <script src="js/vendor/bootstrap.min.js"></script> <script src="js/vendor/jquery.treegrid.js"></script> <script src="js/main.js"></script> ضمن ملف الجافا سكربت Main.js نبني التابع الذي يقوم بفتح وإغلاق كل عقدة عند النقر عليها وذلك من خلال إضافة الصف active عند فتح العقدة إليها function openNode(evt, nodeName) { // Declare all variables var i, tablinks; // Get all elements with class="tablinks" and remove the class "active" tablinks = document.getElementsByClassName("tablinks"); for (i = 0; i < tablinks.length; i++) { tablinks[i].className = tablinks[i].className.replace(" active", ""); } // Show the current tab, and add an "active" class to the link that opened the tab document.getElementById(nodeName).style.display = "block"; evt.currentTarget.className += " active"; } ونضيف التابع الذي يقوم ببداية تحميل الصفحة إغلاق جميع العقد التي كانت مفتوحة أي إعادة كل المتغيرات إلى الحالة الافتراضية $(document).ready(function () { $('#accordion').find('.collapse').collapse('hide'); var $myGroup = $('#accordion'); $myGroup.on('show.bs.collapse', '.collapse', function () { $myGroup.not($(this).parents()).find('.collapse.in').collapse('hide'); }); } ); وبذلك نكون قد أنشأنا قائمة شجرية قابلة للطي والتوسع ديناميكية تمكّن المستخدم من الاطلاع على محتويات الموقع والانتقال بين صفحاته بسهولة
  13. نظام MediaWiki هو برنامج مفتوح المصدر ومجاني يخضع لاتفاقية GPL، وقد طُوِّر بالأساس من أجل تلبية احتياجات الموسوعة الحرة ويكيبيديا في عام 2002، بالإضافة إلى تخديم المشاريع الأخرى التي تعمل ضمن مبدأ ويكي. يحوي البرنامج على أكثر من 900 خيار للإعدادات وأكثر من 2000 إضافة متاحة للتحميل لزيادة ميزات نواة البرنامج، وبذلك يمكن القول بأن البرنامج قادر على التعامل مع أحجام ضخمة من البيانات تقدر بعدة تيرابايت، إضافة إلى أنه يستطيع تخديم الآلاف من طلبات محتوى الصفحات من الخادوم خلال ثانية واحدة. نبذة تاريخية عندما انطلقت الويكيبيديا في الشهر الأول من عام 2001 كانت تستخدم برنامج ويكي صغير يسمي UseModWiki حيث طُوّر بلغة بيرل وقام بتخزين جميع الصفحات ضمن ملف نصي. ولكن سرعان ما تَبيّن مدى محدودية هذا البرنامج من ناحية الأداء والقدرة التشغيلة، لذلك قام ماغنوس مانسكي والذي كان محرر في ويكيبيديا بالعمل على نسخة جديدة من البرنامج لتحل مكان UseModWiki ولتعمل تحديدًا مع الويكبيديا، وبذلك قام بتطوير برنامج مكتوب بلغة PHP يخزن المعلومات ضمن قاعدة بيانات MySQL وتم إطلاقه للعمل على النسخة الإنكليزية من الويكبيديا في بداية عام 2002 كما تزامن مع القيام تدريجيًا بتوزيعه للعمل على اللغات الأخرى التي تُستخدم في الويكيبيديا، وقد تم الإشارة إلى هذا البرنامج بكلمات مثل "المرحلة الثانية من UseModWiki" في شهر حزيران من عام 2003 أعلن رسميًا عن ميدياويكي كبرنامج إدارة محتوى يحل محل UseModWiki، وفي شهر تموز من العام نفسه اقترح المساهم في ويكيبيديا دانييل ماير اسم MediaWiki للبرنامج. طريقة تثبيت ميدياويكي لتثبيت أي نظام إدارة محتوى على جهازك يجب أن يكون لديك خادوم أولًا، وقد شرحت طريقة تثبيت خادوم WAMP هنا سابقًا. بعد الانتهاء من عملية تثبيت الخادوم على الحاسب الشخصي، سأبدأ بتثبيت نظام ميدياويكي وفق مجموعة من الخطوات المتسلسلة: 1- نحتاج أولًا للتأكد من أن الخادوم الذي قمنا بتثبيته WAMP يعمل، ويتم التأكد من ذلك من خلال رؤية أيقونة الخادوم باللون الأخضر في شريط المهام 2- نبدأ عملية تحميل نظام ميدياويكي من الموقع الرسمي للنظام https://www.mediawiki.org/wiki/Download حيث نختار النسخة المستقرة stable من النظام 3- ننتقل إلى مجلد www الموجود بالخادوم من خلال النقر على أيقونة WAMP واختيار www directory من القائمة 4- ننسخ الملف الذي قمنا بتحميله في الخطوة 2 إلى مجلد www ونقوم بفك ضغطه ثم نغير اسمه إلى mediawiki 5- نفتح صفحة إعدادات النظام من خلال الرابط http://localhost/mediawiki/mw-config/index.php 6- ستظهر لدينا أولًا خيارات اللغة للنظام وسنبقيها على اللغة الانجليزية ونضغط على continue 7- بعدها تظهر لدينا رسالة ترحيبية تحوي معلومات عن تنسيق النظام واتفاقية شروط استخدامه وبالنقر على زر continue تعني الموافقة على سياسة الموقع 8- تظهر لدينا الآن الاتصال مع قاعدة بيانات، حيث يوضح الموقع أنواع قواعد البيانات التي يمكن استخدامها مع نظام ميدياويكي، سنختار نوع قاعدة البيانات MySQL 9- لبناء قاعدة بيانات الموقع نقوم بفتح صفحة التحكم الخاصة بالخادوم عبر الرابط http://localhost/phpmyadmin/ وندخل اسم المستخدم root أما كلمة المرور تترك فارغة ملاحظة: هذه الصفحة تطلب مرة واحدة فقط عند أول دخول لصفحة إعدادات الخادوم خلال الجلسة. 10- بعد الدخول إلى صفحة إعدادات الخادوم ننقر على زر new الموجود في القائمة الجانبية وندخل في المربع create database اسم قاعدة البيانات الخاصة بالموقع مثل my_wiki ثم ننقر على زر create 11- نعود لصفحة إعدادات قاعدة البيانات التي ظهرت لدينا في الخطوة 8 ونكمل الإعدادات من خلال كتابة اسم قاعدة البيانات والمضيف واسم المستخدم ثم ننقر زر continue 12- ستظهر صفحة إعدادات قاعدة البيانات، نبقى على الاختيارات الافتراضية لهذه الصفحة لأن هذه الخيارات هي الأفضل بالنسبة للإدخال باللغة العربية، وبعدها نضغط على continue 13- ستظهر صفحة تنصيب المشروع حيث ندخل اسم موقعنا واسم المستخدم وكلمة المرور وفي النهاية يمكن اختيار النمط القياسي في التنصيب من خلال الضغط على خيار just install the wiki ثم continue 14- وفي صفحة install نختار continue أيضًا 15- عند انتهاء عملية تثبيت النظام سيقوم تلقائيًا بتحميل ملف localSettings.php والمطلوب هو نسخ هذا الملف والاحتفاظ به ضمن مجلد mediawiki داخل مجلد www بحيث يكون ملف index.php و localSettings.php في نفس المجلد 16- للدخول إلى صفحة الموقع الخاص بنا نختار http://localhost/mediawiki/index.php حيث نلاحظ أن شكل الموقع الخاص بنا يشبه تمامًا شكل صفحات ويكيبيديا. وبهذا نكون قد انتهينا من عمليت تثبيت النظام ويمكننا الآن البدء ببناء محتوى خاص بالموقع ونشره. بناء موقع باستخدام ميدياويكي سأبدأ الآن بعملية بناء محتوى صفحات ويب من خلال ميدياويكي، ولكن أولًا سأضيف اللغة العربية إلى النظام. أولًا: تغيير النظام إلى اللغة العربية لتغيير إعدادات النظام إلى اللغة العربية نحتاج أولًا إلى إضافة مجموعة من المكونات الخاصة باللغات المتعددة إلى النظام ثم تغيير إعداداتها لتناسب اللغة العربية وذلك وفق الخطوات التالية: 1- نقوم بتحميل إضافة تسمى UniversalLanguageSelector من خلال الرابط https://www.mediawiki.org/wiki/Special:ExtensionDistributor/UniversalLanguageSelector فيظهر لدينا شاشة لاختيار رقم نسخة ميدياويكي حيث نختار MediaWiki 1.3 2- يبدأ تحميل الإضافة بصيغة ZIP تلقائيًا، ثم ننسخ الملف إلى المسار C:\wamp64\www\mediawiki\extensions وننسخ إليه ملف الإضافة عند الانتهاء من تحميله ثم نفك ضغطه داخله. 3- نرجع إلى المسار C:\wamp64\www\mediawiki ونفتح منه الملف LocalSettings.php ثم نضيف في نهايته سطر الرماز wfLoadExtension( 'UniversalLanguageSelector' ); 4- نقوم بتسجيل الدخول كـ admin إلى النظام من خلال النقر على زر Log in الموجود في الأعلى 5- بعد أن تظهر الصفحة الرئيسية ننقر على رابط preferences فينتقل إلى صفحة الإعدادات حيث سنقوم بالتعديل داخل قسم Internationalisation حيث نختار more language setting 6- ستظهر لدينا لوحة تحكم خاصة باللغة فقط ونلاحظ وجود اللغة العربية ضمن الاقتراحات حيث يقوم النظام بإظهار مجموعة من خيارات اللغة التي قام باستنتاجها من خلال الاعتماد على تخصيصات الحاسب ومنطقتنا 7- عند اختيار اللغة العربية سينتقل عرض المتصفح فورًا إلى اللغة العربية 8- لتغيير لغة الإدخال إالى العربية نبقى داخل قسم “تفضيلات” الذي يظهر لدينا وننقر على رابط “المزيد من إعدادات اللغة” 9- سيظهر لدينا في الأسفل “إعدادات الإدخال” نختار من “إدخال” العربية ثم ننقر على “طبق الإعدادات” وعند فتح الصفحة الرئيسية للموقع ستظهر لدينا باللغة العربية ثانيًا: اختيار القوالب يوجد قوالب قياسية تم اعتمادها من قبل ميدياويكي يمكن استخدامها، حيث يمكن اختيارها من خلال الدخول إلى “تفضيلات” ثم “الواجهة”. نلاحظ الخيار المعلم هو القالب الحالي، نختار القالب الذي نريد ثم ننقر على حفظ حيث ينتقل الموقع مباشرة إلى الشكل الجديد له. ثالثًا: إضافة محتوى إن الموقع الذي قمنا ببنائه باستخدام ميدياويكي يحاكي بشكل كامل موقع ويكيبيديا وبالتالي فإن عملية إضافة محتوى في موقعنا الخاص هنا تشابه عملية إضافة محتوى على الويكيبيديا، حيث يتم ذلك بالخطوات التالي: 1- في قائمة البحث في الأعلى ندخل اسم المقال التي نريد كتابتها ونضغط على زر البحث (او go في الويكيبيديا) 2- سيظهر في نتائج البحث أنه لايوجد مقالة بهذا العنوان وبالتالي أختار "أنشئ الصفحة (لمحة عن ميدياويكي)" 3- تظهر الآن صفحة إنشاء المقالة حيث نكتب المقالة التي نريد ضمن العرض ثم نختار احفظ الصفحة 4- سنجد الآن أن المقالة قد تم إضافتها إلى الموقع ملاحظة: في حال أبقينا لغة العرض باللغة الإنجليزية سيظهر لدينا محرر المقالة بشكل أفضل حيث يحوي العديد من الأزرار التي تمكننا من تحرير المقالة دون الحاجة إلى استخدام الرموز يعتبر ميدياويكي هو نظام لإدارة محتوى صفحات الويكي، ولذلك فإن أغلب المواقع التي صممت من خلاله تعتمد على مبدأ الويكي ومنها الويكيبيديا أضخم موسوعة حرة تمتلك الملايين من المقالات بمختلف لغات العالم Conservapedia أيضًا موسوعة ولكنها تمتلك معايير كبيرة بحيث لا تسمح بأي تشويه للحقيقة Wikiquote موسوعة تضم العديد من الأقوال منقولة عن مشاهير، أفلام، أو من الأدب WikiTravel موسوعة تضم أشهر أمكان السفر والسياحة حول العالم Wikihow موقع ضخم يملك أكبر عدد من المقالات عن “how to” أو “كيف” حول العالم Wikicars أكبر موسوعة تحوي معلومات عن السيارات Wikisummaries موسوعة تحوي على عدد من ملخصات الكتب Game Programming Wiki أحد أفضل الموارد لمطوري الألعاب حيث يحوي العديد من المقالات التعليمية وأسطر code لبرمجة ألعاب الفيديو
  14. يعرّف جملة Joomla بأنه نظام إدارة محتوى مفتوح المصدر ومجاني تمامًا وتم نشره وفق شروط سياسة GPL مما يعني يسمح بإمكانية الاستفادة منه واستخدامه وإعادة نشره مجانًا. بني نظام جملة باستخدام لغة PHP ووفق قواعد البرمجة غرضية التوجه OOP مما يضيف إليه ميزات جديدة أهمها سهولة الاستخدام وقابلية التوسع، بالإضافة إلى أن نظام جملة متعدد اللغات. حصل نظام جملة على العديد من الجوائز منها أفضل نظام محتوى إدارة محتويات للأعوام الثلاثة السابقة، بالإضافة إلى جائزة أفضل تطبيق مفتوح المصدر من Infoworld Bossie للعام 2012. نبذة تاريخية ظهر نظام جملة في شهر آب عام 2005 كنظام فرعي مستقل عن نظام شركة Mambo التي كانت تُسمّى في ذلك الحين شركة ماريو الدولية المحدودة، ولكن لم يكن هناك تمويل لنظام جملة، لذلك قام مطوروا جملة ببناء موقع يدعى OpenSourceMatters.org نشروا فيه معلومات عن البرنامج كما قام مدير المشروع آندرو ايدي بكتابة رسالة ظهرت في منتدى mamaboserver.com العام للإعلان عن النظام ودعوة المهتمين للمشاركة في بنائه، وقد تفاعل الناس مع الإعلان وقاموا بالانضمام إلى OpenSourceMatters.org في وقت قياسي حيث ساهم المشاركون في انطلاق نظام جملة. بعد هذا التفاعل الكبير من العديد من الناس الموجودين في شركة Mambo والأشخاص الآخرين والذي كان قد لاحظه مدير المشروع، دعى المسجلين في المنتدى لاقتراح اسم للمشروع في شهر آب من العام نفسه بعد أسبوعين من انطلاق الفكرة فقط. وفي 22 أيلول من العام نفسه أُعلِن عن الاسم الجديد للمشروع “Joomla” وهو اللفظ الانجليزي لكلمة “Jumla” القادمة من اللغة السواحلية التي تنطق بها بلاد افريقية مثل تنزانيا وكينيا وتعني "الجميع معًا" أو "الكلِّية" لذلك سنستخدم كلمة "جملة" باللغة العربية للإشارة إلى هذه النظام حيث أنها تحمل نفس المعنى. طريقة تثبيت جملة لتثبيت أي نظام إدارة محتوى على جهازك يجب أن يكون لديك خادوم أولًا، وقد شرحت طريقة تثبيت خادوم WAMP في مقال مقدمة في دروبال. بعد أن قمت بتركيب الخادوم ابدأ بعملية تثبيت نظام جملة وذلك وفق الخطوات التالية: 1- يجب أن نتبه إلى أن الخادوم WAMP يعمل، من خلال التأكد من وجود أيقونه الخادوم في شريط المهام باللون الأخضر 2- نفتح المتصفح على الموقع الرسمي لنظام جملة الذي يحتوى على نواة النظام التي سنقوم بتركيبها https://downloads.joomla.org/ حيث نختار النسخة الأخيرة joomal 3.8.3 ونحمّلها 3- ننتقل إلى مجلد www الموجود بالخادوم من خلال النقر على أيقونة WAMP واختيار www directory من القائمة 4- ننشئ مجلد جديد ضمن مجلد www ولنسميه joomla3 5- نقوم بعملية نسخ لملف نظام جملة الذي حمّلناه بصيغة ZIP في الخطوة الثانية إلى مجلد joomla3 الذي أنشأناه في الخطوة السابقة ونفك ضغطه 6- نفتح صفحة الخادوم الرئيسية من خلال الرابط التالي http://localhost/ حيث نستطيع من خلال هذه الصفحة التأكد من وجود مشروعنا الخاص بجملة 7- ننتقل إلى الموقع الذي قمنا ببنائه من خلال الرابط localhost/joomla3 حيث ستظهر لدينا صفحة إعدادات الموقع 8- ندخل في صفحة الإعدادات اسم الموقع JOOMLA3، البريد الإلكتروني، اسم المستخدمadmin ، كلمة المرور وتأكيد كلمة المرور ثم ننقر على زر NEXT 9- ستظهر لدينا الآن لوحة الإعدادات الخاصة بقاعدة البيانات المتعلقة بالموقع 10- لبناء قاعدة بيانات الموقع نقوم بفتح صفحة التحكم الخاصة بالخادوم عبر الرابط http://localhost/phpmyadmin/ وندخل اسم المستخدم root أما كلمة المرور تترك فارغة 11- بعد الدخول إلى صفحة إعدادات الخادوم ننقر على زر new الموجود في القائمة الجانبية وندخل في المربع create database اسم قاعدة البيانات الخاصة بالموقع مثل joomlaDB ثم ننقر على زر create 12- نعود لصفحة إعدادات جملة التي ظهرت لدينا في الخطوة رقم 9 حيث ندخل مكان username اسم كلمة المستخدم الخاص بقاعدة البيانات root ثم ندخل اسم قاعدة البيانات joomlaDB في خانة Database Name وننقر على زر next 13- ستظهر لدينا أخيرًا صفحة overview ، نلاحظ وجود عدة أقسام في هذه الصفحة حيث نتأكد من اختيار الخيار الأول none في قسم finalization وهو ضروري لأننا سنقوم باستخدام اللغة العربية في موقعنا كما نلاحظ أن جميع المتطلبات في قسم pre-installation check مُعلّمة بجانبها بكلمة yes وهذا يعني أننا قمنا بالخطوات كاملة بالشكل المطلوب لذك نكمل وننقر زر install 14- عند تثبيت الموقع ستظهر لدينا صفحة التي تحوي رسالة تفيد بأن الموقع قد تم تثبيته ولكن نلاحظ رسالة التحذير الموجودة في الأسفل باللون الأصفر ولحلّها ننقر على زر Remove Installation folder 15- نلاحظ الآن بعد انتهاء عملية تثبيت جملة وجود زرين الأول site وهو الذي يأخذنا عند النقر عليه إلى النسخة النهائية لموقعنا والتي يشاهدها المستخدم أما زر administrator فينتقل عند النقر عليه إلى صفحة الدخول للوحة التحكم الخاصة بالموقع وعند النقر على log in سينتقل المتصفح إلى لوحة التحكم control panel وبذلك نكون قد انتهينا من إنشاء موقعنا الخاص باستخدام جملة، ويمكننا البدء بعملية النشر على صفحات الويب. بناء موقع باستخدام جملة بعد أن قمنا بتثبيت نظام جملة سنبدأ الآن ببناء الموقع خطوة بخطوة. أولًا: تغيير لغة جملة إلى العربية للدخول إلى لوحة التحكم control panel الخاصة بموقعنا نستخدم الرابط http://localhost/joomla3/administrator/ وللقيام بتغيير اللغة نتبع الخطوات التالية: 1- ننتقل إلى قسم اللغة من خلال اختيار المسار التالي Extensions -> Languages عندها تظهر لدينا صفحة اللغات حيث ننقر على زر install languages 2- تظهر لدينا قائمة باللغات التي تدعمها جملة، نختار منها اللغة العربية Arabic Unitag وننقر على زر install وفي حال تم تحميل اللغة بنجاج تظهر لدينا رسالة بذلك ضمن المربع الأخضر 3- نعود الآن إلى صفحة اللغة من خلال المسار Extensions -> Languages نلاحظ أنه في القائمة الجانبية تظهر لدينا ثلاث خيارات ثلاث هي installed، content language و overrides 4- الخيار installed يعني لغة الواجهة النهائية التي تظهر للمستخدم، أي أنه في المواقع التي تستخدم اللغة الانجليزية يكون اتجاه الكتابة من اليسار إلى اليمين بينما في اللغة العربية من اليمين إلى اليسار نلاحظ ضمن قائمة اللغات العمود language tag وهو يمثل رمز اللغة المعين من قبل ISO والذي يتم من خلاله تعريف اللغة لجعل اللغة العربية هي لغة الواجهة التي تظهر لزائر الموقع ننقر على زر النجمة المقابل للغة العربية ضمن العمود default تظهر لدينا في الأعلى رسالة باللون الأخضر تفيد بتغير الواجهة إلى اللغة العربية حيث نجد أن اتجاه الموقع الذي نستطيع الوصول إليه من المسار http://localhost/joomla3/ أصبح من اليمين إلى اليسار كما تم تعريب الواجهة 5- الخيار content language يعني لغة محتوى الموقع حيث نلاحظ وجود إشارة × على الحالة أمام اللغة العربية لذلك فقط نقوم بتغيير الحالة إلى publish من خلال الضغط على مربع × 6- الخيار overrides يعني لغة لوحة التحكم ولتغييرها من قائمة Filters نختار خيار اللغة العربية لـ Administrator ثم نقوم بتسجيل الخروج لذلك فإنه عند تسجيل الخروج من لوحة التحكم control panel ثم محاولة الدخول مرة أخرى من خلال الرابط http://localhost/joomla3/administrator سيظهر لدينا خيارات للغة نختار منها اللغة العربية وعند دخولنا ستكون لوحة التحكم قد أصبحت باللغة العربية بشكل كامل ثانيًا: اختيار القوالب يوجد العديد من القوالب المجانية المناسبة لجملة في الإنترنت حيث يمكنك البحث عن إحداها وتثبيتها على موقعك وجميعها تتم بنفس الخطوات. ولكن أولًا دعني أعرفك على أحد المواقع التي تقدم لك قوالب مجانية وهو https://www.siteground.com/joomla-templates.htm حيث يحوي هذا الموقع على الكثير من القوالب وبمجرد اختيارك لأحدها يمكنك أن تنقر عليه عندها ستظهر لديك خيارين إما free download أو view demo في حال أردت أن تشاهد القالب بشكل موسع. هذا الموقع يطلب منك فقط اسمك وبريدك الالكتروني ليرسل إليك خلال ثواني رابط يمكنك من خلاله تحميل القالب. بعد قيامك بتحميل القالب إلى جهازك على شكل ملف ZIP سنبدأ بالخطوات التالية لتثبيته لديك: 1- نقوم بفك ضغط ملف ZIP والذي يعطينا مجلد باسم القالب 2- ننقل مجلد القالب (الذي قمت بتحميله اسمه sunnyorange) إلى المسار التالي ضمن مشروع joomla3 هو C:\wamp64\www\joomla3\templates مع العلم أن هذه المسار اختياري يمكنك تغييره 3- نفتح لوحة التحكم من http://localhost/joomla3/administrator/ ثم من القائمة الجانبية نختار الإضافات ثم تنصيب الإضافات 4- نختار الخيار "تنصيب من مجلد" ونضع في المربع مسار مجلد القالب الذي قمنا بإنشائه في الخطوة 2 ثم ننقر على التأكيد والتنصيب حيث تظهر لدينا رسالة في المربع الأخضر بأنه تم تنصيب القالب بنجاح 5- نلاحظ شكل الواجهة النهائية للمستخدم بالشكل التالي 6- من لوحة التحكم الجانبية نختار مدير القوالب في قسم الإعدادات العامة 7- تظهر لدينا أسماء القوالب حيث يكون القالب الافتراضي المُعلّم بالنجمة الصفراء هو القالب المطبق الآن ولتغييره إلى القالب الذي قمنا بتثبيته فقط نضغط على إشارة النجمة 8- عند فتح واجهة الموقع النهائية نلاحظ أنها تغيرت لشكل القالب الذي قمنا بتحميله ومن الأفضل عند اختيار القالب مراعاة الشكل ليعبر عن هدف الموقع بالإضافة لكونه سهل التعامل والتنقل يجذب الزائر لتكرار تجربة تصفحه. ثالثًا: إضافة محتوى لإضافة مقال جديد إلى الموقع نتبع الخطوات التالية: 1- نختار من لوحة التحكم إضافة مقال جديد فيظهر لدينا محرر المقالة الذي يمكن من خلاله كتابة المقالة وتنسيقها بشكل كامل، مع التأكد من وضع عنوان المقال بالأعلى حيث ستظهر هذه المقالات ضمن مدير المقالات بعد حفظها 2- لإضافة المقالة إلى قائمة موجودة سابقًا كما في حالتنا Main Menu نختار من القائمة الرئيسية اسم القائمة ثم إضافة عنصر جديد 3- سيتظهر لدينا الآن تحرير عنصر قائمة جديد، حيث نلاحظ مكان القائمة في Main Menu 4- نختار ضمن نوع عنصر القائمة مقالات ثم مقال مفرد ليظهر لدينا مربع جديد يمكننا من إضافة المقالات التي أنشأناها سابقًا ثم ننقر على حفظ وإغلاق عند فتح موقعنا نلاحظ وجود عنصر جديد في Main Menu بالإضافة إلى المقالة التي قمنا بكتابتها. يوفّر جملة الكثير من الطرق لإضافة قوائم وعناصر إلى هذه القوائم بالإضافة إلى المقالات والمدونات مع إمكانية تعديلها وتغيير طريقة ترتيبها وكل ذلك من خلال لوحة التحكم، لذلك أنصحك بالاستمتاع ببناء العديد من الأرشيفات والمدونات التجريبية حتى تصل إلى الشكل الأمثل الذي تخطط له. من أهم المواقع التي تم بناؤها باستخدام جملة كلية الدراسات العليا للفنون الجميلة – جامعة هارفارد لينوكس موقع أخبار التقنية العالمي IT Wire موقع قناة التلفزيون MTV Greece مركز الأمم المتحدة الإقليمي للإعلام في أوروبا الغربية UNRIC IKEA
  15. دروبال هو نظام برمجي لإدارة المحتوى مكتوب بلغة PHP مجاني ومفتوح المصدر وتم نشره تحت شروط رخصة GPL والتي تعني أنه يمكن لأي شخص تحميله واستخدامه ومشاركته مع الآخرين من دون أن يتم اقتطاع أي رسوم أو أجر عليه. كلمة دروبال هي تعريب لفظي للاسم الإنجليزي للمشروع Drupal التي أتت بدورها من اللغة الهولندية والتي تكتب بالشكل druppel وتعني قطرة الماء. نبذة تاريخية ظهرت فكرة دروبال في إحدى النقاشات التي كانت تحدث على منتديات البرمجة من قبل Dries Buytaert ومن ثم طُوّرت هذه الفكرة لتصبح مشروع برمجي مفتوح المصدر في عام 2001. بدأ الاهتمام بالدروبال كنظام إدارة محتوى لتطبيقات الويب عام 2003 عندما ساهم في بناء موقع المرشح الديمقراطي للانتخابات الأميركية هاورد ديين حيث استطاع الموقع من خلال استخدام دروبال دعم الشكبة اللامركزية وبالتالي استطاعت مواقع المرشح غير الرسمية التواصل مع بعضها مباشرة ضمن الحملة. وبعد انتهاء الحملة قام شخص من داخل الحملة بمتابعة بناء منصة ويب تساعد في النشاط السياسي وتم إطلاقها في مختبرات CivicSpace في يوليو 2004 وبذلك تكون هذه المنصة أول شركة بموظفيين ذو دوام كامل تعتمد في تطويرها على تقنية دروبال. طريقة تثبيت دروبال سأتحدّث هنا عن عملية تثبيت دروبال ضمن بيئة نظام ويندوز. لتثبيت منصة دروبال وبدء العمل فيها يتوجب علينا أولًا تثبيت خادوم محلي للعمل معه. أكثر الخاوديم المحلية شيوعًاهي XAMP أو WAMP. سنقوم بتثبيت دروبال مع WAMP Server بالخطوات التالية: أولًا: سنقوم بتحميل WAMP Server وتثبيته في الجهاز وذلك حسب الترتيب التالي: 1- نفتح المتصفح على الموقع الرسمي لـ WAMP ثم نتّجه إلى مكان تحميل البرنامج (Download) 2- بعد انتهاء تحميل WAMP نقوم بتثبيته على الحاسوب 3- بعد الانتهاء من عملية تنصيب الخادوم نحتاج للتأكد من أنه يعمل بالشكل الصحيح وذلك من خلال فتح الصفحة الرئيسية على الرابط التالي http://localhost وستظهر لدينا صفحة الخادوم كما في الصورة التالية وستلاحظ أيقونة الخادوم قد أصبحت باللون الأخضر في شريط المهام ثانيًا: سنقوم بتثبيت Drupal 8 على ويندوز ويتم بذلك بالخطوات التالية: 1- نفتح المتصفح على موقع دروبال الرسمي ثم ننقر على قسم التحميل download & Extend كما يشير السهم 2- نختار نسخة drupal8.4.3 وبعد تحميل ملف ZIP نقوم بنقله إلى المسار التالي على حاسوبك وهو C:\wamp64\www ثم يمكنك تغيير اسم الملف الناتج إلى drupal8 فقط 3- نقوم بزيارة صفحة drupal التي قمنا بتثبيتها من خلال الرابط التالي http://localhost/drupal8 فتظهر لدينا الصفحة الرئيسية لدروبال 4- نقوم باختيار اللغة English ونضغط على save and continue للمتابعة في عملية التنصيب 5- سينتقل إلى صفحة choose profile نختار الخيار الأول standard ونتابع 6- ستظهر لك قائمة بالمتطلبات التي يجب تصحيحها في حال كان هناك متطلبات في حال لم يكن هناك أي خطأ يمكنك الضغط في نهاية الصفحة على continue anyway 7- ستظهر لدينا الآن لوحة بناء قاعدة البيانات الخاصة بالموقع 8- نفتح إعدادات الخادوم من خلال الضغط على أيقونة WAMP الموجودة في شريط المهام ونختار الخيار phpMyAdmin اسم المستخدم هو root وكلمة المرور تترك فارغة لتُفتح لدينا إعدادات الخادوم 9- لبناء قاعدة البيانات علينا النقر أولًا على زر New ثم ندخل اسم قاعدة البيانات drupal8 على سبيل المثال ثم ننقر على زر create وبذلك نكون قد أنشأنا قاعدة البيانات 10- نعود لصفحة إعداد دروبال التي في الخطوة رقم 7 وندخل اسم قاعدة البيانات التي أنشأناها سابقًا drupal8 واسم المستخدم root ونترك خانة كلمة المرور فارغة (لم نقم بوضع كلمة مرور على قاعدة البيانات عند بنائها) ثم نضغط على save and continue حيث سيبدأ بعملية تنصيب الموقع installing site التي قد تأخذ بعض الوقت 11- ستظهر لدينا لاحقًا صفحة إعدادات الموقع والتي تطلب اسم الموقع واسم المستخدم لإدارة الموقع وكلمة المرور 12- في النهاية ستظهر لدي صفحة إدارة موقع الانترنت وبالتالي أكون قد أنشأت موقعي الخاص والآن يمكنني من خلال دروبال إضافة الصفحات والمحتوى من خلال الصفحة الأخيرة. بناء موقع باستخدام دروبال تتميز دروبال بالقوة والسرعة والكفاءة في العمل بالإضافة إلى الواجهة الجذابة. ومن الأفضل للمستخدم أن يكون ملمًّا بلغة PHP ليتمكن من تخصيص الموقع وتصحيح الأخطاء رغم أنه أمر غير مطلوب عند بناء الموقع. سنبدأ ببناء الموقع الجديد خطوة بخطوة: أولًا: تغيير لغة الدروبال إلى العربية بعد بناء الموقع نلاحظ أن واجهته والقوائم فيه باللغة الإنجليزية ولتحويله إلى اللغة العربية نقوم بما يلي: 1- من شريط المهام في رأس الصفحة نختار extend ونقوم باختيار Modules الخاصة باللغة وهي language, interface translation, content translation, configuration translation وبعدها install 2- بعدها ننتقل من configuration إلى languages ونضغط على زر Add language ثم نختار اللغة العربية Arabic بعدها Add language لتبدأ عملية تحميل اللغة العربية إلى الموقع. 3- نختار اللغة العربية كـ default ونضغط save configuration ليتحوّل بعدها اتجاه الصفحة من اليمين إلى اليسار. 4- لتعريب الواجهة كاملة نذهب إلى موقع دروبال الرسمي الذي يقدم ملفات تحوي ترجمة لأغلب لغات العالم ونختار اللغة العربية نلاحظ أن المعلومات المتوفرة عن اللغة العربية هي أن عدد المساهمين 60 شخصًا وقد تم الانتهاء من 1.04% فقط من دروبال 5- نقوم بعدها بتحميل نسخة اللغة drupal 8.4.3 وهي النسخة المطابقة لنسخة النواة التي لدينا 6- نعود إلى صفحة موقعنا ونذهب إلى configuration ثم user interface translation ثم import بعدها نختار ملف اللغة العربية drupal-8.4.3.ar.po الذي قمنا بتحميله في الخطوة السابقة وفي النهاية نضغط import بعد الانتهاء من عملية استيراد الملف نلاحظ تغير واجهة الموقع بشكل كامل إلى اللغة العربية ثانيًا: اختيار القوالب يقدم دروبال العديد من القوالب حيث يمكنك اختيار إحداها. لإضافة قالب theme نقوم باختيار “المظهر” من القائمة الرئيسية فتظهر لدينا صفحة من القوالب الموجودة مسبقًا كما نلاحظ يوجد “الحلة الافتراضية” أي المظهر الحالي ولتغييره نقوم بالضغط على install new theme حيث ستظهر صفحة لإدخال رابط theme الذي نستطيع اختياره من الموقع الرسمي للدروبال والذي يقدم 2564 قالب مختلف كما يقدم لنا دروبال خاصية تحميل قالب خاص بنا. بعد اختيار القالب نقوم بفتح الصفحة الخاصة به وفي نهايتها سنجد downloads والتي تحتوي على نوعين من الملفات بالضغط على الزر اليميني على نوع الملف tar.gz ونختار copy link address ننسخ هذا العنوان إلى صفحة install new theme في دروبال ونختار تثبيت بعد ذلك نضغط على home ثم “المظهر” فتظهر لدينا قائمة بالقوالب الموجودة لدينا عندها يمكن اختيار أي منها لتكون theme الخاص بالموقع من خلال الضغط على set as defualt. من المهم عند اختيارك لتصميم شكل موقعك أن تراعي الأمور التالية: سهولة التعديل. أن يظهر التصميم بشكل جيد على جميع الأجهزة (حاسب، جهاز لوحي، موبايل). البساطة والتي تساعد الزائر على التنقل بسهولة بين كافة محتويات الموقع. ثالثًا: بناء صفحة ضمن الموقع سنقوم معًا ببناء صفحة “نبذة عنّا” وذلك من خلال اتباع الخطوات التالية 1- من الصفحة الرئيسية نختار "الأدوات -> إضافة محتوى" بعدها تظهر لنا صفحة فيها خيارين لشكل المحتوى الذي نريد إضافته إما Article أو Basic Page، نختار الخيار الثاني Basic Page. 2- تظهر لدينا صفحة "أنشئ Basic Page" نضيف عنوان للصفحة على سبيل المثال "نبذة عنّا" وضمن قسم المتن نضيف محتوى الصفحة. من أجل أن يظهر رابط الصفحة في القائمة الرئيسية يجب اختيار المربع "يوفّر رابط القائمة" من القائمة “إعدادات القائمة” ونضغط في أخيرًا على “حفظ” 3- لتغيير ترتيب عناصر القائمة الرئيسية نقوم باختيار "الهيكلية -> القوائم -> main navigation" ثم نختار تحرير القائمة ونقوم بترتيب العناصر الموجودة في رابط القائمة حيث يمكن أن نضع الرئيسية ونبذة عن على نفس المستوى أو نرتبها كقائمة داخل بعضها بالإضافة إلى تغيير الترتيب. وبهذه الخطوات البسيطة يمكننا إضافة محتوى للموقع الالكتروني والتحكم بطريقة عرضه وترتيبه. ميزات استخدام منصة دروبال تتجه العديد من الشركات والمنظمات لإنشاء مواقعها باستخدام دروبال وذلك بسبب الكثير من الميزات التي يقدمها ولعل أهمها: 1- الأداء الفعال والسريع: صفحات دروبال تتحمل أسرع ولديها استجابة أسرع من المواقع المصممة من خلال منصات أخرى وذلك لعدم احتوائه على الكثير من الموارد الكثيفة وبالتالي يحتاج إلى سيرفرات أقل كلفة. 2- عالي التكيّف: بمعنى أنه يمكنك تغيير شكل وتصميم موقعك الخاص حسب رؤيتك الخاصة حيث يقدم لك دروبال مجموعة واسعة من القوالب والإضافات التي تحوي على الكثير من الخيارات. 3- الأهم من ذلك كله أنه مجاني مدى الحياة حيث يمكنك تحميله وتنصيبه على سيرفر الاستضافة دون أي تكاليف. من أهم الشركات والمنظمات التي قامت باختيار دروبال لتصميم مواقعها عربيًا وعالميًا نذكر: من أهم الجامعات التي تستخدم دروبال لموقعها الرسمي جامعة هارفرد جامعة كولورادو جامعة أكسفورد بالإضافة إلى مواقع عالمية أخرى وكمثال سنذكر بعضها: موقع نادي إشبيلية الإسباني موقع أولمبياد ريو في البرازيل 2016 موقع شبكة NBC الموقع الرسمي لحكومة استراليا الموقع الرسمي لحكومة جنوب أفريقيا الموقع الرسمي لحكومة فرنسا صحيفة الموجز المصرية صحيفة لوفيجارو الفرنسية وغيرها العديد من المواقع…