البحث في الموقع
المحتوى عن 'تطوير الويب'.
-
لا يخفى على أحد اليوم مدى أهمية تطوير مواقع الويب فالجميع اليوم يسعى لإنشاء موقع إلكتروني خاص به بدءًا من الأشخاص ووصولًا للعلامات التجارية الكبرى إما للتعريف عن أنفسهم وإثبات وجودهم في الفضاء الرقمي، أو لبيع منتجاتهم وخدماتهم، أو تسيير معاملات عملائهم عبر الإنترنت، وغيرها من الفوائد التي لا حصر لها. لكن هل تعلم أن معظم مواقع الويب المتقدمة التي تتعامل معها لا تقتصر على الجزء الذي تراه أمامك على الشاشة والذي يعرف بالواجهات الأمامية لمواقع الويب بل هناك أيضًا الواجهات الخلفية الخفية المسؤولة عن إنجاز كافة الوظائف التي يتضمنها الموقع وجعل كل عناصره من أزرار وقوائم تتفاعل معك بالشكل الصحيح وهي تستخدم تقنيات وأدوات برمجية مختلفة عن تلك التي تستخدمها الواجهات الأمامية. نسلط الضوء في مقال اليوم على كل ما يخص تطوير الواجهات الخلفية لمواقع الويب، ونستعرض أهم المهارات والتقنيات التي تحتاج لتعلمها وأهم المسؤوليات المنوطة بها، فإذا كنت ترغب في العمل كمطور واجهة خلفية لكنك لا تعرف من أين تبدأ وما هي خطوات التعلم الصحيحة فهذا المقال سيفيدك حتمًا. كيف تعمل مواقع الويب؟ قبل الغوص في تفاصيل تطوير مواقع الإنترنت ومفهوم الواجهة الأمامية والخلفية لموقع الويب دعنا نتعرف بداية على المصطلحات الأساسية للويب والكيفية التي تعمل مواقع الويب وفقها. مبدئيًا لدينا نوعان من الأجهزة المتصلة بشبكة الإنترنت هما العميل client وهو جهازك الحالي وهو ببساطة هو الجهاز المتصل بالإنترنت التابع للمستخدم الذي يتصفح الإنترنت من خلال تطبيق خاص مثبت فيه هو متصفح الويب web browser مثل جوجل كروم أو فايرفوكس. خادم الويب web server وهو حاسوب بعيد مصمم للعمل كمستودع لملفات مواقع الويب من أكواد برمجية وملفات صور والنصوص وغيرها من العناصر التي تراها على موقع الويب وتسهل وصولك إليها فمطور المواقع يقوم بتحميل كل هذه الملفات إلى الخادم وأنت تتصل به وتعرض هذه الملفات على جهازك. يجب أن يزود الخادم ببرامج خاصة تمكنه من استقبال الطلبات الواردة إليه ومعالجتها والرد عليها ويجب أن يكون متصلًا بالإنترنت بصورة دائمة ويلبي طلبات العملاء بسرعة مع العلم بأن تسمية الخادم تختلف بحسب طبيعة الخدمة التي يقدمها فإذا كان الخادم يوفر خدمة قاعدة بيانات يسمى خادم قاعدة البيانات وإذا كانت يخزن صفحات الويب يسمى خادم ويب له عنوان URL فريد يمكن الوصول إليه عبر الإنترنت. الفرق بين الواجهة الأمامية Frontend والواجهة الخلفية Backend قبل الغوص في تفاصيل تطوير الواجهة الخلفية من الضروري أن تفهم الفرق بين الواجهة الأمامية frontend والواجهة الخلفية backend وهما مصطلحان يهدفان إلى فصل الاهتمامات بين طبقة العرض أو واجهة المستخدم أو ما يعرف بالواجهة الأمامية للتطبيقات والمواقع وبين طبقة الوصول إلى البيانات أو ما يعرف بالواجهة الخلفية التي تعمل خلف الكواليس. هل يبدو هذا صعب الفهم! حسنًا لنفترض أنك تتصفح أحد متاجر بيع الملابس على الإنترنت أنت تتفاعل الآن مع ما يسمى بالواجهة الأمامية للموقع فكافة أجزاء موقع الويب التي تراها أمامك والتي تعرض على متصفحك من عناوين وفقرات وصور وأزرار وأيقونات هي في الواجهة الأمامية للموقع. لكن من أين تم جلب قائمة المنتجات التي تراها في واجهة المستخدم؟ الجواب أنها خزنت في قاعدة البيانات المخزنة في الواجهة الخلفية وتم عرضها على الواجهة الأمامية لديك لتتصفحها، بعدها أعجبتك عدة قطع وقررت شراءها وحددت خياراتك المفضلة كاللون والقياس وما إلى ذلك ونقرت فوق زر إضافة لسلة المشتريات ثم أدخلت كافة بياناتك المطلوبة لكنك لم تكمل عملية الشراء لأن ثمن المشتريات لم يكن بحوزتك فخرجت من الموقع، برأيك أين تم حفظ هذه البيانات؟ نعم صحيح كما توقعت أيضًا في قاعدة بيانات الموقع المخزنة على الخادم. بعد ذلك بأيام عدت للموقع ونقرت فوق زر سلة المشتريات لتكمل عملية الشراء، سيقوم الكود المربوط بهذا الزر بسحب كل المعلومات التي أدخلتها من قاعدة البيانات ويحسب ثمنها ويرسلها إليك، كل هذا تم في الواجهة الخلفية للموقع، وبالتالي الواجهة الخلفية للموقع هي الجزء الخفي الذي يعمل وراء الكواليس، أما الكيفية التي ستعرض بها هذه البيانات لك فهي مسؤولية مطور الواجهة الأمامية. فأي كود مسؤول عن الجوانب المرئية لموقع الويب كتبه مطور الواجهة الأمامية وهو ينفذ في المتصفح، وأي كود يتعامل مع قواعد البيانات وواجهات برمجة التطبيقات كتبه مطور الواجهة الخلفية وهو ينفذ في الخادم. هناك نوع ثالث من المطورين يطلق عليه مطور الويب الكامل fullstack web developer أو المطور الكامل full stack developer وهو الذي يتولى بنفسه كتابة كل من كود الواجهة الخلفية والواجهة الأمامية للمواقع والتطبيقات ويملك خبرة بكليهما. للمزيد من التفصيل حول الواجهة الأمامية، يمكنك الرجوع إلى مقال تطوير الواجهة الأمامية لمواقع الويب Frontend Web Development الشامل. ما هو تطوير الواجهة الخلفية للويب؟ تطوير الواجهة الخلفية للويب أوما يعرف بتطوير النظم الخلفية backend development أو التطوير من طرف الخادم server-side هو عملية كتابة الشيفرات البرمجية التي تعمل على خوادم الويب web servers والتي تجعل موقع الويب يعمل خلف الكواليس ويتفاعل مع المستخدمين ويلبي كافة طلباتهم. الهدف من تطوير الواجهة الخلفية هو خلق تواصل بين الواجهات الأمامية وبين قاعدة البيانات عبر الخادم فالمستخدم يتفاعل مع الموقع عن طريق إدخال البيانات بعدها نخزن هذه البيانات في قاعدة البيانات الموجودة على نفس الخادم أو خادم منفصل، وأخيرًا يعيد الخادم النتائج المطلوبة ويعرضها على المتصفح أو ما يعرف بالعميل أو الواجهة الأمامية للموقع. لا غنى عن تطوير الواجهات الخلفية في مواقع الويب الديناميكية dynamic websites التي تتفاعل مع المستخدمين وتحتاج إلى تخزين البيانات وفهرستها وحفظها واستردادها وتعديلها وحذفه مثل مواقع التجارة الإلكترونية والمواقع التي تتطلب ملء نماذج وتخزين البيانات المتغيرة مثل وصف المنتجات والمنشورات وملفات تعريف المستخدمين وما إلى ذلك. أما مواقع الويب الثابتة أو الساكنة static websites فهي لا تتطلب تطوير الواجهة الخلفية وتكون مجرد مواقع بسيطة بمحتوى ثابت ولا تتفاعل مع المستخدمين ولا تستطيع تخزين أي شيء وتسعمل خوادم شبه جاهزة لتخديم البيانات. أهمية تطوير الواجهة الخلفية في سوق العمل لا شك أن أهمية تطوير الواجهة الخلفية ينتج عن انتشار تطبيقات الويب وليس فقط مواقع الويب والاعتماد الكبير على عالم الإنترنت والتطبيقات السحابية من برامج محاسبة وفيديو وإدارة مهام …إلخ. فجميع هذه التطبيقات تحتاج إلى بيانات ديناميكية وبالتالي تحتاج جميعها لتطوير واجهات خلفية. وحسب استطلاع الرأي الذي أجراه موقع موقع Stackoverflow الشهير للعام 2022 والذي يشارك فيه عدد كبير من المطورين والمبرمجين حول العالم تبين أن أكثر غالبية المشاركين في الاستطلاع ونسبتهم 46.82% هم في المقام الأول مطورون كاملون full-stack يليهم مباشرة مطورو الواجهة الخلفية back-end بنسبة 43.38% وبعدهم مطورو الواجهة الأمامية front-end بنسبة 25.96% ويلي ذلك باقي التخصصات البرمجية الأخرى. هذا يدل على أهمية مجال تطوير الويب عمومًا وتطوير الواجهة الخلفية على وجه الخصوص والطلب الكبير عليه في سوق العمل وإلا لم يكن الإقبال عليه ليصل لهذه النسب المرتفعة. كما يعد تطوير تطوير الواجهة الخلفية مجالًا وظيفيًا مربحًا وسريع النمو حيث متوسط الراتب السنوي لمطور الواجهة الخلفية وفق نفس الاستبيان في الولايات المتحدة، في عام 2022، بما قدر بـ 68 ألف دولار سنويًا وهذا الرقم بلا شك يختلف من بلد لآخر ويعتمد على سنوات خبرة المطور إلا أنه يظل رقمًا مرتفعًا مقارنة بباقي المهن والتخصصات. وبالتالي فإن استثمارك في تعلم تطوير الواجهات الخلفية للويب يفتح أمامك الكثير من فرص العمل المجزية والمضمونة، وطالما أن الأشخاص والشركات بحاجة إلى مواقع الويب والمتاجر الإلكترونية فستكون هناك حاجة إلى مطوري ويب. مهام ومسؤوليات مطور الواجهة الخلفية إذا قررت العمل كمطور واجهة خلفية فهذا يعني أنك ستكون المسؤول الأساسي عن تطوير كافة أجزاء موقع الويب التي تعمل من جانب الخادم وصيانتها واختبارها وتصحيحها. يمكن القول أنك مسؤول عن العمود الفقري لتطبيقات الويب والعمل في هذا المنصب يتطلب منك القيام بعدة مهام تشمل ما يلي: التواصل مع العملاء وأعضاء الفريق البرمجي وفهم احتياجات الموقع أو التطبيق وتحديد كافة البيانات والوظائف المطلوبة للعمل في الواجهة الخلفية. كتابة الشيفرات البرمجية التي تحقق وظائف الموقع باستخدام لغات البرمجة التي تعمل من جانب الخادم. معالجة كافة طلبات مستخدمي الموقع. صيانة عناصر الواجهة الخلفية واستكشاف أي أخطاء فيها وإصلاحها. إنشاء قواعد بيانات الموقع وتحسينها وإدارتها والاستعلام منها. إنشاء واجهات برمجة التطبيقات API من جانب الخادم والتي يحتاجها مطورو الواجهة الأمامية لاسترداد البيانات وعرضها. إعداد وإدارة بيئات الاستضافة وتثبيت البرنامج الضرورية على الخادم. تحسين أداء تطبيقات الويب وأمانها وتخفيف زمن تحميلها واستجابتها وتعزيز تجربة مستخدميها. دمج الخدمات الخارجية مثل بوابات الدفع والخدمات السحابية مثل Amazon Web Services و Azure مع الموقع. إجراء عمليات النسخ الاحتياطي واستعادة ملفات الموقع وقاعدة البيانات في حال وقوع أي طارئ. التأكد من أمان الموقع وحمايته من الاختراق. بعد الاطلاع على قائمة المهام أعلاه هل تجد مجال تطوير الواجهات الخلفية مناسب لك؟ أنصحك بمتابعة قراءة هذا المقال لتتعرف على أهم لغات البرمجة لتطوير الواجهات الخلفية وأهم النصائح التي تساعدك لتصبح مطور واجهات خلفية محترف. لغات تطوير الواجهة الخلفية Backend يمكن لمطوري الواجهات الخلفية استخدام العديد من لغات البرمجة والأدوات وأطر العمل التي تسهل عملية بناء تطبيقات تتصل بالخادم وتتفاعل مع قواعد البيانات، ستكون أول خطوة عليك القيام بها كمطور واجهات خلفية هو تحديد اللغات التي ستستخدمها، ولتسهيل المهمة عليك فقد جمعنا لك قائمة بأفضل لغات تطوير النظم الخلفية التي يمكنك استخدامها في عملك وأهم مميزاتها وأطر عملها. أهم لغات تطوير الواجهة الخلفية: لغة جافا سكريبت JavaScript مع Node.js لغة بايثون Python لغة PHP لغة روبي Ruby لغة جافا Java لغة C# دعنا نتناول كل لغة من بينها بمزيد من التفصيل ونتعرف على وأطر عملها ودورها الفعال في تطوير الواجهات الخلفية للويب. لغة جافا سكريبت JavaScript تعد جافا سكريبت واحدة من أكثر لغات البرمجة شهرة وانتشارًا بين أوساط المبرمجين بفضل سهولتها وإمكانية استخدامها لكل من تطوير الواجهة الخلفية والأمامية للويب، فهي تستخدم بشكل أساسي لإنشاء مواقع تفاعلية وديناميكية من جانب العميل وتعمل ضمن المتصفحات فقط، لكن بات بمقدورها بفضل بيئة تشغيل Node.js العمل على جانب الخادم وبرمجة الواجهات الخلفية بخروجها من بيئة المتصفح وبهذا يمكنك تعلم جافا سكريبت من العمل كمطور كامل fullstack ويفتح لك فرصًا أكبر. توفر جافا سكريبت كذلك الكثير من أطر عمل تطوير الواجهة الخلفية التي توفر مجموعة من الأكواد والمكتبات الجاهزة للاستخدام والتي تبسط مهام تطوير المواقع وتجعلها أسرع وأكثر كفاءة ومن ضمنها Express.js و Meteor.js وBackbone.js لكل إطار عمل منها ميزات مختلفة ويصلح لأنواع مواقع معينة أكثر من غيرها لذا عليك البحث في الإطار الذي تود استخدامه والتأكد أنه يلبي متطلباتك بشكل جيد. لغة بايثون Python تعد لغة بايثون إحدى أسهل لغات البرمجة وأكثرها شعبية بفضل بنيتها البسيطة والمقروءة، وهي تستخدم في العديد من المجالات ومن بينها تطوير الواجهات الخلفية للويب وهي تستخدم من قبل كبرى الشركات التقنية مثل إنستغرام و Dropbox. ويمكن استخدام أطر عمل بايثون مثل إطار العمل جانغو Django أو فلاسك flask أو FastAPI لتقليل كتابة التعليمات البرمجية وتبسيط عملية تطوير الواجهات الخلفية لمواقع الويب المتقدمة بشكل أسرع و أكثر أمانًا. لغة PHP ذاع صيت لغة PHP لفترة طويلة كواحدة من أشهر لغات الويب وهي تستخدم في تطوير حوالي 80% مواقع الويب في العالم لكونها لغة سريعة ومرنة يمكنها تطوير كافة أنواع المواقع من المدونات البسيطة إلى المتاجر الرقمية المتقدمة. لم تفقد PHP قوتها أمام اللغات الأخرى بفضل قوة أطر العمل المبنية عليها ولعل أشهرها إطار العمل لارافيل Laravel وهو إطار عمل مفتوح المصدر لتطوير الواجهات الخلفية لمواقع الويب بشكل منظم وسهل وآمن وسهل الاستخدام. إلى جانب العديد من أنظمة إدارة المحتوى CMS التي تجعل من تطوير المواقع وإنشاء المحتوى وتعديله وإدارته غاية في السهولة ولا يستلزم أي مهارات تقنية ومن أشهرها ووردبريس WordPress ودروبال Drupal. لغة روبي Ruby روبي هي لغة برمجة نصية مفتوحة المصدر أطلقت عام 1995 وقد اكتسبت هذه اللغة شعبية كبيرة بين أوساط المبرمجين بفضل تركيبتها التي تشبه إلى حد كبير اللغة الإنجليزية المحكية لذا تعد من أسهل لغات البرمجة المستخدمة في تطوير تطبيقات للويب. ورغم أنها ليست بشهرة اللغات السابقة في العالم العربي إلا أن شعبيتها تزداد بالتدريج على مستوى العالم وستجد الكثير من الوظائف المتوفرة عند تعلمها لاسيما عندما تتقن إطار عملها الشهير Ruby on Rails في تطوير تطبيقاتك فهو يسهل ويسرع عملك بشكل لافت. لغة جافا Java جافا هي لغة برمجة عريقة تم إطلاقها عام 1991 وهي لغة قوية ومتعددة الأغراض تعتمد مبدأ البرمجة كائنية التوجه OOP وعلى الرغم من إمكانية تشغيلها على المتصفح إلا أنها مصممة بشكل أساسي لتطوير الواجهات الخلفية للتطبيقات. بالرغم من أن شعبية جافا آخذة في الانخفاض وكونها لغة صعبة التعلم مقارنة بلغات البرمجة الأحدث إلا أنها لاتزال تستخدم في الكثير من مواقع الويب نظرًا لقوتها وضمان أمان التطبيقات المبنية بها لأنها لا تنفذ على الجهاز نفسه بل تنفذ على آلة جافا الافتراضية Java Virtual Machine أو اختصارًا JVM ما يضمن حماية التطبيقات وعزلها. كما تتضمن جافا العديد المكتبات وأطر عمل الواجهة الخلفية التي تسهل تطوير التطبيقات وصيانتها مثل Spring لذا تعد أحد الخيارات التي يمكنك الاعتماد عليها كمطور واجهات خلفية. لغة C# تعد لغة C# واحدة من أفضل لغات البرمجة وهي لغة عريقة عمرها يزيد على عشرين عامًا ولازالت تصلح لجميع أنواع التطبيقات ولبناء تطبيقات الويب يمكن استخدامها مع إطار عمل دوت نت NET Framework. الشهير الذي يستخدم لبناء تطبيقات ومواقع الويب بناء على لغة C# ويوفر بيئة تطوير واجهات خلفية قوية وفعالة يوفر وظائف مخصصة لإدارة كميات كبيرة من البيانات وإعدادات أمان قوية والكثير من الميزات الجاهزة ويسمح بالعمل مع واجهات برمجة تطبيقات الويب الأصلية. تقنيات وأدوات مهمة لتطوير الواجهة الخلفية Backend بعد أن تعرفت على أهم لغات برمجة وأطر عمل تطوير الواجهات الخلفية للويب دعنا نتعرف الآن على التقنيات والمهارات والأمور الأخرى التي تفيدك بشكل كبير في العمل تطوير الواجهات الخلفية. واجهات برمجة تطبيقات API قواعد البيانات وأبرز أنواعها ونظم إدارتها معرفة أساسية بالشبكات وأمنها أسس التعامل مع الخوادم والاستضافات ومزودات الخدمة السحابية نظم التحكم بالإصدارات Git أدوات إدارة الحزم Package Management System استخدام الحاويات Containers الإحاطة بأساسيات لغتي HTML و CSS وإليك معلومات إضافية عن كل تقنية من هذه التقنيات وكيف تفيدك كمطور ويب. واجهات برمجة تطبيقات API من الضروري كمطور واجهة الخلفية أن تتعلم مفهوم واجهة برمجة التطبيقات Application Programming Interface أو اختصارًا API وهو آلية تمكن التطبيقات والمواقع من التواصل مع بعضها والحصول على البيانات الخاصة ببعضها مهما كانت التقنية التي طورت بها هذه التطبيقات وسواء كانت تطبيقات واجهة خلفية تعمل من طرف الخادم أو تطبيقات واجهة خلفية تعمل من طرف العميل. ومن أبرز الأمثلة على أنواع واجهات برمجة التطبيقات نذكر RESTful API الذي يستخدم تنسيق JSON لتبادل البيانات و GraphQL الذي يعد مفهومًا لنقل وتبادل البيانات على شكل استعلامات queries، ويجب أن تحيط بهذين المفهومين جيدًا كمطور واجهات أمامية. وللمزيد حول مفهوم واجهات برمجة التطبيقات وكيفية استخدامها أنصح بمشاهدة فيديو ما هي الواجهة البرمجية API التالي: قواعد البيانات وأبرز أنواعها ونظم إدارتها يحتاج أي مطور واجهات خلفية لامتلاك معرفة في طريقة التعامل مع قواعد البيانات ونظم إدارتها وأنواعها المختلفة ومن أهمها: قواعد البيانات العلائقية التي تستخدم لغة SQL وتخزن بيانات التطبيقات ضمن جداول مرتبطة ببعضها البعض ومن أبرز أنظمة إدارة قواعد البيانات العلائقية نذكر MySQL و SQLite و PostgreSQL. قواعد البيانات غير العلائقية NoSQL وهي أشهر بدائل قواعد البيانات العلائقية التي تخزن بيانات التطبيقات بطرق أخرى غير الجدول العلائقي ومن أشهر نظم إدراتها نذكر MongoDB وكاساندرا. وقد ناقشنا في مقال دليلك الشامل إلى قواعد البيانات DataBase المزيد من الأنواع وميزات واستخدامات كل نوع من بينها بالتفصيل. معرفة أساسية بالشبكات وأمنها تحتاج كمطور واجهة خلفية إلى امتلاك معرفة أساسية ببروتوكولات الاتصال عبر الويب مثل: بروتوكول HTTP بروتوكول HTTPS وشهادة SSL بروتوكول WebSocket كما يحتاج أي مطور ويب لفهم آلية عمل شبكة الإنترنت والمفاهيم الأساسية المرتبطة بها مثل عناوين بروتوكول الإنترنت IP Addresses وأسماء النطاقات في شبكة الإنترنت. ولا يجب أن يغفل عن مفاهيم أمن الويب واتخاذ كافة إجراءات الحماية اللازمة لحماية قواعد بيانات موقع الويب وحماية مسارات واجهة برمجة التطبيقات من الثغرات الأمنية ومن محاولة سرقة البيانات ويستخدم أساليب المصادقة والأذونات التي تتحكم في وصول المستخدمين للتطبيقات ويشفر أي بيانات حساسة ويتحقق من صحة أي مدخلات من قبل المستخدمين وغيرها الكثير من إجراءات الحماية. قد ترغب في مشاهدة الفيديو التالي للتعرف على مزيد من المعلومات حول أشهر طرق الاختراق وسبل الوقاية منها. معرفة جيدة بنظم التشغيل يحتاج مطور الواجهة الخلفية لامتلاك معرفة أساسية بنظم التشغيل وخصوصًا نظام التشغيل لينكس لأن أغلب الخوادم تعمل بنظام لينكس وبالتالي تعلمه يمكنك من معرفة أساسيات التعامل مع الخوادم والاستضافات ومزودات الخدمة السحابية والتعامل مع واجهات سطر الأوامر أو الطرفية وطرق رفع الملفات إلى الاستضافة والوصول إلى قاعدة البيانات المخزنة عليه. كما يحتاج لامتلاك معرفة كافية بمنصات استضافة الويب وطريقة نشر وتشغيل الموقع على خادم ويب مثل خادم أباتشي Apache و خادم إنجن إكس Nginx ومعرفة طريقة التعامل مع مزودات الخدمة السحابية والاستفادة من أنواع الخدمات السحابية المختلفة، ولمزيد من المعلومات يمكنك متابعة العديد من الدروس حول الحوسبة السحابية في أكاديمية حسوب. نظم التحكم بالإصدارات Git تساعد نظم التحكم بالإصدارات المطور في إدارة التغييرات التي يقوم بإجرائها على الشيفرات البرمجية لمشاريعه وتطبيقاته ومن أشهرها نذكر Git وهي عبارة أداة برمجية تمكنك من العودة بسهولة إلى إصدار سابق يعمل بشكل صحيح من مشروعك في حال حدث خطأ ما بدلاً من البحث عن سبب الخطأ ومحاولة التراجع عنه يدويًا، كما أنه يفيد المطور بشكل كبير عند العمل على مشروع مشترك مع فريق عمل فهو ينظم التعديلات المختلفة ويمنع تضاربها. والجدير بالذكر أن التعامل مع أنظمة التحكم بالإصدارات هو ضرورة ولا يستطيع أي مبرمج أو مطور ويب العمل دون خبرة بها وستجد في أكاديمية حسوب مجموعة غنية ومنوعة من المقالات والدروس حول Git التي تساعدك في تعلم التعامل مع نظم التحكم بالإصدارات من الصفر حتى الاحتراف. أدوات إدارة الحزم Package Management System تتضمن معظم التطبيقات اليوم حزمًا ومكتبات خارجية ومن الصعب تطوير التطبيقات اليوم دون الاعتماد على أحد الأدوات البرمجية المساعدة في إدارة هذه الحزم الخارجية وعدم تعارضها، ومن الأمثلة عليها مثل npm الذي يأتي مع Node.js الذي يُستخدم مع لغة جافا سكريبت أو composer المستخدم مع لغة PHP. فمعظم مشاريع الويب اليوم تتضمن الكثير من الحزم التي يعتمد بعضها على بعض وهذه البرمجيات أساسية لمساعدتك في تحديد الحزم اللازمة لمشروعك ويحدد التبعيات المناسبة بنفسه والتأكد من توافقها مع التبعيات الأخرى ويتحكم في إصدارات الحزم التي تقوم بتثبيتها. استخدام الحاويات Containers بالرغم من أن تعلم استخدام الحاويات Containers يعد مهارة إضافية وليس لزامًا عليك كمطور واجهة خلفية إلا أن تعلمها يساعدك في بناء مشاريعك واختبارها ونشرها بكفاءة فالحاويات هي عبارة عن حزم برمجية تتضمن كافة العناصر الضرورية لتشغيل التطبيق في أي بيئة أو نظام تشغيل لكنه يكون معزول ضمن حاوية معزولة منطقيًا عن التطبيقات الأخرى بحيث لا يتعارض معها. يمكنك إنشاء الحاويات وتشغيلها باستخدام تقنية مثل دوكر Dockerوهي تقنية حاوية مفتوحة المصدر تعتمد على نظام لينكس وتسمح للمطورين ببناء وتشغيل التطبيقات واختبارها ونشرها بسهولة، وللاطلاع على مزيد من التفاصيل حول مفهوم الحاويات وأهميتها لمطوري التطبيقات يمكنك مشاهدة الفيديو التالي: الإحاطة بأساسيات لغتي HTML و CSS يحتاج مطور الواجهات الخلفية معرفة الجوانب الأساسية لكل من HTML و CSS اللتان تستخدمان لبناء الواجهات الأمامية فحتى لو لم يستخدمها في عمله فهو يحتاج للتواصل مع مطوري الواجهة الأمامية بشأنها وهي تقنيات سهلة التعلم. من أهم الأساسيات التي ينبغي تعلمها في لغة HTML هي طريقة إنشاء صفحة ويب ثابتة وإنشاء النماذج ومعالجتها وآليات الإدخال المختلفة إضافة إلى معرفة طريقة إنشاء قواعد التنسيق في CSS وكيفية عمل المحددات والفرق بين المعرف id والصنف class. يمكنك معرفة المزيد حول هاتين اللغتين من خلال مطالعة مقال تعلم لغة HTML ومقال أساسيات لغة CSS. خارطة طريق لتعلم تطوير الواجهات الخلفية هل تشعر بالتشتت من كثرة التقنيات التي عليك تعلمها لتصبح مطور واجهة خلفية ولا تعرف من أي واحدة تبدأ وكيف تنظم خطوات التعلم؟ دعني أساعدك وأوضح لك خارطة طريق لتعلم مجال تطوير الواجهات الخلفية والتي تعرض بوضوح طريق مطور الواجهات الخلفية backend في مجال تطوير الويب بالكامل بدءًا من المرحلة الأساسية وحتى المتقدمة وأغلب تلك المواضيع تجد عنها في أكاديمية حسوب وموسوعة حسوب فابحث عنها: أفضل المصادر العربية لتعلم تطوير تطبيقات الواجهة الخلفية إذا كنت تبحث عن مصادر عربية لتعلم تطوير الواجهة الخلفية ستجد العديد منها في أكاديمية حسوب التي تعد أكبر منصة عربية لتعليم البرمجة فهي توفر عدة دورات تدريبية لتطوير التطبيقات منها: دورة تطوير التطبيقات باستخدام لغة JavaScript دورة تطوير تطبيقات الويب باستخدام لغة PHP دورة تطوير التطبيقات باستخدام لغة Python دورة تطوير تطبيقات الويب باستخدام لغة Ruby تتميز كل دورة من هذه الدورات بكونها معدة بعناية من نخبة من المبرمجين في المجال وتتضمن العديد من المسارات التي تبدأ معك من أساسيات اللغة وتعلمك أهم أطر عملها وتنتهي بك في تطوير تطبيقات عملية احترافية تؤهلك للدخول في سوق العمل كما أنك تحصل على متابعة دورية من قبل فريق من المدربين الذين يجيبون على كافة تساؤلاتك بخصوص ما تتعلمه ويوجهونك خلال تطبيق المشاريع، وستحصل في نهاية كل دورة على شهادة معتمدة من أكاديمية حسوب تؤهلك لدخول سوق العمل. كما توفر أكاديمية حسوب مئات المقالات والسلاسل التعلميمة توفر شروحات مميزة لكافة اللغات والأطر والتقنيات التي ذكرناها في سياق مقالنا مثل مقال المدخل الشامل لتعلم تطوير الويب وبرمجة المواقع الذي يرشدك لكل ما يخص تطوير الويب بكافة أقسامه وتخصصاته وغيرها الكثير من المقالات المتقدمة لذا احرص على متابعة دروس الأكاديمية أولًا بأول. وإذا كنت تفضل الدراسة من الكتب لما توفره من تسلسل منهجي في طرح المعلومات ستجد في قسم الكتب في أكاديمية حسوب العديد من الكتب القيمة المتخصصة بشرح لغات البرمجة وقواعد البيانات وتقنيات تطوير الويب وغيرها من العناوين المهمة والمفيدة لأي مطور. أسئلة شائعة حول تطوير الواجهات الخلفية في بداية مشوارك في تطوير الواجهة الخلفية قد تدور بذهنك عدة تساؤلات حول هذا التخصص ومدى صعوبته وملائمته لك وإليك أبرز هذه التساؤلات والإجابات عليها 1. هل يمكن أن أتعلم تطوير الواجهة الخلفية بنفسي؟ نعم بكل تأكيد فتطوير الويب عمومًا وتطوير الواجهة الخلفية خصوصًا لا تتطلب منك الحصول على شهادة جامعية لتمارسها بل يمكنك تعلمها ذاتيًا واكتساب كافة المهارات اللازمة لتطوير مواقع وتطبيقات الويب بنفسك ولحسن الحظ موارد التعلم كثيرة ومتاحة ويمكنك الاعتماد عليها للتعلم الذاتي. وتذكر أن مفتاح نجاحك كمطور واجهة خلفية ليس مرتبطًا بالشهادات بقدر ما يعتمد على اكتساب المهارات المناسبة التي تمكنك من دخول سوق العمل وتطوير مشاريع تعكس تمكنك من هذه التقنيات والمهارات وتعزز فرصتك في العثور على العمل الذي يحقق طموحك. 2. هل وظيفة تطوير الواجهات الخلفية مناسبة لي؟ بالرغم من أن المهارات التقنية هي أول ما ينظر له عند توظيف مطور واجهات خلفية لكن هذا ليس كل شيء فكي تصبح مطور واجهة خلفية محترف يجب أن تمتلك بعض الصفات الأخرى مثل المهارات التحليلية والقدرة على حل المشكلات إلى جانب مهارات التواصل لاسيما عندما تعمل ضمن فريق عمل يضم عدة مطورين، كما يجب أن تمتلك حس الفضول والرغبة في تعلم كل جيد فكل يوم هناك إصدارات وأدوات وإضافات جديدة وعليك بذل الوقت والجهد لتعلمها، لذا تأكد من أنك شخص يمتلك هذه الصفات ولا تركز فقط على الجوانب الفنية وقرر بناء على ذلك إن كان العمل كمطور واجهات خلفية يناسبك أم لا. 3. هل يجب علي تعلم كل التقنيات الواردة في هذا المقال لأبدأ العمل كمطور واجهة خلفية؟ لحسن الحظ لا يلزمك تعلم كل هذه التقنيات لتبدأ تطوير الويب الخلفي فإذا امتلكت المهارات الأساسية بإحدى لغات الواجهة الخلفية وتعلمت إطار عمل واحد على الأقل وأتيحت لك فرصة عمل على مستوى المبتدئين لا تتردد واقبلها فورًا، سيطلب منك حينها البدء بمشاريع عملية صغيرة تناسب مهاراتك وبعدها ستتاح لك الفرصة لتوسيع مجموعة المهارات الخاصة بك وتعلم لغات وأدوات برمجة جديدة ومن جديد أؤكد لك بأن الخبرة العملية هي أكثر ما يساعدك على التطور. 4. ما هو الوقت اللازم لتعلم تطوير الواجهات الخلفية Backend؟ لا شك أن تعلم تطوير الواجهة الخلفية يتطلب معرفة ترسانة مختلفة من لغات البرمجة ومهاراتها وهذا يتطلب بلا شك بعض الوقت والالتزام لكن رغم ذلك تعتمد المدة اللازمة لتعلم تطوير الواجهة الخلفية على عدة عوامل أهمها مدى قابليتك وسرعتك في التعلم وكفاءة المصادر التي تتعلم منها ومدى التزامك بخطة منهجية وعدد الساعات التي تقضيهًا يوميًا في للتعلم. ولا شك أن المعرفة المسبقة بعلوم الحاسوب وأساسيات الشبكات وكنت على دراية بإحدى لغات البرمجة وكتابة الشيفرات البرمجية فهذا يختصر عليك زمن التعلم بشكل كبير، ويمكن القول أن فترة التعلم تتراوح وسطيًا بين 6 أشهر إلى عام لتصبح جاهزًا لدخول سوق العمل في حال اتبعت كل الخطوات والنصائح التي أوردناها في سياق المقال بعدها يمكن أن تتابع تطوير نفسك بشكل تدريجي وتصبح خبيرًا في المجال. 5. ما مدى صعوبة تعلم تطوير الواجهة الخلفية للويب؟ ستشعر بالطبع ببعض الصعوبات عند تعلم تطوير الواجهات الخلفية لأول مرة وستواجه الكثير من التحديات والعثرات خلال رحلة التعلم، لكن بقليل من المثابرة والاستعانة بمصادر تعلم مناسبة وفعالة يمكنك تجاوزها بسهولة وتذكر أنك تستثمر في مجال وظيفي مربح ومضمون لذا يستحق الأمر بذل الجهد. 6. أيهما أصعب تطوير الواجهة الخلفية أم الأمامية؟ برأيي الشخصي يعتمد الجواب على هذا السؤال على طبيعة الشخص وميوله فالبعض يرى أن تطوير الواجهة الخلفية هو الأصعب لكونه يتطلب تعلم تقنيات برمجية أكثر ويستلزم تعلم التعامل مع قواعد البيانات والخوادم والشبكات وضمان أمان التطبيقات كما أنه يتطلب امتلاك عدة مهارات شخصية أهمها التفكير المنطقي والتحليلي التي عليك تطويرها إلى جانب تطوير مهاراتك الفنية لتنجح في سوق العمل. بالمقابل يمكن أن يرى بعض الأشخاص أن تطوير الواجهات الأمامية هو الأصعب لكونه لا يخضع لقواعد ثابتة ويحتاج للاهتمام بالكثير من الجوانب المرئية مثل تجاوب التصميم مع كافة أنواع الأجهزة وأحجام الشاشات وفهم الاختلافات بين المتصفحات واختبار توافق التصاميم عليها ومراعاة تجربة المستخدم ولا ننسى الجانب الإبداعي والذوق في التصميم الإبداعي الذي قد لا يتوفر لدى جميع الأشخاص. ولمساعدتك في هذا الشأن أنصحك بالاطلاع على مقال دليلك الشامل إلى تطوير الواجهات الأمامية لتتعرف على كل ما يخص هذا المجال وتقرر بنفسك أين تبدو الأمور أسهل بالنسبة لك. الخلاصة تعرفنا في مقال اليوم على مجال تطوير الوجهة الخلفية للويب الذي يعنى بتطوير أجزاء تطبيقات ومواقع الويب التي تعمل من جهة الخادم وتعرفنا على أهم الفروقات بين تطوير الواجهة الأمامية الخلفية، وأبرز التقنيات واللغات والأطر المستخدمة في برمجة الواجهة الخلفية وتحقيق وظائف التطبيقات والمواقع الإلكترونية بكفاءة وأهم الخطوات والمصادر التي تساعدك على تعلمها بسهولة وكفاءة. وفي ختام مقالنا جاوبنا على أبرز الأسئلة التي قد تتبادر لذهن أي مبتدئ يرغب بتعلم تطوير الواجهات الخلفية، وفي حال كان لديك سؤال آخر لم نجب عليه في سياق المقال يمكنك تركه في قسم التعليقات أسفل المقال. اقرأ أيضًا المدخل الشامل لتعلم تطوير الويب وبرمجة المواقع برمجة مواقع الويب: دليلك المختصر مدخل إلى تطوير البرمجيات Software Development ما هي صفحات الويب
- 1 تعليق
-
- 1
-
- تطوير الويب
- الواجهة الخلفية
-
(و 1 أكثر)
موسوم في:
-
يتضمن مجال تطوير الويب قسمين أساسين هما تطوير الواجهة الأمامية front-end (فرونت إند) وتطوير الواجهة الخلفية back-end (باك إند) وهما من المجالات الرائدة اليوم فجميع النشاطات التجارية والأشخاص يسعون للتواجد على شبكة الإنترنت ويحتاجون لمطوري ويب لإنشاء مدونات أو مواقع أو تطبيقات أو متاجر إلكترونية خاصة بهم. سنخصص مقال اليوم للحديث عن تطوير الواجهة الأمامية ونوضح كافة المفاهيم المرتبطة وكافة الخطوات والتقنيات التي تحتاجها لتتعلم كي تصبح مطور واجهات محترف فإذا كنت مهتمًا بهذا المجال لكنك لا تملك أدنى فكرة عن كتابة الشيفرات البرمجية أو إنشاء صفحات الويب ولا تعرف من أين تبدأ أنصحك بأن تقرأ المقال للنهاية. ما هو تطوير الواجهة الأمامية Front End Web Development؟ قبل أن نشرح تطوير الواجهة الأمامية front-end تحتاج لأن تعرف مراحل بناء أي موقع إلكتروني، فإنشاء أي موقع أو تطبيق يبدأ بتحديد فكرته وتوثيقها، بعدها ترسل هذه الفكرة إلى مصمم الواجهات الأمامية الذي يرسم واجهات الموقع وصفحاته كلها بمختلف تفاصيلها وحالتها، حيث تُراجع هذه الواجهات ثم ترسل إلى مطور الواجهات لتكويدها وبرمجتها وهنا تقسم العملية إلى برمجة واجهات أمامية وخلفية وتبرمج كل واجهة وتتفاعل الواجهتان مع بعضهما للحصول على المواقع المتكامل. فمطور الواجهة الأمامية front end web developer أو ما يعرف بمطور واجهات المستخدم user interface developer هو المبرمج المسؤول عن إنشاء كافة الأجزاء المرئية التي يراها المستخدم ويتفاعل معها عند زيارة مواقع وتطبيقات الويب وبرمجة كافة الواجهات ومكوناتها من أزرار وقوائم ونصوص ورسومات وصور ونماذج وغيرها وتحديد كيف سيبدو كل جزء من موقع الويب وكيف سيتفاعل المستخدم معه. الفرق بين تطوير الواجهة الأمامية front-end وتطوير الواجهة الخلفية back-end والتطوير الكامل Fullstack من الضروري أن تفهم أبرز الفروقات بين تطوير الواجهة الأمامية وتطوير الواجهة الخلفية والتطوير الكامل والتي تعكس في واقع الأمر تخصصات تطوير الويب أو بمعنى آخر الدور الذي يساهم به مطور الويب عند بناء المواقع والتطبيقات والتقنيات التي يستخدمها لأداء عمله، كما أنها تعبر عن مكان تشغيل الشيفرات البرمجية لهذه المواقع والتطبيقات. بدايةً يجب أن تعرف أن عرض موقع الويب على جهازك يتم دومًا في لغة HTML وهي لغة توصيفية يستخدمها مطورو الويب لإنشاء وعرض الصفحات، هناك عدة تقنيات يمكنك إنشاء المواقع من خلالها لكن مهما كانت التقنية المستخدمة فإن عرض الموقع لديك في نهاية المطاف سيكون بلغة HTML. الآن يمكن أن تحدث عملية عرض ملفات المواقع مباشرة على جهازك كما في حال المواقع البسيطة ذات المحتوى الثابت فهي تخزن على خادم الويب بالأساس بشكل ملفات HTML وترسل لك هذه الملفات مباشرة عند طلبها وتعرض لك كما هي على متصفحك. من ناحية أخرى قد تتطلب عملية عرض المواقع بعض المعالجة المسبقة التي تحدث على جانب خادم الويب أو يسمى الخادم البعيد مثل مواقع الويب الديناميكية التي لا تعرض نفس المحتوى لجميع المستخدمين وتتغير بناء على إدخالات المستخدم، فعندما ترسل طلبًا لعرض صفحة ما من موقع ديناميكي يقوم الخادم بمعالجة طلبك هذا وبعد الانتهاء ويجلب لك البيانات المطلوبة والعرض الأخير على جهازك يكون بشيفرة HTML. كل ما يتعلق بأمور عرض الموقع من جانب متصفح الويب أو يسمى طرف العميل client side يندرج تحت مجال تطوير الواجهة الأمامية للموقع، وكل ما يتعلق بأمور معالجة الموقع من طرف خادم الويب من معالجة البيانات وتخزينها وحفظها وإجراء عمليات عليها وغيرها يندرج تحت مجال تطوير الوجهة الخلفية للموقع ولكل منهما تقنياته وأدواته، على سبيل المثال عندما تسجل في موقع يطلب تاريخ ميلادك، تراه يعرضها لك أحيانًا بشكل عمر أي عدد وليس تاريخ، هذه المعالجة تُرسل عادة من طرف الخادم. ليس لزامًا عليك كمطور ويب تعلم تطوير الواجهة الأمامية أو الخلفية معًا بل يمكنك التخصص في إحداهما فقط، فإذا كنت تحب تنفيذ الجوانب المرئية لواجهات المستخدم وجعلها تعمل وفق التصميم المقترح سيناسبك تطوير الواجهة الأمامية أكثر، وإذا كنت تفضل حل المشاكل المنطقية والتعامل مع قواعد البيانات وواجهات برمجة التطبيقات والخوادم والخدمات السحابية فإن تطوير الواجهة الخلفية يناسبك. أما إذا كنت متحمسًا للقيام بكل ما سبق وكانت لديك القدرة لتعلم كافة التقنيات والمهارات اللازمة لتطوير الواجهة الأمامية وتطوير الواجهة الخلفية والقيام بالأمرين معًا عندها سيطلق عليك اسم المطور الكامل fullstack developer وستفتح أمامك الكثير من الفرص المجزية. وإذا كنت مهتمًا بمعرفة مزيد من التفاصيل حول مجالات تطوير الويب أنصح بمطالعة مقال المدخل الشامل لتعلم تطوير الويب وبرمجة المواقع ومقال دليلك الشامل إلى تطوير الواجهة الخلفية Backend. أهمية تطوير الواجهة الأمامية في سوق العمل إذا كنت مهتمًا بتطوير الويب فدعني أخبرك أن تبدأ به دون تردد فهو واحد من أكثر مجالات العمل نموًا مقارنة بباقي الوظائف فبحسب استبيان عام 2022 لموقع ستاك أوفر فلو الشهير الذي يضم آلاف خبراء البرمجة حول العالم فإن 25.96% من المشاركين في الاستبيان وعددهم 61,302 متخصصون في تطوير الواجهة الأمامية front-end، ويحتل هذا المجال المرتبة الثالثة بين أنواع المطورين بعد تطوير الواجهة الخلفية back-end والتطوير الكامل full-stack وهذا إن دلَّ على شيء فإنما يدل على مدى أهمية هذا المجال والطلب المرتفع عليه. أضف إلى ذلك فإن رواتب مطوري الواجهة الأمامية مرتفعة ومجزية ورغم كونها تتفاوت وتختلف حسب نوع الشركة ومقرها والمهارات المطلوبة للوظيفة ومستوى الخبرة إلا أن اكتسابك لمهارات عالية واحترافك لتطوير الواجهة الأمامية سيضمن لك الحصول على رواتب مرتفعة جدًا فمعظم جهات العمل تبحث عن مطور واجهة أمامية موهوب يمكنه إنشاء مواقع بتصاميم فريدة وبتجربة محسنة من شأنها زيادة رضا العملاء وجعل المواقع تتفوق على منافسيها. الجدير بالذكر أن أصعب جزء في مجال تطوير الواجهة الأمامية هو أنه متجدد باستمرار لذا يحتاج المطور للاطلاع بصورة دائمة على أحدث التقنيات في تطوير الويب ليتمكن من الاحتفاظ بالصدارة في سوق العمل لكنه مجال مجزٍ ويستحق الجهد. ما هي مهام مطور الواجهة الأمامية؟ مطور الواجهات الأمامية هو المسؤول بشكل عام عن إنشاء أجزاء المواقع والتطبيقات التي تعمل من جانب العميل (أو المتصفح)، وهذه المهمة تتضمن القيام بالعديد من المهام والتي تشمل: كتابة شيفرات HTML و CSS وجافا سكريبت لتنفيذ تصميم الموقع التي تكون عادة بشكل صور مصممة من قبل مصمم الواجهات الأمامية المسؤول عن تصميم واجهة المستخدم وتجربة المستخدم UI / UX بواسطة برامج متخصصة مثل فيجما Figma أو Sketch أو فوتوشوب. التواصل مع مطور الواجهة الخلفية المسؤول عن تحقيق وظائف الموقع والتأكد من توافق الواجهة الأمامية مع الواجهة الخلفية للموقع. تحسين أداء موقع الويب والتأكد من سرعة تحميله وتوفر تجربة مستخدم سهلة ومحسنة. التأكد من أن الموقع متوافق مع كافة متصفحات الويب ويعمل بالشكل الصحيح ومعالجة أي مشاكل توافق إن وجدت. التأكد من كون الموقع متجاوب ومتكيف مع كافة أحجام الشاشات بما في ذلك شاشات الهواتف الجوالة والأجهزة اللوحية وأجهزة الحاسوب. أهم أدوات تطوير الواجهة الأمامية إذا قررت التخصص في تطوير الواجهات الأمامية للويب ستجد الكثير من الخيارات المتاحة، فاللغات الثلاث الأساسية لأي مطور واجهة أمامية هي HTML و CSS وجافا سكريبت كما يمكنه إلى جانب ذلك استخدام العديد من اللغات وأطر العمل والمكتبات الأخرى الكثيرة التي تسهل عمله في تطوير الواجهات وفي الفقرات التالية سنسلط الضوء على أبرز هذه الأدوات. أهم لغات برمجة الواجهة الأمامية HTML CSS جافا سكريبت JavaScript تايب سكريبت TypeScript لنتناول بتفصيل أكثر كل لغة من هذه اللغات ودورها في تطوير الواجهات الأمامية للمواقع والتطبيقات. لغة HTML لغة HTML هي اختصار لعبارة HyperText Markup Language أي لغة ترميز النص التشعبي وهي اللغة الأساسية لتطوير الواجهة الأمامية للمواقع والتطبيقات وهي لغة وصفية أو لغة ترميز تصف البنية العامة لصفحات الويب ومحتوياتها من نصوص وأزرار وصور وقوائم باستخدام الوسوم وهي علامات موضوعة ضمن قوسي زاوية <> تحدد نوع المحتوى أو هيكليته على سبيل المثال لإنشاء صفحة ويب تتضمن عنوان وصورة ونص نكتب كود HTML التالي: <!DOCTYPE html> <html dir="rtl"> <head> <title>عنوان الصفحة</title> </head> <body> <h1>عنوان الصفحة</h1> <img id="myImage" src="html.png"> <p> HTML هي اختصار لـHyperText Markup Language أي لغة ترميز النص التشعبي وهي الأساسية لتطوير الواجهة الأمامية للمواقع والتطبيقات </p> </body> </html> احفظ الكود أعلاه في ملف نصي باسم index.html وقم بعرضه في متصفح الويب، عندها ستظهر الصفحة بالشكل التالي: للمزيد من المعلومات أنصح بمطالعة مقال تعلم لغة HTML الذي يشرح لك كافة الأساسيات التي تحتاجها للعمل مع هذه اللغة والاطلاع على توثيق HTML الشامل على موسوعة حسوب. لغة CSS لغة CSS هي اختصار لـ Cascading Style Sheets وهي لغة تصميم تستخدم لتحديد تنسيق صفحة الويب واختيار الألوان والخطوط والخلفيات وما إلى ذلك كما أنها تستخدم في جعل مواقع الويب متجاوبة مع مختلف الشاشات من خلال كتابة شيفرات تغير تنسيق وتخطيط العناصر بحسب أبعاد الشاشة. تستخدم لغة CSS قواعد تنسيق تستهدف عناصر HTML التي نريد تصميمها على سبيل المثال سنكتب التعليمات التالية لتنسيق صفحة الويب التي أنشأناها باستخدام HTML نكتب شيفرات CSS التالية ضمن الوسم <head>: <style> body { font-family: 'Cairo', sans-serif; background-color: #f2f2f2; margin: 0; padding: 0; } h1 { font-size: 36px; color: #333; text-align: center; margin: 50px 0; } img { display: block; margin: 0 auto; max-width: 100%; height: auto; } p { font-size: 18px; color: #666; text-align: center; margin: 50px; line-height: 1.5; } </style> تظهر الصفحة بعد إضافة التنسيقات كما يلي: وللمزيد من المعلومات يمكنك مطالعة سلسلة دروس CSS على أكاديمية حسوب إلى جانب توثيق CSS الشامل على موسوعة حسوب. لغة جافا سكريبت JavaScript بعد أن تقوم بتخطيط عناصر الواجهة الأمامية باستخدام HTML وتنسقها باستخدام CSS قد تحتاج إلى إضافة بعض التفاعلات إلى صفحاتك وهنا يأتي دور لغة جافا سكريبت JavaScript التي تعد واحدة من أشهر لغات البرمجة وأكثرها استخدامًا فهي تمكنك من تطوير كل من الواجهة الأمامية والخلفية. قد يكون تعلم جافا سكريبت هو الخطوة الأصعب لك كمطور واجهة أمامية لا سيما إن لم تكن تملك خبرة سابقة في البرمجة لكن بمجرد تعلمها ستتمكن من نقل الموقع إلى مستوى جديد وإضافة التأثيرات الديناميكية لصفحاته والاستجابة لتفاعل المستخدمين مع عناصره بدلًا من جعله يعرض معلومات ثابتة فقط. على سبيل المثال يمكنك كتابة شيفرات جافا سكريبت لعرض قائمة منسدلة أو إظهار رسالة منبثقة عند النقر فوق زر ما على الصفحة، أو إرسال طلب للتحقق من اسم المستخدم وكلمة المرور بعد النقر فوق زر تسجيل الدخول أو أي شكل من أشكال التفاعل مع الصفحة من طرف العميل. لنفرض أنك تحتاج لتكبير حجم صور الموقع قليلًا عند مرور مؤشر الفأرة فوقها، لن تتمكن من هذا إذا لم تكن تعرف جافا سكريبت وتدمجها مع HTML و CSS بدايةً عليك إضافة أكواد CSS التالية بعد الأكواد التي كتبتها في الخطوة السابقة: .zoom { transition: transform .2s; /* Add any other styles you want */ } .zoom:hover { transform: scale(1.5); /* Change the scale value to adjust the level of zoom */ } وبعدها عليك أن تضيف أكواد جافا سكريبت التالية قبل الوسم </body> ضمن كود HTML: const image = document.getElementById("myImage"); image.addEventListener("mouseover", function() { image.classList.add("zoom"); }); image.addEventListener("mouseout", function() { image.classList.remove("zoom"); }); تستمع شفرة جافا سكريبت هذه إلى حدث مرور مؤشر الفأرة فوق الصورة وتضيف تنسيق التكبير zoom إليه عند وقوع هذا الحدث. كما أنها تستمع إلى حدث خروج مؤشر الفأرة من عنصر الصورة وتزيل تنسيق التكبير منه عند وقوع هذا الحدث، وعند عرض الصفحة في المتصفح نحصل على التأثير التالي: للمزيد من التفاصيل أنصح بمطالعة مقال تعلم جافا سكريبت من الصفر حتى الاحتراف، كما توفر موسوعة حسوب توثيق لغة جافا سكريبت باللغة العربية يمكنك من خلالها تعلم كافة ما يتعلق بهذه اللغة. لغة TypeScript تعد لغة TypeScript لغة برمجة مفتوحة المصدر طورتها مايكروسوفت عام 2012 لتوفر ميزات إضافية تساعد على تطوير تطبيقات جافا سكريبت فهي تجعل تعليمات جافا سكريبت مفهومة بشكل أكبر وتوفر إمكانية تحديد أنواع المتغيرات كي تقلل من أخطاء الكود، وقد تزايدت شعبيتها بشكل كبير في الآونة الأخيرة لما توفره من ميزات لتحسين جودة التطبيقات وتسريع عملية التطوير . يمكنك مطالعة المزيد من المعلومات حول هذه اللغة وإمكانياتها من خلال مجموعة دروس TypeScript المتوفرة على أكاديمية حسوب أهم أطر عمل تطوير الواجهة الأمامية ظهرت أطر العمل frameworks والمكتبات البرمجية لتسهيل عمل المطور وتسريع عمله، لذا ستحتاج لاستخدامها في سوق العمل بدلًا من كتابة كل شيء بيدك من الصفر، وأطر عمل الواجهات الأمامية كثيرة ومن أبرزها: بوتستراب Bootstrap رياكت React أنغولار Angular فيو Vue جي كويري jQuery دعنا نلقي نظرة على كل تقنية منها ونشرح بمزيد من التفصيل دورها وأهميتها في تطوير الواجهة الأمامية. بوتستراب Bootstrap بوتستراب هو إطار ويب مجاني مفتوح المصدر مخصص للواجهة الأمامية فهو يستخدم لتصميم مواقع وتطبيقات ويب متجاوبة مع كافة أحجام الشاشات وذات مظهر احترافي بسرعة وسهولة فهو يحتوي على قوالب تصميم ومكونات جاهزة مكتوبة بلغة HTML ولغة CSS كما يوفر بالإضافة لذلك ملحقات تصميم مكتوبة بلغة جافا سكريبت. للاطلاع على المزيد من المعلومات يمكنك متابعة المقالات الدروس حول إطار عمل بوتستراب على أكاديمية حسوب إضافة لتوثيق بوتستراب الشامل على موسوعة حسوب. رياكت React رياكت React هي مكتبة جافا سكريبت مفتوحة المصدر طورتها شركة فيسبوك عام 2013 وهي تعد اليوم واحدة من أشهر مكتبات تطوير الواجهة الأمامية التي يمكنك من خلالها إنشاء مكونات قابلة لإعادة الاستخدام وتطوير واجهات مستخدم متجاوبة بسرعة وسهولة. يمكنك مطالعة المزيد حول هذه المكتبة وتعلم طريقة بناء واجهات المواقع والتطبيقات باستخدامها من خلال الدروس والمقالات الاحترافية حول React على أكاديمية حسوب وأيضًا توثيق React على موسوعة حسوب. أنغولار Angular أنغولار Angular هو إطار عمل مفتوح المصدر يعتمد على لغة TypeScript أطلقته شركة جوجل وهو يتميز بقدرته على تطوير تطبيقات ويب متطورة وضخمة وإدارتها بسهولة كبيرة فهو يوفر الكثير من الميزات التي تساعد مطوري الواجهة الأمامية مثل إدارة حالة التطبيق والتحقق من الصحة. كما يمكنك مطالعة المزيد من الدروس والمقالات الاحترافية حول Angular على أكاديمية حسوب لتتعرف على طريقة استخدامها في تطوير مواقع ويب احترافية. فيو Vue فيو Vue هو إطار عمل جافا سكريبت مفتوح المصدر طوره Evan You المبرمج في جوجل عام 2014 لتطوير واجهات المستخدم وتطبيقات الصفحة الواحدة وهو اليوم واحد من أكثر أطر عمل الواجهة الأمامية شيوعًا واستخدامًا. ما يميز إطار فيو Vue أنه مرن وخفيف الوزن وسهل الاستخدام فقد أزال كل المكونات الإضافية والمفاهيم غير الضرورية التي تأتي مع أطر عمل الواجهة الأمامية الأخرى مثل أنغولار Angular ورياكت React. وللمزيد من التفاصيل أنصح بمطالعة مقال مقارنة بين أطر الواجهات الأمامية: Angular و React و Vue لمعرفة الإطار الأنسب لمتطلباتك، كما أنصح بمتابعة الدروس والمقالات حول Vue التي توفرها أكاديمية حسوب بشكل دوري لتعلم المزيد حول استخدامات هذا الإطار. جي كويري jQuery جي كويري jQuery هي مكتبة مبنية بالاعتماد على لغة جافا سكريبت وهي توفر لمطوري الواجهة الأمامية الكثير من القوة والمرونة وتتضمن الكثير من الميزات التي تجعل كتابة شيفرات جافا سكريبت أبسط وأكثر اختصارًا. لمعرفة المزيد حول طريقة استخدام مكتبة jQuery عند تطوير مواقع الويب أنصح بمطالعات مجموعة المقالات والدروس حول jQuery المتوفرة على أكاديمية حسوب، كما أنصح بمطالعة توثيق jQuery على موسوعة حسوب. تقنيات وأدوات مهمة لتطوير الواجهة الأمامية إضافة لما سبق، يحتاج أي مطور واجهة أمامية لقائمة طويلة من المعارف والمهارات والأدوات الإضافية التي تعزز أداءه وتساعده في تطوير واجهات المستخدم وتكويدها بسرعة واحترافية، وإليك قائمة بأبرز هذه الأدوات نذكر: شجرة DOM والتعامل معها. معرفة أساسية بالشبكات وشبكة الإنترنت وأشهر برتوكولات التواصل مثل HTTP. لمحة عن قواعد التصميم وأساسيات تصميم واجهات المستخدم وتجربة المستخدم UX/UI. التصميم المتجاوب responsive design مع كافة أحجام الشاشات. التوافق مع المتصفحات Cross-browser. واجهة برمجة التطبيقات API. لمحة عن Node.js وأنظمة إدارة الحزم تحديدًا npm. نظام التحكم في الإصدارات git. شجرة DOM من الضروري أن يعرف أي مطور واجهة أمامية مهارات التعامل مع نموذج كائن المستند Document Object Model أو اختصارًا DOM أو شجرة DOM ومعالجته عبر لغة جافا سكريبت، و DOM هو مجموعة من المواصفات التي تمثل مستند الويب بشكل كائن وتعد أحد الطرق الأساسية في بناء مواقع تفاعلية حيث أنها تنشئ واجهة برمجة تطبيقات API تسمح للغات البرمجة مثل جافا سكريبت بالوصول لكافة عناصر صفحات الويب ومعالجتها والتحكم بها. ستساعدك معالجة DOM في تحديث بيانات الصفحة أو تغيير تخطيطها دون إعادة الحاجة لإعادة تحميلها على سبيل المثال يمكنك من خلال DOM إضافة عناصر HTML للصفحة أو إزالتها أو تعديل تنسيقات CSS لها عند وقوع حدث ما أو عند إعادة تحميل صفحة الويب. معرفة أساسية بالشبكات يحتاج مطور الواجهة الأمامية لامتلاك معلومات أساسية حول طريقة عمل الويب والشبكات الحاسوبية وشبكة الإنترنت ومفهوم العميل والخادم وكيفية التفاعل بينهما وبروتوكولات الاتصال عبر الويب مثل HTTP و HTTPS و SSL ومفهوم خدمة اسم المجال DNS فهذه المعرفة تمكنه من عرض واستدعاء المحتوى من الشبكة والاتصال مع الخادم بشكل آمن وتوفير تجربة مستخدم أفضل. للاطلاع على مزيد من المعلومات يمكنك مطالعة سلسلة المقالات والدروس حول الشبكات على أكاديمية حسوب. قواعد التصميم وأساسيات UX/UI ذكرنا سابقًا أن مطور الواجهة الأمامية قد يكون مسؤولًا عن تصميم موقع ويب من الصفر أو قد يكون مسؤولًا عن تحويل التصاميم الجاهزة إلى شيفرات برمجية، لكن في كلتا الحالتين أجد أنه من الضروري لأي مطور واجهة أمامية أن يعرف أفضل النصائح والقواعد لتصميم واجهة المستخدم والمبادئ والقواعد الأساسية في تصميم تجربة المستخدم UX وتصميم واجهة المستخدم UI فهذا من شأنه أن يساعده على فهم الواجهات وكيفية تفاعل المستخدمين معها بشكل أفضل وكيفية إنشاء واجهات أكثر جاذبية وسهولة في الاستخدام وبالتالي سيتمكن من كتابة شيفرات الواجهة الأمامية بشكل أفضل ويضمن أنها مطابق للقواعد التصميمة الصحيحة. التصميم المتجاوب مع كافة أحجام الشاشات التصميم المتجاوب Responsive Design هو تصميم يقوم بتغيير حجم عناصر صفحات الموقع أو إخفائها أو تصغيرها أو تكبيرها ليضمن ظهورها بطريقة واضحة وسهلة الاستخدام مهما كان نوع الجهاز المستخدم لعرضها. يحتاج مطور الواجهة الأمامية لمعرفة أساسيات تصميم الويب المتجاوب Responsive Web Design وطرق كتابة استعلامات الوسائط Media Queries في CSS بشكل صحيح كي يضمن ظهور المواقع بكفاءة على جميع أنواع وأحجام الأجهزة التي يستعملهما المستخدمون سواء الحواسيب ذات الشاشات الكبيرة أو الهواتف المحمولة ذات الشاشات الصغيرة. التوافق مع المتصفحات Cross-browser أحد المهارات الضرورية التي يجب على مطور الواجهة الأمامية تعلمها هو التأكد من أن الواجهات التي يبرمجها متوافقة مع مختلف المتصفحات وتظهر بشكل سليم ومتسق على المتصفحات الشهيرة مثل كروم وفايرفوكس وسفاري وEdge وOpera ويتعلم كيف يجري اختبارات التوافق مع المتصفحات cross-browser testing ويعالج أي مشكلات تواجهه في التوافق. يمكنك الاستعانة ببعض الأدوات والتقنيات المساعدة في اختبار توافق المتصفح Cross-browser مثل Markup Validation Service و CrossBrowserTesting و LambdaTest …إلخ. لكن تجدر الإشارة بأن أطر عمل الواجهات الأمامية مثل رياكت React وأنجولار Angular يمكنها أن تقوم بهذه المهمة عنك ولن تجعلك تكترث لها، يكفي أن تحدد لها أي نوع متصفح تريد أن نستهدف وهي تتولى الأمر لأنها تعالج دومًا الشيفرة التي تكتبها. استدعاء واجهة برمجة التطبيقات واجهات برمجة التطبيقات API هي صلة الوصل بين تطبيقات الواجهة الأمامية وبين النظم والوجهات الخلفية وبالرغم من أنك لا تحتاج كمطور واجهة أمامية لمعرفة كيفية كتابة واجهات برمجة التطبيقات لكونها مهمة مطور الواجهة الخلفية لكنك تحتاج لمعرفة طريقة الاتصال بهذه الواجهات وجلب البيانات منها وعرضها بشكل مناسب ومعرفة التقنيات المرتبطة بها مثل RESTful ومفهوم JSON. باختصار، يجري التواصل بين الواجهة الأمامية والواجهة الخلفية عبر واجهة برمجة التطبيقات وعادة ما ترسل البيانات من الواجهة الخلفية إلى الواجهة الأمامية بصيغة JSON لذا من الضروري معرفة هذه الصيغة، ويمكنك الرجوع إلى مقال تعلم JSON. تعلم Node.js وأنظمة إدارة الحزم يحتاج مطور الواجهة الأمامية إلى تعلم أحد أدوات إدارة الحزم Package Manager التي تجعل عملية تطوير الواجهة الأمامية أسرع وأسهل، فأدوات إدارة الحزم هي برمجيات تسمح لك بتثبيت الحزم المطلوبة للتطوير وإعدادها وتحديثها وإدارة تبعياتها وضمان عدم تعارضها بشكل تلقائي بدلًا من القيام بذلك بشكل يدوي ومن أشهرها npm و Yarn. وعادة يستعمل مطور الواجهات الأمامية مكتبة Node.js التي تأتي مع نظام إدارة الحزم الشهير npm والذي سيستعمله في تنزيل حزم المشروع وإدارتها ومكتبة Node.js هي أول أداة سيثبتها المطور على جهازه فبدونها لن يعمل مع لغة جافاسكريبت على الإطلاق، لذا يجب أن يتعرف عليها وعلى مدير الحزم npm. وقد شرحنا في مقال أساسيات إدارة الحزم في تطوير الويب من طرف العميل كل ما يتعلق باستخدام مدير الحزم وكيفية استخدامه في إدارة مشاريع الواجهة الأمامية. نظام التحكم في الإصدارات git يساعد نظام التحكم في الإصدار وأشهرها Git مطور الواجهة الأمامية على تتبع التغييرات التي يجريها على المواقع ويمكنه من العودة إلى إصدار كود سابق بكل سهولة إذا حدث خطأ ما في الكود كما يفيده في حال العمل على نفس المشروع مع فريق تطوير. تتوفر في أكاديمية حسوب مجموعة غنية ومنوعة من المقالات والدروس حول Git التي تساعدك في تعلم كافة المهارات اللازمة للتعامل مع نظام التحكم بالإصدارات Git. كانت هذه التقنيات جزءًا يسيرًا من التقنيات والأدوات التي على مطور الواجهة الأمامية معرفتها، وفي الفقرة التالية سنوضح المزيد من هذه التقنيات ونضع لك خارطة طريق منظمة تساعدك في تعلم تعلم تطوير الواجهة الأمامية. خارطة طريق تعلم تطوير الواجهة الأمامية إليك خارطة طريق لتعلم مجال تطوير الواجهات الأمامية والذي يعرض بوضوح طريق مطور الواجهات الأمامية بالكامل بدءًا من المرحلة المبتدئة وحتى المتقدمة وأغلب تلك المواضيع تجد عنها في أكاديمية حسوب وموسوعة حسوب: أهم مصادر تعلم تطوير الواجهة الأمامية إذا كنت مبتدئًا ولا تملك أي خبرة مسبقة وتبحث عن أقصر طريقة لتعلم تطوير الواجهة الأمامية أنصحك بالاطلاع على دروة تطوير واجهات المستخدم التي توفرها أكاديمية حسوب فهي دورة شاملة ومنظمة تزيد على 60 ساعة فيديو تدريبية ومن مسارات متعددة تبدأ معك من أساسيات تطوير واجهات المستخدم التي تشرح لك كل المفاهيم واللغات الأساسية وأطر ومكتبات العمل وتنتهي بك ببناء مشاريع عملية متقدمة ترسخ كل هذه الأساسيات وتساعدك في بناء معرض أعمالك. لن تكون وحدك خلال هذه الدورة بل سيكون معك فريق من المدربين لمساعدتك وإجابتك على أي تساؤل أو مشكلة تواجهك في رحلة التعلم، وفي نهاية الدورة ستحصل على شهادة معتمدة من أكاديمية حسوب تعزز سيرتك الذاتية. إضافة إلى ذلك توفر أكاديمية حسوب الكثير من مصادر التعلم المجانية باللغة العربية من دروس ومقالات وسلاسل تعلمية حول تطوير الويب تتعلم من خلالها كافة تقنيات ولغات برمجة الواجهات الأمامية وأطر العمل الشهيرة التي أوردناها في سياق المقال. وإن كنت تفضل الدراسة من الكتب بسبب شموليتها وتسلسلها في الشرح فإن الأكاديمية توفر لك مجموعة من الكتب القيمة التي تهم أي مطور واجهة أمامية من بينها: كتاب فهم أعمق لتقنيات HTML5 كتاب ملاحظات للعاملين في CSS كتاب البرمجة بلغة جافا سكريبت كتاب تصميم تجربة المستخدم سلسلة تطوير الويب وأخيرًا إذا كنت ترغب بمعرفة المزيد من المعلومات حول الواجهات الأمامية وأهم تقنيات برمجتها ومسار تعلمها أنصحك بمشاهدة هذا الفيديو. الخلاصة بهذا تكون وصلت إلى نهاية هذه المقالة الشاملة التي تناولنا فيها كل ما يتعلق بأساسيات تطوير الواجهة الأمامية front-end أو ما يعرف بتطوير واجهة المستخدم وتعرفنا على أهم اللغات وأطر العمل والأدوات التي تحتاجها كمطور واجهة أمامية لتنجز الجزء المرئي من الموقع الذي يتفاعل المستخدمون من خلاله مع التطبيقات والمواقع، كما شرحنا في ختامة أهم خطوات تعلم تطوير الواجهة الأمامية ومصادر تعلمها باللغة العربية. وفي حال كان لديك أي سؤال يتعلق بتطوير الويب وتحديدًا تطوير الواجهات الأمامية للويب فلا تتردد في كتابته في قسم التعليقات أسفل المقال، أو طرحه في قسم الأسئلة والأجوبة في أكاديمية حسوب ليجيبك عليه مبرمجون خبراء. اقرأ أيضًا المدخل الشامل لتعلم تطوير الويب وبرمجة المواقع برمجة مواقع الويب: دليلك المختصر ما الفرق بين تصميم المواقع الإلكترونية وتطوير المواقع الإلكترونية؟ عالم الويب ومعاييره ما هي صفحات الويب؟
-
- 1
-
- واجهة أمامية
- frontend
-
(و 2 أكثر)
موسوم في:
-
بعد أن تعرفنا في المقال السابق على أساسيات لغة CSS والغاية منها، سنتابع في هذا المقال شرح هيكلية CSS. ننصحك قبل المتابعة في القراءة أن تكون على دراية بالمواضيع التالية: أساسيات عمل الحاسوب تثبيت البرمجيات الأساسية للانطلاق في تطوير الويب أساسيات التعامل مع الملفات فكرة عن أساسيات لغة CSS. تطبيق تنسيقات CSS على HTML لنختبر بداية الأساليب الثلاثة لتطبيق CSS على مستند وهي: استخدام ملف تنسيق خارجي والتنسيقات الداخلية والتنسيقات المحلية السطرية. دورة تطوير واجهات المستخدم ابدأ عملك الحر بتطوير واجهات المواقع والمتاجر الإلكترونية فور انتهائك من الدورة اشترك الآن ملفات التنسيق الخارجية تتكون ملفات التنسيق الخارجية من قواعد تنسيق CSS ضمن ملف منفصل له الامتداد css.، وهذه هي الطريقة الأكثر شيوعًا وفائدةً في تطبيق CSS. بإمكانك ربط ملف CSS واحد بأكثر من صفحة ويب وتنسيقها جميعًا باستخدام هذا الملف. تشير إلى ملف CSS خارجي ضمن ملف HTML باستخدام العنصر <link>: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>My CSS experiment</title> <link rel="stylesheet" href="styles.css"> </head> <body> <h1>Hello World!</h1> <p>This is my first CSS example</p> </body> </html> تبدو قواعد تنسيق CSS شبيهة بالشيفرة التالية: h1 { color: blue; background-color: yellow; border: 1px solid black; } p { color: red; } ينبغي أن تدل السمة href للعنصر <link> على موقع ملف تنسيق CSS. لاحظ أنّ ملف التنسيق في المثال السابق موجود في نفس المجلد الذي يحتوي ملف HTML، وبالإمكان طبعًا وضعه في أي مكان آخر مناسب ثم تعديل المسار. إليك بعض الأمثلة: <!--HTML موجود ضمن المجلد الذي يضم ملف style ضمن مجلد يُدعى --> <link rel="stylesheet" href="styles/style.css"> <!--ضمن المجلد الحالي style موجود ضمن مجلد يُدعى general ضمن مجلد يُدعى --> <link rel="stylesheet" href="styles/general/style.css"> <!--style ارتفع مستوى واحد إلى الأعلى ثم ضمن مجلد فرعي يُدعى --> <link rel="stylesheet" href="../styles/style.css"> تنسيقات داخلية تبقى التنسيقات الداخلية ضمن ملف HTML وتُوضع ضمن العنصر <style>. تبدو شيفرة HTML التي تضم تنسيقات داخلية شبيهةً بالتالي: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>My CSS experiment</title> <style> h1 { color: blue; background-color: yellow; border: 1px solid black; } p { color: red; } </style> </head> <body> <h1>Hello World!</h1> <p>This is my first CSS example</p> </body> </html> للتنسيقات الداخلية فوائدها في بعض الحالات، فقد تعمل ربما ضمن منظومة إدارة محتوى تمنعك من تعديل ملفات CSS الخارجية. مع ذلك، تبقى هذه الطريقة أقل فعالية وخاصة في المواقع التي تضم صفحات متعددة. فإن أردت تطبيق تنسيق CSS موحد في جميع الصفحات من خلال التنسيقات الداخلية، عليك كتابتها في كل صفحة، كما أنها ستنعكس سلبًا على فعالية عملية الصيانة أيضًا. إذًا مشكلة هذا الأسلوب الرئيسية هي أنّ أي تغيير بسيط في التنسيق لا بدّ وأن يُنفّذ في كل الصفحات التي تستخدمها. التنسيقات السطرية وهو تنسيق يؤثر على عنصر HTML بمفرده ويُصرّح عنه داخل السمة style. تبدو التنسيقات السطرية أو المحلية شبيهة بالتالي: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>My CSS experiment</title> </head> <body> <h1 style="color: blue;background-color: yellow;border: 1px solid black;">Hello World!</h1> <p style="color:red;">This is my first CSS example</p> </body> </html> تجنّب استخدام هذه الطريقة ما أمكن، فهي النقيض تمامًا لمفهوم أفضل الممارسات. فهي أولًا أقل الطرق فعالية وخاصة عند صيانة تنسيقات CSS. فقد يُضطرك تعديل واحد في التنسيق إلى تطبيقه من جديد عدة مرات في نفس الصفحة. ستمزج ثانيًا بهذا الأسلوب شيفرة CSS مع شيفرة HTML ومحتوى الصفحة مما يزيد من صعوبة قراءة وفهم الشيفرة، فالفصل بين الشيفرة والمحتوى أمر أساسي في تسهيل الصيانة على مشرفي الصفحات. مع ذلك ستصادف بعض الحالات التي تُستخدم فيها هذه الطريقة وخاصة عندما تعمل في بيئات تُقيّد الوصول والتعديل بشدة. فقد يُسمح لك مثلًا بالعمل على جسم ملف HTML فقط أو قد تضطر لاستخدامها في رسائل البريد الإلكتروني المهيكلة باستخدام HTML وذلك لتحقيق توافقية مع أكبر عدد ممكن من عملاء البريد الإلكتروني. تطبيق: تجربة تنسيقات CSS أنشئ مجلدًا جديدًا على حاسوبك وسمِّه ما شئت، ثم انسخ شيفرتي HTML و CSS التاليتين واجعلهما ضمن ملفين جديدين داخل المجلد: الملف index.html: <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>My CSS experiments</title> <link rel="stylesheet" href="styles.css"> </head> <body> <p>Create your test HTML here</p> </body> </html> الملف styles.css: /* Create your test CSS here */ p { color: red; } عندما تقرر ما تنسيقات CSS التي تريد اختبارها، استبدل محتوى العنصر <body> في ملف HTML ببعض العناصر الجديدة لكي تطبق التنسيق عليها، ثم أضف قواعد التنسيق اللازمة ضمن ملف CSS. يمكنك أن تستخدم أيضًا محرر الشيفرة التفاعلي التالي: المحددات تستهدف المحددات عناصر HTML لتطبيق تنسيقات محددة على المحتوى، وقد رأينا في مقال أساسيات استخدام CSS مجموعة متنوعة منها. إن لم تُطبق التنسيقات المطلوبة على المحتوى المحدد، فهذا يعني أنّ المحدد الذي اخترته لا يطابق ما تريده. تبدأ أي قاعدة من قواعد CSS بمحدد أو بقائمة من المحددات لكي تدل المتصفح على العنصر أو العناصر التي يجب أن تُطبق عليها هذه القاعدة. إليك بعض الأمثلة عن محددات صحيحة: h1 a:link .manythings #onething * .box p .box p:first-child h1, h2, .intro حاول أن تُنشئ بعض القواعد مستخدمًا المحددات السابقة. أضف أولًا بعض عناصر HTML التي ترغب في تنسيقها ثم استخدام المحددات السابقة في تطبيق التنسيقات. يمكنك دومًا العودة إلى موسوعة حسوب إن وجدت أنّ بعض المحددات السابقة غير مألوفة. عمق التحديد specificity قد تتعرض لسيناريوهات يستهدف فيها محددان عنصر HTML نفسه. لنتأمل شيفرة CSS التالية مثلًا إذ يجعل المحدد p الفقرات النصية باللون الأزرق، كما يجعل محدد الصنف special. العنصر المستهدف باللون الأحمر: .special { color: red; } p { color: blue; } لنفرض الآن وجود فقرة نصية في ملف HTML تمتلك الصنف special، وكلتا القاعدتين تستهدفان الفقرة النصية! فمن منهما ستُطبق؟ <p class="special">What color am I?</p> للغة CSS قواعد لمعرفة أي المحددات هو الأقوى في حالة معينة أو خلاف. تُدعى هذه القواعد بالتسلسل cascade أو عمق التحديد specificity. ستكون نتيجة النزاع في الشيفرة التالية مثلًا بين محددي العنصر p هي نص باللون الأزرق لأن القاعدة التي تضبط لون النص على الأزرق تأتي في التسلسل بعد القاعدة التي تضبطه على اللون الأحمر، فآخر تنسيق يَستبدل دائمًا التنسيق السابق في حالات التضارب وهذه هي قاعدة التسلسل. p { color: red; } p { color: blue; } لكن بالعودة إلى الشيفرة التي تسبقها وتعرض نزاعًا بين محدد صنف ومحدد عنصر ستكون النتيجة نصًا باللون الأحمر، إذ سينتصر محدد الصنف على الرغم من أنّ محدد العنصر يأتي بعده في التسلسل! إنّ السبب في ذلك أنّ محدد الصنف يُقيَّم بأنه أكثر تخصيصًا من محدد العنصر وبالتالي سيحل محله في حالات النزاع أو التضارب. حاول أن تجرب الأمر بنفسك، أضف بعض عناصر HTML ثم أضف محددي عناصر من الشكل {...} p إلى قواعد التنسيق وراقب النتيجة، ثم حول المحدد الأول إلى محدد صنف special. وراقب النتيجة. قد تبدو قواعد التسلسل والتخصيص معقدة في البداية، لكنها ستغدو أسهل عندما تألف اللغة. أما الآن، فكل ما عليك تذكره هو وجود التخصيص، وأنّ CSS قد لا تطبقه كما تتوقع دائمًا لوجود أشياء أكثر تخصيصًا. كما عليك الانتباه إلى تطبيق أكثر من قاعدة على العنصر نفسه، فهي الخطوة الأولى لإصلاح أخطاء التنازع. الخاصيات وقيمها تعتمد اللغة في أساسها على مكوّنين: الخاصية property: وهي معرّف يمكن للإنسان فهمه ويحدد الميزة التي تريد تنسيقها أو تعديلها مثل font-size وwidth وbackground-color. القيمة value: تأخذ كل خاصية قيمة تشير إلى كيفية تنسيق الخاصية. يشير المثال في الشكل التالي إلى خاصيات تأخذ قيمة واحدة مثل الخاصية color التي تأخذ القيمة blue عندما نُسند قيمة إلى خاصية نحصل على زوج يُدعى تصريح CSS، وتوضع هذه التصريحات ضمن كتل التصريحات. يشير المثال التالي إلى كتلة تصريحات CSS. ترتبط كتل التصريحات مع المحددات لتشكل ما يُدعى مجموعة قواعد. يتضمن المثال في الشكل التالي قاعدتين: الأولى تستهدف العنصر h1 والثانية تستهدف العنصر p. إنّ تحديد قيم لخاصيات CSS هي الطريقة الرئيسية لتحديد تخطيط الصفحات وتنسيقها، إذ يُقرر محرك CSS أية تصريحات ستطبق على كل عنصر في الصفحة، وتذكر أن تصريحات وقيم CSS حساسة لحالة الأحرف، وأن النقطتين المتعامدتين (:) تفصلان بين الخاصية وقيمتها. تطبيق: ابحث عن القيم المختلفة للخاصيات التالية ثم استخدمها في كتابة قواعد لتنسيق عناصر HTML تختارها: font-size width background-color color border تنبيه: إن لم تكن الخاصية معروفة أو لم تكن القيمة مناسبة لخاصية سيتعامل المتصفح مع التصريح على أنه غير صالح، وسيتجاهله محّرك CSS. تنبيه: اتُفق في CSS وغيرها من تقانات ويب أن تكون التهجئة الإنكليزية الأمريكية هي المعيارية في كتابة التصاريح. فكتابة الخاصية "colour" يجب أن تكون على الشكل color، فلن تعمل إن كُتبت colour. الدوال تأخذ بعض القيم شكل دوال بينما تأخذ معظمها قيمًا عددية أو كلمات مفتاحية بسيطة. الدالة ()calac يمكن لهذه الدالة إنجاز بعض الحسابات الرياضية على CSS: <div class="outer"><div class="box">The inner box is 90% - 30px.</div></div> .outer { border: 5px solid black; } .box { padding: 10px; width: calc(90% - 30px); background-color: rebeccapurple; color: white; } سيعرض المتصفح النتيجة التالية: تتكون الدالة من اسم الدالة وقوسين يضمان قيم الدالة. لاحظ كيف تعرف الدالة ()calc في مثالنا السابق عرض الصندوق ليكون 90% من عرض الكتلة التي تضمه ناقصًا 30 بكسل. ولا يمكن بالطبع حساب هذه القيمة مسبقًا ثم وضع النتيجة كقيمة ثابتة مباشرة. دوال التحويل من أمثلة هذه الدوال الدالة rotate: <div class="box"></div> .box { margin: 30px; width: 100px; height: 100px; background-color: rebeccapurple; transform: rotate(0.8turn); } وستكون النتيجة كما يعرضها المتصفح كالتالي: تطبيق: ابحث عن قيم الخاصيات التالية ثم اكتب قواعد CSS باستخدام هذه الخواص وطبقها على عناصر HTML مختلفة: transform background-image، وخاصة القيم المتدرجة gradient. color، وخاصة قيم rgb وrgba وhsl وhsla. القواعد المسبوقة بالمحرف @ تزود هذه القواعد المتصفح بإرشادات حول ما ينبغي على CSS فعله وكيف ستتصرف. بعض "قواعد@" بسيطة وتتكون من تعليمة وقيمة مثل import@ التي تدرج صفحة CSS ضمن أخرى: @import 'styles2.css'; من أكثر القواعد التي قد تراها هي media@ التي تستخدم لإنشاء استعلام وسائط متعددة media query تستخدم شروطًا منطقية لتطبيق تنسيق CSS محدد. تُحدد CSS في المثال التالي لون خلفية زهري للعنصر <body> لكن استعلام الوسائط المتعددة سيجعل اللون أزرق إن كانت نافذة العرض أوسع من 30em: body { background-color: pink; } @media (min-width: 30em) { body { background-color: blue; } } تطبيق: حاول إضافة استعلام وسائط لتغيير التنسيق اعتمادًا على اتساع نافذة العرض ثم غيّر اتساع نافذة المتصفح وراقب ما يحدث! الخاصيات المختصرة تُدعى بعض الخاصيات مثل font وbackground وpadding وborder وmargin بالخاصيات المختصرة shorthand properties لأنها تضبط عدة قيم في سطر واحد. إليك مثالًا عن قيم في سطر واحد: /*تُطبق القيم وفق التسلسل: أعلى، يمين، أسفل، يسار padding في الاختصار وذلك إن كانت ذات أربع قيم بينما إن كانت ذات قيمتين فستكون القيمة الأولى أعلى/أسفا والثانية يسار/يمين */ padding: 10px 15px 15px 5px; الشيفرة السابقة مماثلة للتصريحات التالية: padding-top: 10px; padding-right: 15px; padding-bottom: 15px; padding-left: 5px; وهذا سطر واحد يختصر الخاصية background: background: red url(bg-graphic.png) 10px 10px repeat-x fixed; وهو مماثل تمامًا للتصريحات التالية: background-color: red; background-image: url(bg-graphic.png); background-position: 10px 10px; background-repeat: repeat-x; background-attachment: fixed; يمكن العودة دائمًا إلى موسوعة حسوب أو شبكة مطوري موزيللا لمعلومات أوفى عن الخاصيات المختصرة. تطبيق: حاول أن تتدرب على استخدام التصريحات السابقة لتألفها أكثر. تنبيه: لا بدّ من الإشارة إلى ناحية هامة جدًا تتعلق بالخاصيات المختصرة عندما تُحذف منها قيم. فالقيمة التي لا تُحدد في الاختصار ستأخذ قيمتها الأصلية، أي أنّ أي نقص في القيم سيعيد الخاصية إلى القيمة التي ضبطت عليها مسبقًا. التعليقات من الممارسات الجيدة عند كتابة أية شيفرة كتابة تعليقات أو ملاحظات حول ما تفعله وكذلك الأمر في CSS. يساعدك الأمر في تذكر طريقة عمل الشيفرة عندما تعود إليها لاحقًا لأغراض الصيانة أو التطوير، كما تساعد الآخرين على فهم الشيفرة. يمكن وضع التعليقات بين مجموعة البداية */و مجموعة النهاية /*. تحدد التعليقات في مثالنا التالي بداية أقسام مختلفة من الشيفرة، إذ يساعدك الأمر في التنقل بين كتل الشيفرة عندما يصبح الملف ضخمًا. وفي هذه الحالة يمكنك بكل سهول البحث عن تعليق محدد ضمن محرر الشيفرة الذي تستخدمه لتصل إلى قسم الشيفرة المطلوب: /* Handle basic element styling */ /* -------------------------------------------------------------------------------------------- */ body { font: 1em/150% Helvetica, Arial, sans-serif; padding: 1em; margin: 0 auto; max-width: 33em; } @media (min-width: 70em) { /* Increase the global font size on larger screens or windows for better readability */ body { font-size: 130%; } } h1 {font-size: 1.5em;} /* Handle specific elements nested in the DOM */ /* -------------------------------------------------------------------------------------------- */ div p, #id:first-line { background-color: red; border-radius: 3px; } div p { margin: 0; padding: 1em; } div p + p { padding-top: 0; } تفيدك التعليقات أيضًا في تعطيل جزء من الشيفرة مؤقتًا لاختبار إن كانت تعمل كما هو مطلوب أم لا. لاحظ كيف عطلنا المحدد special. في الشيفرة التالية بتحويل كتلة التصريحات المرتبطة به إلى تعليق: /*.special { color: red; }*/ p { color: blue; } الفراغات يشير هذا المصطلح إلى الفراغات ومسافات الجدول tabs والأسطر الجديدة. يتجاهل المتصفح هذه الفراغات في CSS كما يتجاهلها في HTML أما الغاية الأساسية من استخدامها فهي تسهيل قراءة الشيفرة. لاحظ كيف يُكتب كل تصريح ضمن سطر خاص به في المثال التالي، ويعدها كثيرون أمرًا جيدًا لانها تُسهِّل صيانة وفهم ملفات التنسيق. body { font: 1em/150% Helvetica, Arial, sans-serif; padding: 1em; margin: 0 auto; max-width: 33em; } @media (min-width: 70em) { body { font-size: 130%; } } h1 { font-size: 1.5em; } div p, #id:first-line { background-color: red; border-radius: 3px; } div p { margin: 0; padding: 1em; } div p + p { padding-top: 0; } يُظهر المثال التالي تصريحات CSS مطابقة للشيفرة السابقة مكتوبةً بشكل مكثّف. وعلى الرغم من أنّ النتيجة ستكون نفسها، إلا أنّ الشيفرة في المثال الثاني أصعب قراءةً: body {font: 1em/150% Helvetica, Arial, sans-serif; padding: 1em; margin: 0 auto; max-width: 33em;} @media (min-width: 70em) { body {font-size: 130%;} } h1 {font-size: 1.5em;} div p, #id:first-line {background-color: red; border-radius: 3px;} div p {margin: 0; padding: 1em;} div p + p {padding-top: 0;} اختر أسلوب كتابة CSS الذي تريده في إنجاز مشاريعك الخاصة، بينما قد تُوضع بعض القواعد عندما تعمل ضمن فريق لإنجاز مشروع جماعي. تنبيه: تُستخدم المسافات الفارغة للفصل بين القيم في تصريحات CSS، لكن يمُنع استخدامها ضمن أسماء الخاصيات. التصريح التالي مثلًا صحيح: margin: 0 auto; padding-left: 10px; لكن هذا التصريح خاطئ: margin: 0auto; padding- left: 10px; هل عرفت أين الخطأ؟ بداية لا تُعد القيمة 0auto صحيحة للخاصية margin، إذ ينبغي أن تكون هذه القيمة قيمتان 0 وauto يفصل بينهما مساحة فارغة. ولن يُميّز المتصفح ثانيًا الخاصية padding- left لأنّ الصحيحة هي دون وجود فراغ (padding-left). لا بدّ إذًا من فصل القيم المختلفة عن بعضها بمساحة فارغة واحدة على الأقل، والإبقاء على اسم الخاصية وقيمها معًا كسلسلة نصية مترابطة. تطبيق: جرب أن تضيف فراغات أو تزيلها في شيفرة CSS اختبارية وراقب ما يحدث! ترجمة -وبتصرف- للمقال How CSS is structured. اقرأ أيضًا المقال السابق: بدء استخدام لغة CSS آلية عمل تعليمات CSS داخل المتصفحات كيفية تعديل حجم عنصر HTML والمساحة المحيطة به باستخدام CSS
-
نعرض في هذه المقالة أساسيات ومبادئ سهولة الوصول accessibility وذلك بالاعتماد على محتوى إحدى الدورات التدريبية في Udacity وفق الترتيب التالي: تعريف مسألة سهولة الوصول لاسيما في مسائل تطوير الويب. آليات تحقيق سهولة الوصول وجعل مواقع الويب شاملة الاستخدام usable من قبل الجميع. كيفية تحقيق سهولة الوصول بأقل جهد ممكن خلال مرحلة التطوير. استخدام الميزات التي توفرها لغة HTML لتحسين سهولة الوصول. عرض الآليات المتقدمة التي تسمح بالوصول لتفاعل سلس للمستخدمين مع صفحات الويب. تعرض هذه المقالة جميع الآليات المتاحة لتطوير مواقع ويب سهلة الاستخدام من قبل الجميع مما سيرفع، بالتأكيد، من مستواك في التطوير. لن يكون الأمر صعبًا إذ يُمكنك القيام ببعض الممارسات البسيطة أثناء استخدامك لغة HTML لتحسين سهولة الوصول (إضافًة لبعض التقانات المتقدمة والتي سنعرضها في هذه المقالة). ستصل، باتباعك للإرشادات المُقدّمة إلى واجهات سهلة الاستخدام لجميع شرائح المستخدمين بما فيهم ذوي الاحتياجات الخاصة. قد يوجد لدى الكثير من المطورين تصور أو فهم خاطئ لما يعنيه سهولة الوصول (شيء له علاقة بالعقود الحكومية أو صناديق التحقق أو قارئات الشاشات؟)، أو لربما يظن البعض أن سيكون عليهم الاختيار بين واجهات جميلة وجذابة وأخرى غير أنيقة إنما سهلة الوصول. بما أن الأمر ليس ذلك على الإطلاق فلنبدأ أولًا بشرح ماذا نقصد بسهولة الوصول وما سنتعلم في هذه المقالة. ما هي سهولة الوصول؟ نصف، عادًة، موقع ويب بأنه سهل الوصول عندما يتمكن جميع المستخدمين بمختلف شرائحهم من الوصول إليه واستثمار وظائفه بسهولة. من البساطة لك كمطور ويب أن تفترض أن جميع المستخدمين قادرين على التفاعل والتعامل مع موقعك بنفس الطريقة التي تقوم بها أنت بنفسك وذلك باستخدام لوحة المفاتيح أو الفأرة أو شاشة اللمس. يُمكن أن تكون فرضيتك هذه صحيحة مع الكثير من المستخدمين إلا أنه قد تبرز في العديد من الحالات مشاكل في التعامل مع الموقع تتراوح من المضايقات البسيطة إلى التوقف عن التصفح والاستخدام. يُعنى تسهيل الوصول بتفقد تجربة المستخدمين غير النمطيين والذين يُمكن أن يكون لهم أسلوب مختلف وغير متوقع في التواصل والتعامل مع محتوى الويب لاسيما الأشخاص الذين يعانون من مشاكل معينة أو إعاقات مختلفة. لا يعني تركيزنا في مسألة سهولة الوصول على الأشخاص الذين يعانون من إعاقات جسدية إهمال مشاكل الوصول التي قد تظهر عند أي مستخدم. فمن منا لم يعان من مشاكل في استخدام التطبيقات على جواله المحمول أو لم يتمكن من الوصول لقائمة معينة على حاسوبه اللوحي أو تفاجأ بظهور عبارة "هذا المحتوى غير متاح لك في منطقتك"؟ تُساعد معالجة مسائل سهولة الوصول بهذا المعنى الأوسع والأعم على تحسين تجربة جميع المستخدمين في التعامل مع المنتج البرمجي كما سنرى لاحقًا. لنبدأ مثلًا بإلقاء نظرة على المثال التالي: من الواضح أن الواجهة السابقة تعاني من المشاكل التالية: للنص المكتوب تباين منخفض وبالتالي سيصعُب على ضعاف النظر قراءته. يوجد مسافات كبيرة بين العناوين (على اليسار) والحقول (على اليمين) مما سيجعل عملية الربط بينهما شاقة لاسيما لمن يتعامل مع هذا النموذج على الجوال ويقوم بتكبير النموذج لمعاينته مما سيُضطره أيضًا للتحريك يمنى ويسرى. لا يرتبط عنوان صندوق التحقق معه (تذّكر التفاصيل Remember details) وبالتالي سيكون على المستخدم النقر حصرًا على صندوق التحقق الصغير عوضًا عن النقر على العنوان. علاوًة على ذلك، لن يتمكن المستخدم الكفيف مثلًا والذي يستخدم قارئ شاشة من الربط بين العنوان وصندوق التحقق. إذا أصلحنا هذه المشاكل كلها بتطبيق حلول سهولة الوصول التالية: زيادة تباين النصوص بجعله أغمق وتعديل التصميم لتقريب التسميات من حقولها وربط عنوان خانة الاختيار معها، نحصل على النموذج المُحسّن التالي: إذا كنت تفضل النموذج الثاني على الأول فأنت، بالتأكيد، فهمت الهدف من هذا الدليل الإرشادي! وتذكر أنه غالبًا ما يكون الأمر الذي يمنع البعض من الوصول والتعامل مع منتجك يُسبب إرباكًا كبيرًا للآخرين. إرشادات تطوير محتوى الويب سهل الوصول نتبع في هذا الدليل الإرشادي الإرشادات التي يُقدّمها الدليل Web Content Accessibility Guidelines (WCAG) 2.0 وهي مجموعة من التوصيات والممارسات الجيدة التي وضعها خبراء سهولة الوصول لحل مسائل "سهولة الوصول" بطريقة منهجية. يتمحور الدليل الإرشادي WCAG حول أربعة مبادئ يُطلق عليها غالبًا الاختصار POUR الأجنبي: قابل للإدراك Perceivable: هل يُمكن للمستخدم إدراك المحتوى؟ مع الآخذ بعين الاعتبار أن ما نُدركه بحاسة واحدة مثل البصر لا يعني، بالضرورة، أن جميع المستخدمين يُمكن لهم أن يدركوه. قابل للتشغيل Operable: هل يتمكن المستخدم من التعامل مع الواجهات والتنقل عبر المحتوى؟ مثلًا إذا كان أمرًا في الواجهة يتطلب تحريك الفأرة فلن يتمكن الأشخاص الذين لا يقدرون على استخدام الفأرة أو شاشات اللمس من القيام به. مفهوم Understandable: هل يفهم المستخدم الواجهات دون أي غموض أو التباس؟ مرن Robust: هل يُمكن عرض المحتوى على متصفحات مختلفة وباستخدام أدوات مساعده؟ نظرًا لضخامة الإرشادات العامة التي يُقدّمها دليل WCAG، قامت مجموعة سهولة الوصول على الويب WebAIM (اختصارًا إلى Web Accessibility In Mind) باستخلاص مجموعة الإرشادات الخاصة بمحتوى الويب ووضعها في قائمة واحدة تُعطي المختصر المفيد مع تسهيل العودة لتفصيلات WCAG إن لزم الأمر. سيُحقق التزامك بهذه الإرشادات تطوير محتوى ويب يتمتع بسهولةالوصول من قبل كافة شرائح المستخدمين. فهم تنوع المستخدمين من المفيد البدء أولًا بفهم احتياجات المستخدمين بمختلف شرائحهم والمشاكل التي قد تواجه البعض منهم عند تعاملهم مع محتوى الويب. للمزيد من التوضيح نعرض فيما يلي جلسة أسئلة/أجوبة مفيدة مع فيكتور تسارن Victor Tsaran مدير البرنامج الفني في شركة Google وهو شخص كفيف لا يرى شيئًا على الإطلاق. السؤال: ما هي طبيعة عملك في Google؟ الجواب: أعمل على التأكد من أن منتجات Google تلائم جميع المستخدمين بما فيهم ذوي الإعاقات مهما كان نوعها. السؤال: ما هي أنواع الإعاقات التي يعاني المستخدمون منها بشكل عام؟ الجواب: يأتي فقدان البصر في مقدمة الإعاقات التي قد تجعل من الصعوبة، وأحيانًا من المستحيل، التفاعل مع الكثير من مواقع الويب لاسيما أن العديد من تقانات الويب المتقدمة لا تأخذ بعين الاعتبار الأدوات المختلفة التي يستخدمها المكفوفون في تصفح محتوى الويب. وبشكل عام يُمكن تقسيم إعاقات المستخدمين إلى أربع مجموعات: البصرية والحركية والسمعية والإدراكية. السؤال: لنعرض هذه الإعاقات واحدًة تلو الأخرى ولنبدأ أولًا ببعض الأمثلة عن الإعاقة البصرية الجواب: تُقسم الإعاقات البصرية إلى عدة فئات أولها المستخدمون الكفيفون، مثلي، والذين يتوجب عليهم استخدام قارئ شاشة أو قارئ برايل أو تركيبة من الاثنين. إضافًة إلى الكفيفين الذين لا يرون على الإطلاق، هنالك عدد كبير من المستخدمين الذين يعانون من ضعف البصر والذين يكون لهم في الغالب نظارات طبية سميكة. يوجد الكثير من الحلول لهؤلاء الأشخاص مثل استخدام قارئ الشاشة أو قارئ برايل أو استخدام تقنية تحويل النص إلى كلام، كما يُمكن لهم تكبير الشاشة وزيادة التباين وتكبير حجم الخطوط وغيرها من التقانات المساعدة والتي ربما يقوم بها الأشخاص العاديون للحصول على مظهر أريح للعين. ومع ملاحظة أن النظر يضعف مع تقدم العمر وأنه في لحظات معينة يُمكن لأي شخص أن تحصل له مشاكل في البصر (بعد عملية ليزر جراحية في العين مثلاً أو بوجود أشعة الشمس القوية على شاطئ البحر مثلًا). أطلب من مطوري الويب أخذ هذا الأمر بعين العطف لمراعاة أصحاب هذه الإعاقات. كما أُذكّر أيضًا بأن 9% من الذكور و1% من الإناث لديهم مشاكل بصرية في تمييز الألوان (الأحمر مع الأخضر مثلًا أو الأصفر مع الأزرق) مما يتطلب من مطوري نماذج الويب مراعاة ذلك أيضًا. السؤال: ماذا عن الإعاقات الحركية؟ الجواب: يُمكن أن تتراوح الإعاقات الحركية من أشخاص لا يستطيعون الحركة أبدًا إلى أشخاص لا يُمكنهم تحريك الفأرة لسبب أو لآخر مثل الأشخاص الذين يعانون من إصابات الإجهاد المتكرر RSI مثلًا. يُمكن حسب درجة الإعاقة الحركية التفاعل مع الحاسوب باستخدام لوحة المفاتيح أو جهاز تبديل أو حتى جهاز متابعة العين كما يُمكن لمثل هؤلاء الأشخاص إعطاء الأوامر للحاسوب صوتيًا. على غرار ضعف البصر، يُمكن أن تكون الإعاقة الحركية مؤقتة كأن تكون راكبًا في قطار يهتز بقوة أو أنك كسرت يدك أو غيرها من الحالات. وبجميع الأحوال، يجب أن نلبي احتياجات ذوي الإعاقات الدائمة والمؤقتة. السؤال: لنتكلم الآن عن الإعاقات السمعية. الجواب: يتراوح الأشخاص في هذه المجموعة أيضًا من الأصم إلى ضعيف السمع. وعلى غرار البصر، يضعُف السمع مع التقدم بالعمر ويلجأ الأشخاص عادًة إلى وسائل تقوية السمع. يجب، أثناء تطوير الواجهات، التأكد من أننا لا نعتمد على الصوت فقط بل نوفر بدائل مثل التعليقات والنصوص. وكما هو الحال مع الإعاقات البصرية والحركية، فمن السهل حقًا تخيل موقف يستفيد فيه شخص تعمل أذنيه جيدًا من هذه البدائل أيضًا. ففي مكتب عمل يتشاركه العديدون، يُمكن حضور فلم فيديو بدون صوت إذا كان الحوار مكتوبًا على الفلم. السؤال: هل يُمكن أن تخبرنا قليلًا عن الإعاقات الإدراكية؟ الجواب: تختلف هذه الإعاقات حسب الحالة فهنالك حالات عسر القراءة وحالات التوحد وحالات التشتت وغيرها من الحالات التي يتطلب معظمها إيجاد تصميمات بسيطة لواجهات التفاعل مع المستخدم. بالطبع، يُمكن لهؤلاء الأشخاص استخدام وظائف التكبير/التصغير لتسهيل القراءة أو زيادة التركيز. بالتأكيد، إذا ابتكرنا ما يُمكن أن يجده الشخص الذي يعاني من ضعف إدراكي مفيدًا فسيكون ممتعًا ومفيدًا لجميع الآخرين. السؤال: هل يُمكن لك في النهاية تلخيص وجهة نظرك بخصوص سهولةالوصول؟ الجواب: إن تصميم وبناء منتجات تتوجه فقط للأشخاص الذين لا يعانون من أي مشكلة سيجعل جمهور هذا المنتج ضيقًا جدًا نظرًا لوجود الإعاقات، ولو بشكل جزئي أو مؤقت، عمليًا عند الجميع. قام فيكتور خلال هذه المقابلة بتصنيف الإعاقات ضمن أربع مجموعات: البصرية والحركية والسمعية والإدراكية، كما نوه إلى أن هذه الإعاقات يُمكن أن تكون ظرفية أو مؤقتة أو دائمة. يُعطي الجدول التالي بعض الأمثلة الواقعية لمختلف أنواع الإعاقات (لاحظ أن بعض الإعاقات قد تندرج في أكثر من تصنيف): table { width: 100%; } thead { vertical-align: middle; text-align: center; } td, th { border: 1px solid #dddddd; text-align: right; padding: 8px; text-align: inherit; } tr:nth-child(even) { background-color: #dddddd; } ظرفية مؤقتة دائمة بصرية ارتجاج في المخ العمى حركية حمل طفل ذراع مكسور، إصابات الإجهاد المتكررة إصابات الإجهاد المتكررة سمعية ضجيج مكتب إدراكية ارتجاج في المخ من الأمثلة على إصابات الإجهاد المتكررة: متلازمة النفق الرسغي carpal tunnel syndrome، مرفق التنس tennis elbow، إصبع الزناد trigger finger. الخطوات الموالية عرضنا في هذه المقالة أساسيات سهولة الوصول: تعريف مسألة سهولة الوصول ومدى أهميتها. قوائم إرشادات تحقيق سهولة الوصول WCAG و WebAIM. الأنواع المختلفة من الإعاقات التي يجب مراعاتها أثناء تصميم محتوى الويب. نعرض في بقية هذا الدليل الإرشادي الجوانب العملية للوصول إلى موقع ويب ذو سهولة وصول جيدة وحيث سنُركّز العمل حول ثلاثة جوانب أساسية: التركيز Focus: نعرض كيفية الاستعاضة عن الفأرة بلوحة المفاتيح مما يسمح للمستخدمين الذين يعانون من إعاقات حركية من التعامل مع الواجهات المختلفة كما يضمن هذا الأمر تحقيق واجهات سهلة الاستخدام ولجميع المستخدمين. الدلالات Semantics: يجب أن نضمن أن واجهاتنا المطورة تعمل بشكل جيد مع أدوات الوصول المختلفة التي يُمكن أن تُستخدم من قبل ذوي الإعاقات. التصميم Styling: يجب أن يُحقق تصميم الوجهات سهولة الاستخدام إلى أكبر قدر ممكن عبر استخدام التقانات المناسبة. يحتاج كل محور من هذه المحاور إلى دورة تدريبية كاملة لذا لن نغطي كل المواضيع بشكل كامل وإنما سنزودك بنقاط البدء ونوجهك إلى العديد من المراجع المفيدة. ترجمة -وبتصرف- للمقال Accessibility للكتّاب الأربعة: Meggin Kearney, Dave Gash, Alice Boxhall, Rob Dodson. اقرأ أيضًا تعلم البرمجة المدخل الشامل لتعلم علوم الحاسوب نظرة عامة عن تطويرتطبيقات الأجهزة المحمولة عبر كوردوفا النسخة الكاملة لكتاب نحو فهم أعمق لتقنيات HTML5
-
نُناقش مسألة التركيز Focus في القسم الأول من هذه المقالة التعليمية، كما نشرح آلية ترتيب عناصر شجرة DOM في القسم الثاني منها، ونُنهي المقالة بشرح استخدام فهرس الجدولة tabindex. مقدمة في التركيز نبدأ أولًا بشرح عملية التحكم بالتركيز على العناصر وآليات إدارته، وحيث يختص التركيز بعناصر التحكم (عناصر الإدخال مثل الحقول وصناديق التحقق والأزرار والروابط) التي تتلقى حاليًا الدخل من لوحة المفاتيح أو من الحافظة عند إجراء عملية لصق. يُعدّ التركيز نقطة الانطلاق الأولى لتعلم مسائل إمكانية الوصول لاسيما أننا جميعًا نتعامل مع لوحة المفاتيح بسهولة، كما سيستفيد جميع المستخدمين من نتائج إعداد التركيز المناسب. قد يعتمد المستخدمون الذين يعانون من إعاقات حركية، والتي تتراوح من التواء الرسغ إلى الشلل الدائم، على لوحة مفاتيح أو جهاز تبديل للتنقل في صفحة الويب، مما يستلزم توفير تجربة استخدام جيدة ووضع استراتيجية تركيز ملائمة لهم. تُساهم عملية التنقل في الموقع بسرعة في رفع انتاجية المستخدمين لاسيما المحترفين منهم والذين يستخدمون اختصارات لوحة المفاتيح بسهولة. وبالمحصلة، تضمن استراتيجية التركيز المُنفذّة جيدًا تمتع كل مستخدم بتجربة أفضل. سنرى لاحقًا أن الجهد الذي قد يبذله المطور ضروري للسماح لذوي الإعاقات المختلفة باستخدام الأدوات المساعدة كما أنه يُساعد في إغناء تجارب تعامل كل المستخدمين مع صفحات الويب المطورة. ما هو التركيز يُحدّد التركيز عنصر التحكم الحالي الذي يتلقى الإدخالات من لوحة المفاتيح ويعرض الأحرف التي يكتبها المستخدم، كما يستقبل هذا العنصر بيانات أي عملية لصق من الحافظة. يُميّز العنصر الحاصل على التركيز بواسطة إطار لوني حوله يعتمد نمطه على المستعرض أو على أسلوب التنسيق المُحدّد من قبل مطور صفحة الويب. يقوم المستعرض Chrome مثلًا بوضع إطار أزرق، بينما يقوم Firefox بوضع إطار متقطع. يتعامل بعض المستخدمين مع حاسوبهم حصرًا باستخدام لوحة المفاتيح وبالتالي يكون التركيز بالنسبة لهم أمرًا هامًا جدًا فهو وسيلتهم للوصول إلى أي كائن في صفحة الويب. تنص قائمة التحقق من مجموعة إمكانية الوصول Web AIM (اختصارًا إلى Web Accessibility In Mind) في الفقرة السابقة منها على أن جميع وظائف صفحة الويب يجب أن تكون ممكنة الوصول عن طريق لوحة المفاتيح (إلا في حالات خاصة لا يُمكن القيام بها باستخدام لوحة المفاتيح كالرسم اليدوي مثلًا). يُمكن نقل التركيز من عنصر لآخر باستخدام مفتاح الجدولة Tab أو التركيب Shift+Tab أو باستخدام مفاتيح الأسهم. يختلف هذا الأسلوب قليلًا في نظام التشغيل Mac OSX. يسمح لك المتصفح Chrome بالتنقل باستخدام المفتاح Tab بينما يجب استخدام Option+Tab في المتصفح Safari. يُمكن تغيير إعدادات نقل التركيز باستخدام لوحة المفاتيح عن طريق نافذة لوحة المفاتيح من تفضيلات النظام: يُدعى ترتيب نقل التركيز من عنصر لآخر للأمام أو للخلف بترتيب الجدولة، وهو من الأمور التي يجب على مطور صفحة الويب أن يأخذها بالحسبان فيتحقق من وجود ترتيب انتقال ملائم بين العناصر في الصفحة. تعريف إمكانية التركيز يُمكن التركيز على أي عنصر من عناصر HTML التي تسمح للمستخدم بالتفاعل معها (تغيير قيمها أو حالتها) مثل صناديق النصوص والأزرار والقوائم، وتدخل تلقائيًا في ترتيب الجدولة وتتفاعل مع أحداث لوحة المفاتيح دون أي تدخل من قبل مطور الصفحة. أما العناصر التي لا يتفاعل المستخدم معها مثل الفقرات والحاويات div فلا ينتقل التركيز عليها ولا تدخل في ترتيب الجدولة. تجربة التركيز نعرض في المثال التالي تقانات التركيز التي شرحناها سابقًا: افتح المستعرض Chrome وانتقل للرابط airline site mockup page واطلب تذكرة سفر باستخدام لوحة المفاتيح حصرًا (لا تتفاعل الصفحة بأي حال مع الفأرة). عليك ملء المعلومات التالية: اتجاه واحد للسفر oneway إلى مدينة Arrival ملبورن Melbourne تاريخ المغادرة Depart Date 12/10/2017 تاريخ العودة Return Data 23/10/2017 مقعد جانب النافذة Preferred seat type لا تطلب تلقي إشعارات العروض الترويجية Receive promotional offers بمجرد أن تنتهي من إتمام عملية إدخال البيانات دون أي خطأ ومن ثم نقر زر البحث، سيتم مسح البيانات وإعادة تهيئة نموذج إدخال جديد (قم بالتجربة المطلوبة ومن ثم أتمم القراءة). لنعاين الآن كيف يتفاعل نموذج الصفحة السابق مع إدخالات لوحة المفاتيح. يؤدي الضغط على مفتاح الجدولة Tab في البداية إلى إضاءة الروابط أعلى النموذج (الرحلات Flights، الفنادق Hotels، سيارات الأجرة Rental Cars)، وإذا استمريت بضغط مفتاح الجدولة مرارًا ستنتقل إلى مجموعة أزرار الانتقاء والتي عليك الآن استخدام مفاتيح الأسهم للتنقل فيما بينها (نوع الرحلة). اخرج من مجموعة أزرار الانتقاء باستخدام مفتاح الجدولة Tab لتنتقل إلى حقل الاسم ومن ثم إلى حقل العنوان للكتابة فيهما. عند وصولك للقائمة المنسدلة للمدن، يُمكنك اختيار عنصر منها عن طريق مفاتيح الأسهم أو عن طريق البدء بكتابة الأحرف الأولى من اسم المدينة ليتم ملء الحقل بالمدينة المناسبة. عند وصولك لقائمة نوع الكرسي يُمكن اختيار عنصر من القائمة باستخدام مفاتيح الأسهم أو بكتابة أحد الأحرف w أو a أو n لتحديد عنصر القائمة الموافق (لا تفضيل No preference، ممر Aile، نافذة Window). يُمكنك إلغاء تحديد صندوق التحقق (لطلب عدم تلقي إشعارات الحملات الترويجية) بالضغط على مفتاح المسافة عند وصول التركيز لصندوق التحقق. ضع أخيرًا التركيز على زر البحث Search وانقر المفتاح Enter لإرسال بيانات النموذج. يبدو أن التفاعل مع النموذج باستخدام لوحة المفاتيح فقط أسهل وأسرع من استخدام الفأرة ولوحة المفاتيح معًا (وضياع الوقت بالتنقل بينهما)، وهو أمر سهل التحقيق من قبل المطور لأن ما عليه سوى استخدام عناصر HTML الأساسية ولن يحتاج إلى كتابة أي شيفرة إضافية لإدارة عمليات التركيز. أهمية ترتيب العناصر في شجرة DOM يؤدي استخدام عناصر HTML الأساسية إلى الحصول على ترتيب انتقال تركيز ملائم إذ أن ترتيب الانتقال بين العناصر يكون وفق ترتيبها في نموذج كائن الوثيقة DOM. يكون ترتيب انتقال التركيز بين الأزرار في المثال التالي وفق ترتيبها في DOM أي الزر "I Should" أولًا ومن ثم الزر "Be Focused" و أخيرًا الزر "Last": <button>I Should</button> <button>Be Focused</button> <button>Last!</button> يجب الانتباه إلى بعض المشاكل التي قد تنجم عند استخدام تنسيق CSS لاسيما إذا كان ذلك يؤثر على أمكنة تموضع العناصر. فمثلًا إذا وضعت الخاصية (عائم إلى اليمين) للزر الأول "float: right" فسيظهر هذا الزر أقصى اليمين إلا أن ترتيبه في الجدولة سيبقى الأول لأنه الأول في ترتيب العناصر ضمن DOM. بالتأكيد، سيُسبب هذا إرباكًا للمستخدم إذ سيقفز بزر الجدولة Tab من الزر أقصى اليمين "I Should" إلى الزر أقصى اليسار "Be Focused" بعده. <button style="float: right">I Should</button> <button>Be Focused</button> <button>Last!</button> تنص قائمة التحقق من مجموعة إمكانية الوصول Web AIM اختصارًا Web Accessibility In Mind على أن الترتيب المرئي (ترتيب القراءة) يجب أن يكون متوافقًا مع ترتيب الجدولة كي لا نُربك المستخدم الذي يعتمد على لوحة المفاتيح. المحتوى غير الظاهر يجب الانتباه إلى انتقال التركيز على عناصر غير ظاهرة مما يُربك المستخدم الذي سيشعر عندها بفقدان أو ضياع مؤشر التركيز وسيبدأ بضغط مفتاح الجدولة مرارًا ليكتشف أن مؤشر التركيز يظهر ويختفي! يُمكن أن تظهر هذه المشكلة مثلًا عند استخدام لوحة تنقل جانبية متجاوبة responsive side navigation panel وعندها يجب أن نمنع التركيز من الانتقال للوحة عندما لا تكون ظاهرة، ونسمح له بالانتقال لها فقط عندما يكون المستخدم في حالة تفاعل معها. قد يتوجب عليك أحيانًا البحث عن موضع التركيز باستخدام خاصية العنصر النشط document.activeElement لمعرفة العنصر النشط حاليًا، ومن ثم إظهاره باستخدام display: none أو visibility: hidden أو إخفائه باستخدام display: block أو visibility: visible حسب الحالة. نؤكد أخيرًا على ضرورة قيام المطور بتجريب عملية التنقل مرارًا وتكرارًا في صفحته المطورة قبل نشرها للعموم ليتأكد من عدم وجود أي خلل في التركيز كاختفائه أو وجود ترتيب غير ملائم، وفي حال وجود أي خلل فيُمكن تصحيحه عن طريق إعادة ترتيب العناصر في نموذج كائن الوثيقة DOM أو عن طريق إخفاء العناصر عندما تكون غير ظاهرة في الشاشة ومن ثم إظهارها عندما يتفاعل المستخدم معها. استخدام فهرس الجدولة tabindex يُلائم الترتيب الافتراضي للجدولة والذي يُحدّده ترتيب العناصر في شجرةDOM السلوك المنطقي المطلوب للانتقال، إلا أنه قد تتطلب صفحتك المطورة تغيير هذا الترتيب الافتراضي. يُمكن القيام بذلك بتغيير مكان توضع العنصر في الوثيقة إلا أن ذلك قد لا يكون ممكنًا في بعض الحالات مما يجعلنا نتوجه لاستخدام سمة فهرس الجدولة tabindex في HTML. يُمكن تحديد ترتيب الجدولة لأي عنصر باستخدام السمة tabindex والتي تكون قيمتها عدد صحيح يُحدّد ترتيب العنصر. علاوةً على ذلك، يُمكن استخدام هذه السمة لإضافة كائن لا يتمتع بإمكانية التركيز (مثل الحاويات div) إلى ترتيب الجدولة، كما يُمكن حذف عناصر من ترتيب الجدولة. يؤدي إسناد القيم 0 إلى السمة tabindex لإضافة العنصر إلى الترتيب الطبيعي للجدولة أي يُمكن الانتقال له باستخدام مفتاح الجدولة Tab كما يُمكن وضع التركيز عليه برمجيًا باستخدام الطريقة focus. يُظهر المثال التالي عنصر مخصص يُمكن الانتقال له باستخدام المفتاح Tab: <custom-button tabindex="0">Press Tab to Focus Me!</custom-button> يؤدي إسناد القيم -1 إلى السمة tabindex إلى إزالة العنصر من الترتيب الطبيعي للجدولة أي لن يعود بالإمكان الانتقال له بمفتاح الجدولة Tab إلا أنه يُمكن وضع التركيز عليه برمجيًا باستخدام الطريقة focus. <button id="foo" tabindex="-1">I'm not keyboard focusable</button> <button onclick="foo.focus();">Focus my sibling</button> لا يُمكن الآن الانتقال للزر الأيسر بمفتاح الجدولة Tab وإنما يُمكن وضع التركيز عليه بالنقر على الزر الأيمن: يؤدي إسناد قيمة صحيحة أكبر من الصفر (مثلًا 5) إلى وضع العنصر الموافق في مقدمة ترتيب الجدولة. أما إذا وجد أكثر من عنصر لهم قيمة أكبر من الصفر فيتم الانتقال بدءًا من العنصر ذو القيمة الأدنى (أكبر من الصفر) إلى القيمة الأعلى التالية وهكذا. تُعدّ عملية إسناد قيم أكبر من الصفر مخالفة للنموذج النمطي الطبيعي anti-pattern. ليكن لدينا مثلًا: <button>I should be first</button> <button tabindex="6">And I should be second</button> <button tabindex="5">But I jumped to the front!</button> سيكون الزر الأخير (الأيمن) أول الأزرار في الجدولة ومن ثم الزر الثاني(الأوسط) وأخيرًا الزر الأول. بالطبع، لا معنى لتغيير ترتيب الجدولة للعناصر التي لا يتفاعل معها المستخدم مثل العناوين والصور. كما أنه من المستحسن تنظيم ترتيب الجدولة وفق ترتيب العناصر في DOM وعدم اللجوء لاستخدام tabindex إلا عند الضرورة القصوى مقتصرًا على عناصر التحكم التفاعلية مثل صناديق النص والأزرار والقوائم. لا تقلق بشأن مستخدمي قارئ الشاشة أن يفوتهم محتوى هامًا بسبب أن ليس له ترتيب جدولة tabindex، فحتى لو كان المحتوى مهمًا مثل الصور لا داع أن تضع له ترتيب جدولة لأن المستخدم لن يتفاعل معها أصلًا. ركّز على وضع عبارات توصيفية للصور في الخاصية Alt كي يستفيد منها مستخدمي قارئ الشاشة كما سنعرض لاحقًا. إدارة التركيز على مستوى الصفحة يُمكن أن يكون استخدام السمة ضروريًا في بعض الحالات. مثلًا: إذا احتوت صفحة على عدة أقسام لا تُعرض جميعها بنفس الوقت أي أن النقر على رابط قد يؤدي إلى تغيير المحتوى الظاهر دون إعادة تحميل الصفحة. يجب إذًا في هذه الحالة إسناد القيمة -1 لترتيب الجدولة لكل قسم كي لا ننتقل بمفتاح الجدولة Tab للقسم وإنما حصرًا باستخدام الطريقة focus. يحافظ هذا الأسلوب، المدعو بإدارة التركيز، على تزامن المحتوى المرئي مع سياق تفاعل المستخدم مع الصفحة. إدارة التركيز للعناصر المخصصة يُمكن أيضًا أن تحتاج لإدارة التركيز للتحكم بعنصر مخصص. مثلًا نعلم أنه يُمكن استخدام مفاتيح الأسهم لتحديد خيار من عنصر قائمة الاختيار الأساسية select. إذا أنشأت عنصرًا مخصصًا مشابه للقائمة، فسترغب بأن يكون له نفس أسلوب الاختيار لتراعي مستخدمي لوحة المفاتيح والذين يستخدمون الأسهم لاختيار عنصر من القائمة. نقوم في الشيفرة التالية باستخدام عنصر القائمة الأساسي مما يُعطي قائمة يُمكن التنقل والاختيار منها باستعمال مفاتيح الأسهم: <!-- يُمكن نقل التركيز باستخدام مفتاح الجدولة أو مفاتيح الأسهم--> <select> <option>Aisle seat</option> <option>Window seat</option> <option>No preference</option> </select> Aisle seat Window seat No preference قد لا يكون من السهل دائمًا معرفة سلوك لوحة المفاتيح الواجب تنفيذها مما يتوجب العودة إلى دليل تطوير تطبيقات الإنترنت الغنية سهلة الوصول Accessible Rich Internet Applications Authoring Practices التي تختصر إلى ARIA، لمعاينة قائمة أنواع عناصر التحكم وأحداث لوحة المفاتيح التي تتجاوب معها. نستخدم هذا الدليل لدعم لوحة المفاتيح في عنصر مخصص جديد. ليكن مثلًا العنصر المخصص Custom Elements الجديد التالي والذي يُماثل مجموعة أزرار الانتقاء إنما يُمكن أن نُخصص له مظهرًا وسلوكًا جديدين: <radio-group> <radio-button>Water</radio-button> <radio-button>Coffee</radio-button> <radio-button>Tea</radio-button> <radio-button>Cola</radio-button> <radio-button>Ginger Ale</radio-button> </radio-group> بمراجعة القسم الثاني من دليل ARIA لتحديد نوع التفاعل مع لوحة المفاتيح المطلوب، نجد ضمن قائمة نماذج التصميم المقترحة جدول مواصفات مجموعة أزرار الانتقاء characteristics table for radio groups والتي تُعدّ الأقرب للعنصر المخصص الذي نقوم بتطويره. يُبين هذا الجدول ضرورة تجاوب العنصر مع مفاتيح الأسهم أعلى/أسفل/يمين/يسار. لإضافة هذا التفاعل مع العنصر المخصص الجديد سنستخدم تقنية تُدعى ترتيب الجدولة المتنقل roving tabindex. تتمحور تقنية ترتيب الجدولة المتنقل على إسناد القيمة -1 لجميع العناصر ما عدا العنصر المُحدّد حاليًا: <radio-group> <radio-button tabindex="0">Water</radio-button> <radio-button tabindex="-1">Coffee</radio-button> <radio-button tabindex="-1">Tea</radio-button> <radio-button tabindex="-1">Cola</radio-button> <radio-button tabindex="-1">Ginger Ale</radio-button> </radio-group> يستخدم العنصر المخصص الجديد مستمع listener لمعرفة المفتاح الذي يضغطه المستخدم وعندها تُسندّ قيمة ترتيب الجدولة -1 إلى العنصر المُحدّد حاليًا ومن ثم تُسندّ القيمة 0 لترتيب الجدولة للعنصر الجديد الذي سيُحدّد باستخدام الطريقة focus. <radio-group> // Assuming the user pressed the down arrow, we'll focus the next available child <radio-button tabindex="-1">Water</radio-button> <radio-button tabindex="0">Coffee</radio-button> // call .focus() on this element <radio-button tabindex="-1">Tea</radio-button> <radio-button tabindex="-1">Cola</radio-button> <radio-button tabindex="-1">Ginger Ale</radio-button> </radio-group> عندما يصل المستخدم إلى الخيار الأخير (أو الأول، وفق الاتجاه الذي يتحرك به باستخدام مفاتيح الأسهم)، نعاود وضع التركيز على الخيار الأول (أو الأخير). يُمكن العودة إلى مستودع GitHub للحصول على الشيفرة المتاح للعموم وتجريب العنصر الجديد المخصص. النوافذ الشرطية وقفل لوحة المفاتيح يُمكن في بعض الأحيان، أثناء إدارة التركيز، الوقوع في ورطة لا يُمكن الخروج منها. من الأمثلة على ذلك حالة عنصر الإكمال التلقائي autocomplete الذي يحاول إدارة التركيز ومتابعة ترتيب الجدولة إلا أنه يمنع التركيز من الخروج منه حتى إكمال النص مما يؤدي إلى حجز لوحة المفاتيح والذي يُمكن أن يضايق المستخدم إلى حد كبير. تنص الفقرة 2.1.2 من دليل ARIA على أنه لا يجوز بأي حال من الأحوال حجز لوحة المفاتيح أو حصر التركيز في عنصر ما إذ أن المستخدم يجب أن يكون قادرًا على التنقل ضمن جميع عناصر الصفحة بحرية كاملة. يُمكن أن يكون هذا السلوك مطلوبًا في بعض الحالات مثل حالة النافذة الشرطية modal التي تمنع المستخدم من الوصول لعناصر الصفحة الخلفية. يُمكن وضع غطاء داكن شفاف لتغطية الصفحة الخلفية إلا أن ذلك لن يمنع خروج التركيز خارج النافذة الشرطية بشكل أكيد. يُمكن في مثل هذه الحالات تنفيذ حجز مؤقت للوحة المفاتيح لحصر التركيز ضمن النافذة الشرطية عندما تكون مفتوحة ومن ثم العودة للعنصر الذي كان عليه التركيز في الصفحة الخلفية عند إغلاق النافذة الشرطية. يوجد العديد من المقترحات لتسهيل المعالجة السابقة مثل استخدام العنصر الجديد <dialog> إلا أنه مازال غير متوافق مع بعض المتصفحات. يُمكن العودة للمقالة للتزود بمعلومات أكثر عن <dialog> كما يُمكن تفحص هذا المثال من مستودع GitHub. نعرض فيما يلي الخطوات الأساسية اللازمة لتنفيذ قفل لوحة المفاتيح بشكل مؤقت وذلك لحالة نافذة شرطية (حاوية div لبعض العناصر) مع حاوية ثانية للغطاء الداكن. استخدم التابع document.querySelector لحفظ مرجع لحاوية النافذة الشرطية ومرجع للحاوية الثانية. احفظ فور فتح النافذة الشرطية مرجع للعنصر الذي كان عليه التركيز في النافذة الخلفية (وبهذا ستتمكن من الرجوع إليه لاحقًا). استخدم مستمع لحدث ضغط مفتاح للأسفل keydown. يجب أيضًا استخدام مستمع لحدث النقر على الحاوية الثانية. احصر مجموعة العناصر القابلة للتركيز في النافذة الشرطية إذ سيلعب العنصر الأول والأخير دور الحارس للدوران ضمن مجموعة العناصر مع مفتاح الجدولة لضمان البقاء ضمن النافذة الشرطية. أظهر النافذة الشرطية وضع التركيز على أول عنصر فيها. انقل التركيز من عنصر لآخر للأمام عندما يقوم المستخدم بضغط مفتاح الجدولة Tab أو للخلف عندما يقوم المستخدم بضغط Shift+Tab مع مراعاة الدوران عند أول وآخر عنصر. أغلق النموذج حال ضغط المستخدم لمفتاح الهروب Esc (هذا أمر ضروري يسمح للمستخدم بإغلاق النافذة دون البحث عن زر الإغلاق ومفيد بالأخص للمستخدمين الذين لا يستعملون الفأرة). أخف النافذة الشرطية وحاوية الغطاء عند طلب الإغلاق وأعد التركيز على عنصر الصفحة الذي قمت بحفظ مرجع له. يُمكن، باتباع الخطوات السابقة، إدارة نافذة شرطية مريحة التعامل لجميع فئات المستخدمين. يُمكن الحصول على الشيفرة المتاح للجميع واختبار المثال كاملًا. ترجمة -وبتصرف- للمقالات الثلاث التالية: Introduction to Focus DOM Order Matters Using tabindex للمؤلفين الثلاثة: Meggin Kearney, Dave Gash, Rob Dodson. اقرأ أيضًا المقال السابق: سهولة وصول جميع الزوار لمواقع وتطبيقات الويب استخدام Vue.js للتعامل معDOM اكتشاف دعم المتصفحات لميزات HTML5 تعلم البرمجة المدخل الشامل لتعلم علوم الحاسوب p iframe { border: 1px solid #e7e5e3 !important; }
-
قد يبدو الحكم على سهولة الوصول accessibility لتطبيق أو لموقع ويب وشموليته لكل المستخدمين بأنه مهمة صعبة. ولربما يتساءل البعض عن نقطة البداية لهذه المهمة، لا سيما هؤلاء الذين يتعاملون مع عملية التحقق من سهولة الوصول للمرة الأولى. بما أن العملية تعني التحقق من مجموعة متنوعة من الإمكانات فهذا يعني وجوب مراعاة مجموعة من المسائل المختلفة. نعرض في هذه المقالة آلية مقترحة تفصل هذه المسائل وتعمل عليها بشكل منطقي خطوة بخطوة للتحقق من سهولة الوصول لموقع ويب. البدء مع لوحة المفاتيح يُعدّ التنقل في الصفحة باستخدام لوحة المفاتيح فقط الوسيلة الأساسية للوصول لكل شيء على الشاشة من قبل المستخدمين الذين لا يُمكن لهم استعمال الفأرة (أو الذين يُحبذون عدم استعمالها). توجد شريحة واسعة من هذا النوع من المستخدمين مثل الأشخاص الذين يعانون من إعاقات حركية أو من الشلل أو المصابون بالإجهاد المتكرر (الناتج أحيانًا عن الاستخدام الطويل للفأرة)، إضافًة إلى مستخدمي قارئ الشاشة (ضعاف البصر مثلًا). يُعدّ توفير ترتيب تنقل منطقي عبر مفتاح تاب tab ومراعاة التركيز على العناصر بدقة لتوضيح مكان المؤشر الحالي أحد أهم أساسيات تحقيق سهولة الوصول باستخدام لوحة المفاتيح. النقاط الأساسية يجب أن تراعى النقاط الأساسية التالية: يُمكن البدء بالتنقل في الموقع باستخدام مفتاح الجدولة tab للتأكد من توفير ترتيب الجدولة المنطقي. يجب أن يكون ترتيب الجدولة موافقًا لترتيب العناصر في شجرة DOM. يُمكن العودة للمقالة التركيز على عناصر صفحة الويب لمراجعة القاعدة الأساسية في التركيز والتي تنص على أن أي عنصر تحكم يتفاعل المستخدم معه يجب التمكن من وضع التركيز عليه وإظهار مؤشر مرئي واضح للمستخدم عندها (مثلًا: إظهار حلقة تركيز focus ring). من الممارسات الشائعة تعطيل تنسيق الحدود الظاهرة على حواف العنصر عبر ضبط outline: none دون توفير أي تنسيقات بدلية لحدود حواف العنصر في CSS ولا تعد هذه من الممارسات الجيدة.anti-pattern. لن يتمكن مستخدم لوحة المفاتيح من التفاعل مع الصفحة إذا كان لا يستطيع رؤية موضع التركيز. يُمكن استخدام مكتبة برمجية مثل المكتبة what-input في حال الرغبة بالتمييز بين التركيز باستخدام الفأرة أو باستخدام لوحة المفاتيح. يجب إتاحة التركيز على العناصر المخصصة التفاعلية. مثلًا: في حال استخدام سكريبت جافا لتحويل مقطع إلى قائمة منسدلة جميلة فلن تكون قابلة للتركيز آليًا. يجب إسناد القيمة 0 لخاصية ترتيب الجدولة tabindex=0 لإتاحة التركيز على العنصر. يجب تجنب وضع قيم أكبر من الصفر للخاصية tabindex لأن ذلك سيجعلها في مقدمة ترتيب الجدولة وبغض النظر عن مكانها في شجرة DOM، مما يضع مستخدمي قارئ الشاشة الذين يميلون للتنقل بشكل متسلسل في حيرة والتباس. يجب تجنب وضع التركيز على العناصر التي لا يتفاعل المستخدم معها كالترويسات headings مثلًا. يلجأ بعض المطورين إلى إدراج خاصية ترتيب الجدولة tabindex في الترويسات ظنًا منهم أنها مهمة. يُعدّ هذا السلوك سلوكًا غير شائعًا مما يُقلل من كفاءة الاستخدام عمومًا. أما بالنسبة لمستخدمي قارئ الشاشة يكون التركيز على الترويسات غير ضروري لأن قارئ الشاشة يقرؤها. يجب التأكد من توجيه تركيز المستخدم إلى المحتوى الجديد المُضاف للصفحة كي يتمكن المستخدم من التفاعل معه. يُمكن مراجعة فقرة إدارة التركيز على مستوى الصفحة من المقالة المشار إليها سلفًا، والمعنونة بالتركيز على عناصر صفحة الويب لمزيد من الأمثلة. يجب تجنب قفل التركيز في أي نقطة. قد تؤدي عناصر الإكمال التلقائي autocomplete widgets لقفل التركيز باستخدام لوحة المفاتيح. يُمكن قفل التركيز في بعض الحالات المُحدّدة مثل إظهار نافذة شرطية modal والرغبة بمنع المستخدم من التعامل مع بقية عناصر الصفحة مع الاحتفاظ بإمكانية إغلاق هذه النافذة الشرطية باستخدام لوحة المفاتيح. إمكانية التركيز لا تعني إمكانية الاستخدام يجب على المطور عند إنشاء عنصر تحكم مُخصّص التأكد من وصول مستخدم لوحة المفاتيح لجميع وظائف هذا العنصر. المحتوى خارج الشاشة تحوي العديد من المواقع على محتوى مخفي موجود في شجرة DOM، كحالة الروابط الموجودة داخل قائمة تظهر استجابًة لفعل مستخدم ما responsive drawer menu أو زر داخل نافذة شرطية لم يأتِ بعد وجوب عرضه. يؤدي ترك هذه العناصر في شجرة DOM إلى إرباك مستخدم لوحة المفاتيح لا سيما أن قارئ الشاشة سيقرأ هذه العناصر كما لو أنها جزءًا من الصفحة. يُمكن مراجعة فقرة أهمية ترتيب العناصر في شجرة DOM من مقالة التركيز على عناصر صفحة الويب، للحصول على إرشادات التعامل مع هذه العناصر. اختبار الصفحة مع قارئ الشاشة يؤدي تحسين دعم لوحة المفاتيح إلى وضع أساسيات الخطوة التالية وهي التحقق من احتواء الصفحة على العناوين labels والدلالات المناسبة وعدم وجود أي عوائق أمام تنقل قارئ الشاشة ضمن الصفحة. النقاط الأساسية يجب أن تراعى النقاط الأساسية التالية: يجب التحقق من أن لجميع الصور الخاصية alt لتوفير النص البديل لها عند الحاجة. يُمكن استثناء الصور التي توضع بهدف العرض فقط ولا تكون جزءًا أساسيًا من المحتوى. يجب إسناد السلسلة الفارغة ""=alt لإعلام قارئ الشاشة بوجوب تخطي صورة. يجب التحقق من توفير عناوين labels لجميع عناصر التحكم. يُمكن أن يتطلب ذلك استخدام الخاصيتين aria-label و aria-labelledby للعناصر المخصصة. للمزيد من التفاصيل يُمكن العودة إلى العناوين والعلاقات في ARIA. يجب التحقق من أن لجميع عناصر التحكم الدور role المناسب وخصائص ARIA المطلوبة لضبط حالتها. مثلًا: يحتاج مربع الاختيار المخصص إلى الدور "role="checkbox وإلى الخاصية "aria-checked="true|false للإعلام عن حالة العنصر بشكل صحيح. يجب التحقق من التسلسل المنطقي للانتقال بين عناصر الصفحة. بما أن برامج قراءة الشاشة تنتقل في الصفحة وفق ترتيب شجرة DOM فستؤدي عملية استخدام أنماط CSS لتغيير أماكن توضع العناصر إلى الإعلان عن هذه العناصر وفق تسلسل غير منطقي. يجب على المطور وضع العناصر في شجرة DOM وفق ترتيب الإظهار الذي يرغبه. يجب عدم السماح بإخفاء أي قسم من أقسام الموقع أو حظر وصول قارئ الشاشة إليه بشكل دائم إذا كان دعم تنقل قارئ الشاشة في كل محتوى الصفحة مطلوبًا. يجب التأكد من إسناد القيمة true إلى الخاصية aria-hidden إذا كان المطلوب إخفاء محتوى ما عن قارئ الشاشة كأن يكون خارج الشاشة أو عبارة عن شيئٍ للعرض فقط. التعرف على قارئ شاشة واحد يُساعد في فهم المسائل والمشاكل قد يبدو تعلم استخدام قارئ الشاشة للوهلة الأولى أمرًا صعبًا، إلا أنه عملية سهلة في الواقع إذ يُمكن للمطورين التعامل معه باستخدام بضعة أوامر من لوحة المفاتيح. يُمكن استخدام قارئ الشاشة VoiceOver الذي يتوفر في أنظمة Mac OS.كما يُمكن لمستخدمي النظام Windows مشاهدة هذا الفيديو عن قارئ الشاشة NVDA والذي هو برنامج مفتوح المصدر مدعوم بالتبرعات. لا تمنع الخاصية aria-hidden التركيز باستخدام لوحة المفاتيح يجب أن نتذكر أن خصائص ARIA تؤثر على دلالات العناصر فقط وليس على سلوكها. يُمكن إخفاء عنصر عن قارئ الشاشة باستخدام hidden=true إلا أن هذا لن يغير من سلوك التركيز على العنصر. أما بالنسبة للمحتوى التفاعلي الموجود خارج الصفحة فنحتاج غالبًا للجمع بين aria-hidden=true و "tabindex=”-1 للتأكد من إزالة العنصر من تسلسل استخدام لوحة المفاتيح. تهدف السمة الجديدة المقترحة inert إلى تسهيل ذلك بالجمع بين سلوك كلتا الخاصيتين. الإشارة إلى حالة العناصر التفاعلية مثل الروابط والأزرار والهدف منها يُسهّل عرض التلميحات hints المرئية للعناصر التفاعل والتنقل في الموقع. تُدعى هذه التلميحات بالإمكانات affordances والتي تُساعد الأشخاص على تصفح الموقع باستخدام مجموعة متنوعة من الأجهزة. النقاط الأساسية تراعى النقاط الأساسية التالية: يجب أن تكون العناصر التفاعلية، مثل الروابط والأزرار، قابلة للتمييز بوضوح عن العناصر غير التفاعلية. إذ يصعُب على المستخدمين التنقل في موقع أو تطبيق عندما لا يتمكنون من معرفة فيما إذا كان العنصر قابلاً للنقر أم لا. هناك العديد من الطرق الصحيحة لتحقيق هذا الهدف. إحدى الممارسات الشائعة هي وضع خط تحت الروابط لتمييزها عن النص المحيط بها. على غرار متطلبات التركيز، تتطلب العناصر التفاعلية مثل الروابط والأزرار حالة حومان hover لمستخدمي الفأرة كي يدركوا أنهم يحركون الفأرة فوق شيء يُمكن النقر عليه. علاوًة على ذلك، يجب أن يكون العنصر التفاعلي مميزًا بنفسه. إذ لا يُساعد الاعتماد على حالة الحومان وحدها للإشارة إلى العناصر القابلة للنقر على الشاشات التي تعمل باللمس. الاستفادة من الترويسات والعلامات تُعطي العناوين Headings والعلامات landmarks بنية دلالية للصفحة، وتزيد من كفاءة التنقل لمستخدمي التقنية المساعدة بشكل كبير. أفاد العديد من مستخدمي برامج قراءة الشاشة أنهم عندما يصلون إلى صفحة غير مألوفة لأول مرة فإنهم يحاولون التنقل عن طريق الترويسات عادةً. وبالمثل، توفر برامج قراءة الشاشة أيضًا القدرة على الانتقال إلى علامات مهمة مثل <main> و <nav>. لذا فمن المهم دراسة كيفية استخدام بنية الصفحة لتوجيه تجربة الاستخدام. النقاط الأساسية تراعى النقاط الأساسية التالية: يجب استخدام التسلسل الهرمي للترويسات h1-h6 بالشكل المناسب والتفكير بالترويسات كأدوات لإنشاء مخطط outline الصفحة. يجب عدم ترك الترويسات بالأنماط المبنية مسبقًا لها بل يجب الآخذ بعين الاعتبار فيما لو كانت جميع الترويسات بنفس الحجم واستخدام المستوى المناسب دلاليًا للمستوى الأول والثاني والثالث. وفي النهاية استخدام أنماط CSS لجعل الترويسات تتماشى مع تصميم الصفحة. يجب استخدام عناصر العلامات landmarks والأدوار roles لتمكين المستخدمين من تجاوز المحتوى المكرر. توفر العديد من التقنيات المساعدة الاختصارات shortcuts اللازمة للانتقال إلى أقسام محدّدة من الصفحة مثل الأقسام المُعرّفة باستخدام العناصر <main> أو <nav> والتي تلعب دور علامات ضمنية. يُمكن استخدام خاصية الدور role في ARIA لتعريف المناطق بشكل صريح في الصفحة مثلًا: <"div role="search>. يُمكن العودة لفقرة الدلالات والتنقل في المحتوى للمزيد من الأمثلة. يجب على المطور تجنب استخدام الخاصية role مع القيمة application إلا في حال تمتعه بالخبرة السابقة في العمل معها. إذ يؤدي هذا الاستخدام إلى إعلام التقنية المساعدة بتعطيل جميع اختصاراتها shortcuts وتمرير جميع ضغطات المفاتيح إلى الصفحة، مما يعني أن مفاتيح قارئ الشاشة التي يستعملها المستخدمون عادةً للتنقل في الصفحة لن تعمل بعد الآن، وسيحتاج المطور إلى معالجة جميع أحداث لوحة المفاتيح بنفسه. استخدام قارئ الشاشة للتحقق السريع من الترويسات والعلامات توفر برامج قراءة الشاشة مثل VoiceOver و NVDA قائمة سياقية context menu تسمح بالوصول السريع للمناطق الهامة في الصفحة. يُمكن استخدام هذه القوائم للحصول على نظرة عامة سريعة على الصفحة وتحديد ما إذا كانت مستويات الترويسات مناسبة وما هي العلامات المستخدمة. راجع مقاطع الفيديو التعليمية هذه حول أساسيات VoiceOver و NVDA. أتمتة العملية يمكن أن يكون التحقق من سهولة الوصول أمرًا شاقًا وعرضة للخطأ. ولذا يكون من الأفضل أتمتة هذه العملية في نهاية المطاف. يمكن القيام بذلك من خلال استخدام ملحقات extensions المستعرض وأدوات اختبار سهولة الوصول باستخدام سطر الأوامر. النقاط الأساسية يمكنك اتباع الخطوات التالية: يُمكن التحقق من اجتياز الصفحة لجميع الاختبارات باستخدام إضافات المتصفح aXe أو WAVE. هذه الإضافات ليست سوى خيارين متاحين ويمكن أن تكون إضافة مفيدة لأي عملية اختبار يدوي حيث تستطيع التعرف على المشكلات الدقيقة بسرعة مثل فشل نسب التباين failing contrast ratios وخصائص ARIA المفقودة. يُمكن استخدام سطر الأوامر واستخدام ax-cli الذي يوفر نفس الوظائف التي يوفرها امتداد المتصفح aXe، ولكن يمكن تشغيله بسهولة من الطرفية. يُمكن تضمين مكتبة برمجية مثل axe-core لمجموعة الاختبار المؤتمتة وذلك لضمان تجانس الاختبارات وتكاملها لا سيما في بيئة عمل تكاملي مستمر. وهي المكتبة نفسها التي تدعم الامتداد aXe إلا أنها أسهل للاستخدام عن طريق سطر الأوامر. في حال استخدام إطار عمل أو مكتبة فيُمكن أن يُطرح السؤال: هل توفر أدوات سهولة الوصول الخاصة بها؟ تتضمن بعض الأمثلة استخدام المكتبة البرمجية protractor-accessibility-plugin في Angular و a11ysuite في Polymer و Web Components. يجب دومًا الاستفادة من الأدوات المتاحة كلما أمكن ذلك تجنبًا لإعادة اختراع الدولاب. استخدام الأداة Lighthouse عند تطوير صفحات الويب التقدميّة تُساعد الأداة Lighthouse في قياس أداء تطبيق الويب التقدمي وتستخدم أيضًا المكتبة ax-core لتشغيل مجموعة من اختبارات سهولة الوصول. يُمكّن استخدام هذه الأداة في تحديد حالات فشل الوصول والتي يُساهم إصلاحها في تحسين تجربة المستخدم الإجمالية للموقع. النتيجة يجب إدراج عمليات التحقق من سهولة الوصول كجزء أساسي في خطة التطوير ويجب إجراء هذه العمليات مبكرًا وبشكل دوري، مما يُساهم في تحسين تجارب الاستخدام للموقع، كما يجب أن لا ننسى أن الوصول السهل يعني تجربة استخدام جيدة! ترجمة -وبتصرف- للمقالة How To Do an Accessibility Review للمؤلف Rob Dodson. اقرأ أيضًا سهولة وصول جميع الزوار لمواقع وتطبيقات الويب النسخة الكاملة من كتاب نحو فهم أعمق لتقنيات HTML5
-
عرضنا في مقالة سابقة مسائل سهولة الوصول أو ما نطلق عليها بالشمولية (شمل مختلف المستخدمين والزائرين سواء كانت لديهم مشاكل وإعاقات أم لا) وإتاحة جميع عمليات التفاعل مع صفحات الموقع باستخدام لوحة المفاتيح فقط، لاسيما للأشخاص الذين لا يستخدمون الفأرة أو أجهزة التأشير لأسباب متعددة مثل الإعاقات الجسدية أو بسبب مشكلة تقنية أو لمجرد تفضيلاتهم الشخصية. لا يتطلب تحقيق هذه السهولة الكثير من الجهد والوقت فيما لو خُطّط لها بشكل صحيح منذ البداية. مع التنويه إلى أن تحقيق هذه السهولة يُفضي في نهاية المطاف إلى صفحات سهلة الوصول وجذابًة للمستخدمين. نبدأ أولًا، في هذه المقالة، بعرض بعض المعلومات الأساسية عن التقنية المساعدة assistive technology وهو المصطلح المُستخدم للإشارة إلى الأدوات المساعدة، كقارئ الشاشة مثلًا، للأشخاص الذين يعانون من إعاقات تمنعهم من الوصول للمعلومات بشكل اعتيادي. ننتقل بعد ذلك لعرض بعض تجارب الاستخدام العامة، ونتعمق بعدها في تجارب مستخدمي التقنيات المساعدة. وفي النهاية، نعرض كيفية استخدام لغة HTML بفعالية لتحقيق تجربة استخدام لهؤلاء المستخدمين وكيفية تداخل ذلك مع مسألة التركيز التي تعرضنا لها في مقالة سابقة. التقنية المساعدة يشمل مصطلح التقنية المساعدة جميع الأجهزة والبرمجيات والأدوات التي تُساعد أي شخص يعاني من إعاقة ما من إكمال مهمة معينة بنجاح. بشكل عام، يُمكن أن تكون الأداة شيئًا بسيطًا مثل عكاز المشي أو عدسة التكبير للقراءة، أو شيئًا ذو تقنية عالية مثل ذراع جسمال robot أو برنامج التعرف على الصور في هاتف ذكي. يُمكن أن تتضمن التقنية المساعدة شيئًا عامًا مثل تكبير/تصغير zoom المتصفح، أو خاصًا مثل وحدة تحكم مصممة خصيصًا للألعاب. كما يُمكن أن تكون جهازًا منفصلًا مثل شاشة برايل braille display (للكفيف) أو مُضمّنه بشكل كامل في برنامج ما مثل التحكم بالصوت. كما يُمكن أن تكون التقنية المساعدة مبنية مسبقًا built-in في نظام التشغيل، أو عبارة عن إضافة add-on ما مثل امتدادات المتصفح Chrome. لا يُمكن الفصل بين التقنية عمومًا والتقنية المساعدة بشكل واضح، إذ تهدف التقنية بجميع أشكالها، في النهاية، إلى مساعدة الناس للقيام بمهامهم. يُمكن لنفس التقنية أن تُعدّ أحيانًا ضمن فئة التقنية المساعدة وأحيانًا خارجها. مثلًا: كانت الآلة الحاسبة الناطقة للمكفوفين من أقدم المنتجات التجارية لتركيب الكلام. أما اليوم، فقد أصبح تركيب الكلام موجودًا في كل مكان: بدءًا من برمجيات توجيه الاتجاهات driving directions إلى المساعدين الافتراضيين virtual assistants. على النقيض من ذلك، نجد اليوم العديد من التقنيات العامة تُستخدم لأغراض مساعدة مثل استخدام ضعاف البصر زوم zoom كاميرا هواتفهم الذكية لإلقاء نظرة أفضل على شيء صغير في العالم الحقيقي. يجب أن يأخذ مطور صفحات الويب بعين الاعتبار مجموعة متنوعة من التقنيات الممكنة. إذ قد يتفاعل الأشخاص مع موقع الويب باستخدام قارئ الشاشة screen reader أو عارض برايل braille display أو مكبر الشاشة screen magnifier أو متحكم الصوت voice control أو جهاز تبديل switch device أو أي شكل آخر من أشكال التقنيات المساعدة والتي تُكيّف واجهات الصفحات الافتراضية لإنشاء واجهات مُخصصة يُمكن استخدامها من قبل هؤلاء الأشخاص مع اختلاف أدوات الوصول المستخدمة. تعتمد العديد من هذه التقنيات المساعدة على الدلالات المُعبّر عنها برمجيًا programmatically expressed semantics لإنشاء تجربة استخدام سهلة الوصول. نتطرق أولًا إلى الإمكانات affordances قبل شرح الدلالات المعبر عنها برمجيًا. الإمكانات الدالة على كيفية الاستخدام يُمكن لنا، في أغلب الأحيان، بمجرد النظر على شكل أداة أو جهاز أن نُكوّن فكرة عن عمل هذا الجهاز وكيفية استخدامه. يُساهم التصميم الجيد للإمكانات Affordances (المهام المعينة التي توفرها الأغراض المختلفة) في توضيح آلية استخدامها للعموم بسهولة. مثلًا يُدرك أي شخص بمجرد النظر لغلاية ماء أو إبريق شاي أن الإبريق يُحمل من مقبضه وليس من فوهته حتى لو كانت المرة الأولى التي يرى فيها إبريق الشاي. يُمكن تفسير ذلك بأن الإمكانات المُقدّمة من الإبريق تُشابه الإمكانات المُقدّمة من أغراض أخرى شبيهة به مثل أواني الري وأباريق المشروبات وأكواب القهوة وغيرها. بالطبع، يُمكنك مسك الإبريق من فوهته إلا أن تجارب المستخدم السابقة مع أغراض أخرى شبيهة بالإبريق تؤكد له بأن المقبض هو الخيار الأنسب. بشكل مماثل، تُعدّ إمكانات واجهات المستخدم البيانية الإجراءات التي يُمكن للمستخدم القيام بها، إلا أن هذه الإجراءات يُمكن أن تكون غامضة نظرًا لعدم وجود أي كائن مادي للتفاعل معه. تُصمّم واجهات المستخدم البيانية لتكون إمكاناتها واضحة دون أي لبس فيها باستخدام الأزرار buttons ومربعات الاختيار check boxes وأشرطة التمرير scrol bars بحيث يكون استخدامها واضحًا دون الحاجة لتدريب طويل للتعامل معها. مثلًا، يُمكن التعبير عن بعض عناصر التحكم الشائعة (إمكانات العناصر) كما يلي: أزرار الانتقاء Radio buttons "يُمكن انتقاء واحدًا من الخيارات المتاحة". مربع الاختيار Check box "يُمكن اختيار نعم أو لا من هذا الخيار". حقل نصي Text field "يُمكن كتابة أي نص في هذه المساحة". قائمة منسدلة Dropdown "يُمكن فتح هذا العنصر لعرض الخيارات المتاحة". يُمكن الوصول للاستنتاجات السابقة حول عناصر التحكم بمجرد رؤيتها، إلا أن السؤال المطروح هو: ما وضع الشخص غير القادر على رؤية هذه العناصر وبالتالي لا يستطيع إدراك إمكاناتها بديهيًا؟. يجب على المطور إذًا التأكد من التعبير عن المعلومات بمرونة كافية للوصول إليها باستخدام التقنية المساعدة والتي يُمكن لها إنشاء واجهة بديلة لتناسب احتياجات المستخدم الخاصة. يُدعى هذا العرض غير المرئي من إمكانات الاستخدام بالدلالات semantics. قارئ الشاشة يُعدّ قارئ الشاشة screen reader من أكثر التقنيات المساعدة شيوعًا، وهو عبارة عن برنامج يقرأ النص المكتوب على الشاشة بصوتٍ عالٍ مُولدٍ تلقائيًا مما يُمكّن الأشخاص ذوي الإعاقة البصرية من استخدام الحواسيب. يُمكن مشاهدة هذا الفيديو لفيكتور تساران (الكفيف ومدير البرنامج الفني في شركة Google) وهو يتصفح الويب باستخدام قارئ الشاشة المدعو VoiceOver في نظام التشغيل OS X. لمعايشة تجربة الكفيف الفعلية مع قارئ الشاشة، يُمكن القيام بالتمرين التالي: فتح صفحة الويب التالية (باستخدام المتصفح Chrome) ChromeVox lite demo page والتي هي عبارة عن صفحة بسيطة مكتوبة بلغة جافا سكريبت تُخفى النصوص فيها لمحاكاة تجربة ضعف البصر ولإرغام المستخدم على استخدام قارئ الشاشة. يُمكن استخدام لوحة التحكم الموجودة أسفل الشاشة للتحكم في قارئ الشاشة والذي يحتوي على الحد الأدنى من الوظائف الضرورية. يتم التنقل في المحتوى باستخدام الزرين السابق Previous والتالي Next، كما يُمكن النقر على أي شيء باستخدام الزر Click. تُستخدم الصفحة السابقة بعد تمكين ChromeVox lite لاستخدام قارئ الشاشة. وفي الحقيقة، يوفر قارئ الشاشة (أو أي تقنية مساعدة أخرى) تجربة استخدام بديلة كاملة اعتمادًا على الدلالات المُعبّر عنها برمجيًا. فعوضًا عن الواجهة المرئية، يوفر قارئ الشاشة واجهة مسموعة. يُعلَم قارئ الشاشة ببعض المعلومات حول كل عنصر من عناصر الواجهة. يجب أن نتوقع من قارئ شاشة مصمم جيدًا أن يُخبر المستخدم بجميع، أو على الأقل بمعظم، المعلومات التالية حول عناصر الواجهة: دور العنصر role أو نوعه type، إذا كان موصّفًا (يجب أن يكون). اسم العنصر name، إذا كان له اسم (يجب). قيمة العنصر value، إذا كان له قيمة (قد تكون أو لا تكون). حالة العنصر state، مثلًا: فيما إذا كان مُمكّنًا أو معطلاً (إن أمكن). يستطيع قارئ الشاشة إنشاء واجهة المستخدم البديلة لأن العناصر الأصلية native تحوي مسبقًا بيانات تعريف إمكانية الوصول. كما يستخدم المتصفح الشيفرة الأساسية native code لإظهار الواجهة الرسومية يستخدم قارئ الشاشة البيانات الوصفية metadata في عقد شجرة DOM لإنشاء إصدار سهل الوصول كما يُبين المثال التالي: شجرة الوصول لا نحتاج إلى إنشاء أي واجهة مرئية على الإطلاق في حال أردنا إنشاء واجهات لمستخدمي قارئ الشاشة فقط، وإنما يجب توفير المعلومات الكافية لقارئ الشاشة ليُنشئ الواجهة المسموعة الموافقة لاحتياجات هؤلاء المستخدمين. أي أنه يجب إنشاء نوع من واجهات برمجة التطبيقات API تصف بنية صفحة الويب على غرار DOM API مع معلومات وعقد أقل مما تحتاجه الواجهة المرئية. يُبين الشكل التالي مثالًا: يُظهر المثال السابق ما يُمكن أن يُقدّم المتصفح لقارئ الشاشة. يٌعدّل المتصفح شجرة DOM إلى شكل قابل للاستخدام من قبل التقنية المساعدة. ندعو الشجرة المُعدّلة بشجرة الوصول Accessibility Tree. يُمكن تشبيه شجرة الوصول بصفحة ويب قديمة من التسعينيات مع بضعة صور والكثير من الروابط مع حقل وزر كما يُظهر الشكل التالي: يُمكن التمعن في صفحة الشكل السابق لتخيل تجربة مماثلة لما سيحصل عليه قارئ الشاشة، ومع ملاحظة بساطة الصفحة إلا أنها تُشبه إلى حدّ كبير شجرة الوصول. تتفاعل معظم التقنيات المساعدة مع شجرة الوصول، ويكون التدفق شبيهًا بما يلي: يُقدّم التطبيق (المتصفح أو أي تطبيق آخر) إصدارًا دلاليًا من واجهة المستخدم إلى التقنية المساعدة عبر واجهة برمجة تطبيقات معينة API. تستخدم التقنية المساعدة المعلومات التي تصلها عبر واجهة برمجة التطبيقات لإنشاء عرضًا بديلًا لواجهة المستخدم. مثلًا: يُنشئ قارئ الشاشة واجهة يسمع فيها المستخدم تمثيلًا منطوقًا للتطبيق. يُمكن أن تسمح التقنية المساعدة للمستخدم بالتفاعل مع التطبيق بطرق مختلفة. مثلًا: توفر معظم قارئات الشاشة إمكانية محاكاة النقر بالفأرة أو بالإصبع. تُخبر التقنية المساعدة التطبيق برغبة المستخدم القيام بإجراء ما (مثل "النقر") عبر واجهة برمجة التطبيقات. يتحمل التطبيق بعد ذلك مسؤولية تفسير الإجراء بشكل مناسب ضمن واجهة المستخدم . أما مع متصفح الويب (منصة تشغيل تطبيق الويب)، فسيكون هنالك خطوة إضافية في كل اتجاه لأن المتصفح يحتاج لترجمة تطبيق الويب إلى شجرة وصول والتأكد من إطلاق الأحداث events المناسبة في جافا سكريبت والموافقة لأفعال المستخدم والتي تُمرر للمتصفح من التقنية المساعدة. يجب على مطور الويب التأكد من السلوك السابق (والذي هو من مسؤولية المتصفح) وتطوير صفحات ويب تستفيد من هذا السلوك لإنشاء تجارب استخدام سهلة الوصول. لتحقيق الهدف السابق (سهولة الوصول)، يجب التأكد من التعبير عن دلالات الصفحات بشكل صحيح مثل: التأكد من سهولة الوصول لأدوار roles وحالات states وخصائص properties جميع العناصر الهامة، مع تحديد أسماء هذه العناصر ووصفها. وبالتالي يُمكن للمتصفح بعد ذلك السماح للتقنية المساعدة بالوصول إلى هذه المعلومات لإنشاء تجربة مخصصة. الدلالات في عناصر لغة HTML الأساسية يُمكن للمتصفح تحويل شجرة DOM إلى شجرة الوصول لأن لمعظم عناصر HTML دلالة ضمنية. تستخدم شجرة DOM عناصر HTML الأساسية والتي تعمل بشكل قياسي موحد على مختلف المنصات. تُعالَج مسألة الوصول للعناصر الأساسية مثل الروابط والأزرار تلقائيًا. يُمكن الاستفادة من الدلالات المبنية مسبقًا built-in بكتابة تعليمات HTML التي تٌعبّر عن دلالات عناصر الصفحة. يُمكن أن يستخدم المطور أحيانًا عناصر شبيهة بالعناصر الأساسية إلا أنها ليست كذلك. مثلًا العنصر الشبيه بالزر في الصورة التالية ليس زرًا على الإطلاق: يُمكن إنشاء العنصر السابق في HTML بعدة طرق مثلًا: <div class="button-ish">Give me tacos</div> لن يتمكن قارئ الشاشة من التعرف على العنصر السابق (ليس زرًا) عند الوصول إليه. كما يجب إضافة خاصية ترتيب الجدولة tabindex للعنصر السابق ليتمكن مستخدمو لوحة المفاتيح من الوصول إليه إذ لا يُمكن الوصول إليه (كما هو مُصمم حاليًا) إلا عن طريق الفأرة. يُمكن تجاوز المشكلة السابقة باستخدام عنصر زر عادي عوضًا عن div. يوفر استخدام عنصر أصلي للمطور معالجة مسائل الوصول باستخدام لوحة المفاتيح إذ يُعالجها العنصر الأصلي بمفرده. لا يجب التردد في استخدام العناصر الأصلية بحجة مظهرها البسيط الأساسي إذ يُمكن للمطور إضافة المظهر المرئي المناسب لها مع حفاظها على دلالاتها الضمنية وسلوكها الاعتيادي. لاحظنا سابقًا أن قارئ الشاشة يُعلن عن دور العنصر واسمه وحالته وقيمته. يسمح استخدام الدلالات الصحيحة بالوصول إلى الدور والحالة والقيمة إلا أنه يجب التأكد من سهولة العثور على اسم العنصر. يوجد عمليًا نوعين من الأسماء: العناوين المرئية Visible labels والتي يربط المستخدمون من خلالها المعنى بالعنصر. البدائل النصية Text alternatives والتي تُستخدم عندما لا يكون هنالك حاجة لتسمية مرئية. لا نحتاج لعمل أي شيء مع العناصر النصية لأن محتواها النصي يُعرّف عنها، أما بالنسبة لبقية عناصر التحكم أو الإدخال أو العناصر ذات المحتوى المرئي، كالصور مثلًا، فيجب التأكد من وجود اسمها. عمليًا، يكون التحقق من الاسم على رأس قائمة التحقق من سهولة الوصول المعتمدّة من قبل المنظمة WebAIM (منظمة غير ربحية تُعنى بتقديم حلول سهولة الوصول منذ عام 1999). من الطرق المستخدمة اتباع التوصية: "يجب أن يكون لجميع عناصر الإدخال في النموذج عناوين نصية". يوجد طريقتين لربط عنوان label مع عنصر على النموذج مثل مربع الاختيار، تؤدي كل منهما إلى جعل نص التسمية هدفًا لنقر مربع الاختيار والذي يكون مساعدًا أيضًا لمستخدمي الفأرة أو شاشة اللمس. يُمكن لربط عنوان مع عنصر إما: وضع عنصر الإدخال داخل عنصر عنوان كما تُبين الشيفرة التالية: <label> <input type="checkbox">Receive promotional offers? </label> حيث يكون مظهر مربع الاختيار مع إمكانية النقر على العنوان أو على مربع الاختيار لاختيار/إزالة الاختيار من مربع الاختيار: أو: استخدام الخاصية for لعنصر العنوان مع إسناد مُعرّف مربع الاختيار لها كما توضح الشيفرة التالية: <input id="promo" type="checkbox"> <label for="promo">Receive promotional offers?</label> يُمكن لقارئ الشاشة إظهار المعلومات التالية عندما يكون مربع الاختيار معنونًا بشكل صحيح: العنصر هو مربع اختيار بحالة الاختيار ويُدعى "Receive promotional offers?" كما يُبين الشكل التالي: يُمكن استخدام قارئ الشاشة للعثور على التسميات غير المرتبطة مع العناصر بشكل صحيح عن طريق التنقل عبر الصفحة باستخدام مفتاح الجدولة tab والتحقق من الأدوار والحالات والأسماء المنطوقة. النصوص البديلة للصور تُعدّ الصور من أهم مكونات صفحات الويب، وهي بالطبع نقطة شائكة خاصًة للمستخدمين ضعاف البصر. ولذا يجب الآخذ بعين الاعتبار لدور الصورة في الصفحة عند تحديد النص البديل لها. لنعاين الصورة التالية مثلًا: <article> <h2>Study shows 9 out of 10 cats quietly judging their owners as they sleep</h2> <img src="imgs/160204193356-01-cat-500.jpg"> </article> تظهر صورة قطة في الصفحة في مقال عن سلوك القطط المعروف في حكمهم على الآخرين. يقوم قارئ الشاشة في هذا المثال بنطق اسم الصورة "/160204193356-01-cat-500.jpg" بشكل صحيح إلا أن هذا غير مفيد للمستخدم على الإطلاق. يُمكن استخدام الخاصية alt لتوفير نص بديل ذو معنى مفيد لهذه الصورة مثل "قطه تُحدّق في الفضاء بشكل متوعد" <img src="/160204193356-01-cat-500.jpg" alt="A cat staring menacingly off into space"> يُظهر قارئ الشاشة الوصف الموجز للصورة في الشريط الأسود VoiceOver، ويُمكن للمستخدم بعدها اختيار الانتقال للمقالة. يُمكن أن نشير إلى الملاحظتين التاليتين عن الخاصية alt: تسمح الخاصية alt بتحديد نص بسيط لعرضه في أي وقت لا تكون فيه الصورة متاحة، مثل حالة الفشل في تحميلها أو التعامل معها من قبل زاحف الويب crawler أو المرور عليها من قبل قارئ الشاشة. تختلف الخاصية alt عن خاصية العنوان title أو أي نوع من التسميات التوضيحية في أنها تُستخدم فقط عند تعذر توفير الصورة للمستخدم. تُعدّ كتابة نصًا بديلًا مفيدًا عملًا فنيًا إذ يجب أن يعكس النص مفهوم الصورة بشكل واضح وضمن سياق استخدامها. يُمكن مثلًا وضع النص البديل المناسب التالي لصورة شعار موقع الصفحة السابقة The Funion logo. <img class="logo" src="logo.jpg" alt="The Funion logo"> قد يكون إعطاء الشعار نصًا بديًلا بسيطًا مثل "الصفحة الرئيسية" أمرًا جاذبًا أكثر للمطور (لأن الشعار موضوع في الصفحة الرئيسة) إلا أن هذا قد يُربك كلًا من ضعاف البصر وجيدي النظر على وجه السواء. تؤدي القيمة "الصفحة الرئيسية" إلى إرباك مستخدم قارئ الشاشة الذي يريد تحديد موقع الشعار الموجود في رأس الصفحة، كذلك سيواجه المستخدم المبصر نفس السؤال: ماذا يؤدي النقر على الشعار؟ وبالمقابل، لا يكون مفيدًا دومًا وصف الصورة. لنأخذ مثلًا حالة صورة العدسة المكبرة التي توضع داخل زر البحث الذي له النص "بحث". بالتأكيد لو لم يكن النص موجودًا، لكان من المفيد إعطاء الخاصية alt للصورة القيمة "بحث" إلا أنه مع وجود النص سيقرأ قارئ الشاشة هذا النص بصوتٍ عالٍ وسيكون من التكرار قراءة قيمة الخاصية alt للصورة. يؤدي عدم وضع قيمة للخاصية alt للصورة إلى قراءة اسم الملف من قبل قارئ الشاشة في أغلب الأحيان، والذي يكون أمرًا مربكًا وغير مفيد. يُمكن اللجوء في مثل هكذا حالات إلى وضع قيمة فارغة للخاصية alt وبالتالي سيتخطى قارئ الشاشة الصورة بشكل كامل. <img src="magnifying-glass.jpg" alt=""> والخلاصة، يجب أن تحتوي جميع الصور على الخاصية alt، إلا أنه ليس بالضرورة أن تكون قيمتها نصًا. إذ يجب أن تحتوي الصور الهامة على نص بديل يصف الصورة بإيجاز، أما الصور الموضوعة بهدف الزخرفة فقط، فيجب وضع قيمة فارغة للخاصية alt أي alt="" الدلالات والتنقل في المحتوى تعرفنا فيما سبق على الإمكانات والدلالات وكيفية استخدام التقنيات المساعدة لشجرة الوصول بهدف إنشاء تجربة استخدام بديلة لمستخدمي هذه التقنيات. يُمكن تحقيق سهولة الوصول بجهد بسيط في حال كتابة عناصر HTML بطريقة مُعبرّة عن دلالاتها إذ يوفر الكثير من عناصر HTML الدلالات والسلوك الداعم المطلوب بشكل مبني مسبقًا built-in. نعرض فيما يلي بعض الدلالات الأقل وضوحًا والتي تُعدّ هامة جدًا لمستخدمي قارئ الشاشة لا سيما مسائل التنقل في محتوى الصفحات. من السهولة معاينة صفحة مليئة بعناصر التحكم والعثور بسرعة على المطلوب إلا أنه سيكون من الأصعب قراءة محتوى الصفحات الزاخرة بالمحتوى مثل صفحات الويكيبيديا وصفحات الأخبار من الأعلى للأسفل، وهنا تبرز الحاجة الماسة لطرق تنقل في المحتوى بفعالية أكبر. يحمل مطوري الويب بعض الأفكار الخاطئة حول برامج قراءة الشاشة بأنها مملة وبطيئة وأن كل شيء موجود على الشاشة يجب أن يتمكن المستخدم من وضع التركيز عليه. هذا ليس هو الحال في الكثير من الأحيان. يعتمد مستخدمو قارئ الشاشة على قائمة الترويسات headings لتحديد موقع المعلومات في أغلب الأحيان. كما تمتلك معظم برامج قراءة الشاشة طرقًا سهلة لإيجاد قائمة ترويسات الصفحة وهي ميزة هامة تُدعى الدوّار rotor. نعرض فيما يلي كيفية استخدام العناوين في HTML بشكل فعّال لدعم هذه الميزة. استخدام العناوين بفعالية نُعيد التذكير أولًا بأن ترتيب العناصر في شجرة DOM أمرًا هامًا سواءً بالنسبة لترتيب التركيز focus أو بالنسبة لترتيب قارئ الشاشة. يُمكن باستخدام برامج قراءة الشاشة مثل VoiceOver و NVDA و JAWS و ChromeVox استنتاج أن قائمة الترويسات headings list تتبع ترتيب شجرة DOM وليس ترتيب ظهورها على الشاشة. يعود هذا الأمر إلى أن قارئ الشاشة يتعامل مع شجرة الوصول accessibility tree والتي هي بدورها ناتجة عن شجرة DOM أي أن الترتيب المُعتمد من قبل قارئ الشاشة هو ترتيب شجرة DOM في نهاية المطاف. يدّل ذلك على أن تنظيم بنية الترويسات المناسبة أصيح أمرًا هامًا وضروريًا أكثر مما مضى. توضع مستويات الترويسات heading levels، في الصفحات المُنظّمة جيدًا، بشكل هرمي لضمان علاقة أب/ابن بين أقسام المحتوى. تُشير توصيات WebAIM إلى هذه التقنية مرارًا وتكرارًا. نعرض فيما يلي بعض الروابط التي تُشير إلى: استخدام الترميز الدلالي لتعيين العناوين 1.3.1. استخدام العناوين كتقنية لتجاوز كتل المحتوى 2.4.1. بعض التفاصيل حول كتابة عناوين مفيدة 2.4.6. تحديد الأقسام الفردية من المحتوى باستخدام العناوين عندما يكون ذلك مناسبًا 2.4.10 ليس بالضرورة أن تكون كل العناوين مرئية على الشاشة. مثلًا: تضع صفحات الويكيبيديا بعض العناوين عمدًا خارج الشاشة وتُتيحهم فقط لقارئات الشاشة وللتقنيات المساعدة الأخرى. <style> .sr-only { position:absolute; left:-10000px; top:auto; width:1px; height:1px; overflow:hidden; } </style> <h2 class="sr-only">This heading is offscreen.</h2> يُمكن العودة لمقالة المنظمة WebAIM حول المحتوى خارج الشاشة للمزيد من المعلومات. يُمكن، في بعض التطبيقات المعقدة، أن تكون هذه الطريقة جيدة لاستيعاب العناوين عندما لا تتسع المساحة المتاحة لعرضها أو لا يكون لها دورًا هامًا في سياق العرض الحالي. تحذير: من المهم عدم المبالغة في استخدام هذه الطريقة (إخفاء العناوين). يجب الانتباه إلى أن مستخدمي التقنية المساعدة قد يكونوا قادرين أيضًا على رؤية الشاشة بأنفسهم، لذا فإن التركيز فقط على إنشاء محتوى يُناسب "قارئ الشاشة فقط" قد يؤدي في الواقع إلى تدهور تجربة الاستخدام لبعض المستخدمين، كما يُمكن أن يؤدي لكثير من الإرباك أثناء صيانة التطبيق من قبل المطور. خيارات التنقل الأخرى يوجد العديد من العناصر الأخرى التي يُمكن استخدامها للتنقل في الصفحة بما فيها الروابط links وعناصر النموذج controls والعلامات landmarks إضافًة إلى الترويسات. يُمكن لقارئ الصفحة استخدام ميزة الدوّار rotor (طريقة سهلة لتحديد قائمة الترويسات في صفحة) للوصول إلى قائمة روابط في الصفحة. قد تحتوي الصفحة، مثل صفحات الويكيبيديا، على الكثير من الروابط التي غالبًا ما يبحث المستخدم عن تعريف لمصطلح ما ضمنها. يؤدي هذا إلى الاقتصار على زيارة الروابط التي تحوي المصطلح بدلًا من كل ظهور لمصطلح على الصفحة. يُمكن أن تكون هذه الميزة مفيدة في حال عثور قارئ الشاشة على الرابط وكان لنص الرابط معنى واضح. نعرض فيما يلي بعض الممارسات السيئة والتي تُعطي روابط صعبة الوصول: استخدام الروابط <a> دون تحديد قيمة للخاصية href (لاسيما في التطبيقات ذات صفحة واحدة) مما يوقع قارئات الشاشة في مشاكل عديدة. استخدام الأزرار مع الروابط مما يجعل قارئ الشاشة يُعامل المحتوى كرابط ويُهمل وظيفة الزر. يجب في مثل هذه الحالة استبدال الرابط بزر حقيقي واستخدام تنسيق مناسب له. استخدام الصور كمحتوى للروابط. يُمكن في بعض الأحيان أن تكون مثل هذه الصور غير قابلة للاستخدام من قبل قارئ الشاشة. لضمان وصول التقنية المساعدة للرابط يجب التأكد من وضع الخاصية alt للصورة. يجب الانتباه لتوفير نصًا واضحًا يُعطي معلومات مفيدة حول المكان الذي ينقلنا الرابط إليه. مثلًا لا يوفر النص "معرفة المزيد" أو "انقر هنا" أي معلومات دلالية، على خلاف النصوص مثل "تعرّف على المزيد حول التصميم سريع الاستجابة" أو "مشاهدة البرنامج التعليمي" والتي تُساعد برامج قراءة الشاشة في توفير سياق مفيد حول الروابط. يُمكن للدوّار أيضًا استرداد قائمة التحكم في النموذج والتي تُمكّن القراء من البحث عن عناصر مُحدّدة والانتقال إليها مباشرًة. ترتكب برامج قارئات الشاشة العديد من أخطاء التهجئة أو النطق مثل قراءة رقم الهاتف كعدد صحيح كبير أو قراءة النص المكتوب بحروف كبيرة كاختصار أو قراءة اسم "Hsoub" مثل "saub". من حسن الحظ، يعتاد المستخدمون على مثل هذه الأخطاء ويألفونها ويأخذوها بالحسبان. يحاول بعض المطورين توفير النص مُهجًأ صوتيًا لقارئ الشاشة. مثلًا: لنأخذ التهجئة البسيطة التالية: "don't do it" والتي ستُفاقم المشكلة! مثلًا إذا كان المستخدم يستخدم شاشة برايل للعرض فستُكتب الكلمات بشكل غير صحيح مما سيؤدي لمزيد من الالتباس. بما أن قارئات الشاشة تقرأ الكلمات بصوت مرتفع يُمكن ترك الأمر لقارئ النص للتحكم في تجربته وقرار متى يكون ذلك ضروريًا. يُمكن للقارئ استخدام الدوّار rotor لمعاينة قائمة العلامات landmarks list لمساعدته في إيجاد المحتوى الأساسي ومجموعة علامات التنقل navigational landmarks التي توفرها عناصر العلامات في HTML. توفر HTML5 مجموعة من العناصر الجديدة التي يُمكن لها أن تُساعد في تحديد البنية الدلالية للصفحة بما فيها الترويسة header والتذييل footer والتنقل nav والمقال article والقسم section والجزء الرئيسي main والجزء الجانبي aside. توفر هذه العناصر أدلة على هيكلية الصفحة دون فرض أي تصميم مبني مسبقًا (وهو ما يجب فعله باستخدام CSS). تحل هذه العناصر الهيكلية الدلالية مكان كتل div المتعدّدة والمتكررة وتوفر طريقة وصفية أوضح للتعبير عن بنية الصفحة بشكل حدسي سواء للمطورين أو للمتصفحين. ترجمة -وبتصرف- لمجموعة المقالات: Introduction to Semantics The Accessibility Tree Text Alternatives for Images Semantics and Navigating Content للمؤلفين: Meggin Kearney وDave Gash وAlice Boxhall. اقرأ أيضًا تعلم البرمجة المدخل الشامل لتعلم علوم الحاسوب
-
هذا خلاصة التصميم بمساعدة المطور الخاص بك، درس إلكتروني من InVision للكاتب كيفين توماسو. يدور التصميم من أجل التطوير حول إيجاد الحل الذي ينتج أفضل تجربة ممكنة للمستخدم بأقل عدد من الأجزاء المتحركة. لا تنتهي مشاريع تطبيقات الويب في جلسة واحدة؛ فهي تحتاج للنمو، والتطور والتغيير - يفضل بسرعة في بعض الأحيان. ويجب على المصممين عند اتخاذ القرار، وضع كيفية بناء التصميم في الحسبان. فالتصميم الذي يبدو رائعًا للمستخدم ولكنه يتعطل في كل مرة يريد فيها المطور أن يحدث تغييرًا، لا يعد تصميمًا - واجهة جميلة مع مشاكل كامنة خلفها. قد يبدو تصميمك جيدًا من الخارج، ولكن الشيفرة المستخدمة في إنشائه قد تكون في حالة فوضى. إن التصميم بمساعدة المطور يعني العمل ضمن فريق، وليس مجرد إكمال خطوة في الطريق. الهدف النهائي هو إنشاء منتج عظيم ليكون عبارة عن تجميع التصميم مع عملية التطوير. يمكن أن يحسن التصميم مع مدخلات المطور وشيفرة يمكن كتابتها بمساعدة المصمم. العمل معًا وفهم من أين قد جئتما، هو السبيل لتحقيق الأهداف والتغلب على العقبات بشكل كبير. "التصميم بمساعدة المطور يعني العمل ضمن فريق". أيضًا يُعنَى التصميم مع التطوير بمعرفة الأهداف النهائية واتخاذ قرارات صعبة من خلال المعرفة الواسعة بالصورة الكلية. عندما تستطيع النظر للغابة من خلال الأشجار، فإنك تستطيع الوصول إلى وجهتك بشكلٍ أفضل. وفي هذه الحالة تكون الوجهة عبارة عن منتجٍ رائع. ما الذي لا يعبر عن التصميم مع التطوير هذا ليس دعوة أو عذر لانتقاد المطور أو إعطاء تغذية راجعة. ولا يشير أيضًا إلى أن عملهم أهم بأي طريقة. لا يوجد للمنتج مكانًا في حياة المستخدم بدون تصميم، تمامًا كعدم إمكانية وجوده قبل عمل شيفرة له. ما يجذب المستخدمين ويبقيهم في موقعك هو التصميم وتجربة المنتج. فبدون تصميمٍ جيد، ستأمل أفضل المواقع والتطبيقات أن تنجح بغض النظر عن مظهرها (أنا أنظر إليك، كرايجلست). والحقيقة هي أن التصميم يحدث أولًا، ولذلك فإن معرفة الأدوات والتقنيات التي ستستخدم لإخراج تصميمك، تملك تأثيرًا أكبر من التأثير في الحالة العكسية. لا يضيف إعادة تعديل الصور من خلال ضبط levels & curves واستخدام أداة burn في برنامج الفوتوشوب، الكثير للمطور؛ لأنه في الوقت الذي ينتهون فيه منها، سيكون عليهم إضافة الصورة النهائية للموقع. ومن ناحيةٍ أخرى، إذا كنت تعرف أفضل الطرق لحفظ الصورة وتصغير حجم الملف ورفع الأداء، فإن منتجك سيتحسن. يمكنك التفكير بمساعدتهم في إنجاز عملهم بينما تعمل، ولكن العكس لا يعمل دائمًا هنا. أنت هو المصمم. ستكون محط اهتمام الجميع في حال كنت تعرف القليل حول كيفية قيام طاقم البناء بعمله. اتبع هذه الخطوات البسيطة لتصبح مصممًا رائعًا يُعنَى هذا الدرس التعليمي بمساعدتك على التصميم مع وضع التطوير في الذهن. أما بالنسبة لما لم يتم تناوله هنا، فيعني أن عملك الأول والرئيسي هو التصميم مع وضع المستخدمين في الذهن. أنت تعرف بهذا ولست بحاجة لسماعه مني، أنت رائعٌ في هذا. الهدف هو جعلك أفضل في الصورة الكبرى، بحيث يتحسن المنتج مع كل قرار تتخذه بطريقةٍ أو بأخرى. قائمة التحقق التي تمر من خلالها عندما تواجه أي قرار في التصميم هي كالتالي: عندما يكون فيها فائدة واضحة للمستخدم، افعلها. لا تدع أي مطور يخرجك منها إذا كانت توفر تجربةً أفضل للمستخدم بشكلٍ مؤكد. مثلًا: إذا احتاجت رسالة خطأ في موقعك لتكون بألوانٍ مختلفة، وكلماتٍ محددة وظهورها في الداخل مع عناصرها لتجنب مغادرة المستخدم بدلًا من رسالةٍ في أعلى الصفحة، افعلها. يستحق نجاح منتجك هذا العمل الإضافي في البداية. يمكن كتابة الشيفرة بشكل أفضل بمساعدة المصمم. اسأل حول كيفية إنجاز هذا. استخدم أي حقائق ومصادر ممكنة لتوضيح موقعك، ولكن لا تجعل المستخدم يعاني لأن هذا سيكون أكثر تحديًا عند التطوير. تحقق مما إذا كان هناك طريقة أخرى لخلق نفس التأثير من أجل مساعدة المستخدم وقاعدة الشيفرة. ففي الكثير من الأحيان، يكون هناك مجال لإنجاز ما تريده بطريقةٍ أخرى أسهل لا تسبب الفوضى. اطلب مدخلات المطورين، حيث أن منطقهم وعقلهم يمكن أن يخرج بحلٍ أفضل من الذي قد خططت له، ويعمل لصالح المستخدم وصالحهم أيضًا. مثلًا: يمكن تصنيف رسائل الأخطاء ووضع شيفرة الألوان في برنامج قابل لإعادة الاستخدام. وبدلًا من وجود رسالة مخصصة ولون لكل إدخال كما هو في المثال السابق، قد يكون هناك 3 فئات من الرسائل، كل واحدة بلون. يسمح هذا للمطورين بترتيب وإعادة استخدام الشيفرة بشكل أفضل، بينما يتواصل بوضوح مع المستخدم. عندما يحدث جدال حول صنف، أو عنصر في التصميم أو ميزة تخدم المستخدم، اختر الطريق الذي يجعل الشيفرة قابلة لإعادة الاستخدام، أو ثابتًا أو نظيفًا. هل يمكن لرسائلك التحذيرية استخدام اللون الأصفر المشترك بدلًا من اللون البرتقالي الاعتيادي؟ ينقل كل منهما طبيعة التحذير للمستخدم، ولكن استخدام لون مخزن وثابت يقلل من التعقيدات ويجعل الشيفرة أصغر حجمًا. ترجمة ـوبتصرف- للمقال What does it mean to design for development لكاتبه Kevin Tomasso
- 1 تعليق
-
- 1
-
- تطوير الويب
- تصميم المواقع
- (و 3 أكثر)
-
توفّر jQuery أدوات قويّة لإيجاد العنصر أو العناصر التي تريدها في الصّفحة، ثمّ العمل بهذه العناصر للوصول إلى النّتيجة المرغوبة. تسهّل jQuery بأدواتها هذه عمليّات كانت لتكون أكثر تعقيدًا لو أردنا تنفيذها من خلال وظائف DOM الأصليّة. سنطّلع في هذا الجزء على بعض (لا كلّ) وظائف الانتقال عبر الصّفحة وتّعديل العناصر في jQuery. وقبل أن نبدأ، علينا فهم بعض المصطلحات الضّروريّة. لنفترض أنّ لدينا نصّ HTML التّالي: <ul> <li> <span> <i>Foo</i> </span> </li> <li>Bar</li> </ul> نقول عن عنصر القائمة الأوّل (<li>) أنّه ابن (child) القائمة غير المرتّبة (<ul>). نقول عن القائمة غير المرتّبة (<ul>) أنّها والد (parent) عنصري القائمة الاثنين. نقول عن العنصر <span> أنّه خَلَفُ (descendant) القائمة غير المرتّبة. نقول عن القائمة غير المرتّبة أنّها سَلَفٌ (ancestor) لكلّ ما داخلها. نقول عن عنصري القائمة أنّهما شقيقان (siblings). الانتقال عبر الصّفحة (Traversal) تسمح jQuery لنا بالانتقال عبر عناصر HTML الّتي تكوّن صفحتنا. إذ نُنشئ أوّلًا تحديدًا مبدئيًّا ثمّ ننتقل عبر DOM انطلاقًا منه. وخلال مسيرنا عبر DOM، فإنّنا نُغيّر من تحديدنا الأوّل فنضيف إليه أو نحذف منه بعض العناصر، أو نستبدل به تحديدًا آخر بالكامل في بعض الأحيان. تصفية التّحديدات بإمكانك تصفية تحديد موجودٍ بحيث يتضمّن فقط العناصر الّتي تطابق معاييرَ مُحدّدة. بإمكانك مثلًا إجراء التّصفية بإحدى الطّرق التّالية: var listItems = $( 'li' ); // صفِّ التّحديد ليحوي فقط العناصر ذات الصّنف 'special' var special = listItems.filter( '.special' ); // صفّ التّحديد ليحوي فقط العناصر من غير الصّنف 'special' var notSpecial = listItems.not( '.special' ); // صفّ التّحديد ليحوي فقط العناصر الّتي تتضمّن span var hasSpans = listItems.has( 'span' ); من المهمّ أن تعرف أن الوظيفة .not() ليست عكس .is()، لأنّ .is() تُعيد قيمة منطقيّة (true أو false)، بينما تُعيد .not() كائن jQuery جديدًا. إيجاد العناصر انطلاقًا من تحديد يمكن الاستفادة من تحديد أوّليّ كأساس لإنشاء تحديدات إضافيّة؛ فإذا كان لديك تحديدٌ يحوي عنصر قائمة مُفردًا مثلًا، وأردت التّعامل مع "أشقّائه" أو مع القائمة غير المُرتّبة الّتي تحويه، فبإمكانك إنشاء تحديد جديد انطلاقًا من التّحديد الموجود بسهولة: // اختر أوّل عنصر قائمة في الصّفحة var listItem = $( 'li' ).first(); // أيضًا: .last() // اختر أشقّاء عنصر القائمة var siblings = listItem.siblings(); // اختر الشّقيق التّالي لعنصر القائمة var nextSibling = listItem.next(); // أيضًا: .prev() // اختر والد عنصر القائمة var list = listItem.parent(); // اختر عناصر القائمة الّتي تنحدر مباشرةً من القائمة var listItems = list.children(); // اختر كلّ عناصر القائمة ضمن القائمة، بما في ذلك العناصر الفرعيّة var allListItems = list.find( 'li' ); // اختر كل أسلاف عنصر القائمة ذوي الصّنف "module" var modules = listItem.parents( '.module' ); // اختر أقرب سلفٍ لعنصر القائمة له الصّنف "module" var module = listItem.closest( '.module' ); بإمكانك كذلك الإضافة على التّحديد الحاليّ باستخدام الوظيفة .add()، الّتي تقبل مُحدِّدًا أو مصفوفة عناصر أو نص HTML أو كائن jQuery. var list = $( '#my-unordered-list' ); // افعل شيئًا ما بالقائمة ثم ... var listAndListItems = list.add( '#my-unordered-list li' ); العودة إلى التّحديد الأصليّ تحتفظ jQuery بإشارة إلى تحديد الأصليّ عندما تستخدمه للانتقال إلى تحديدات أخرى انطلاقًا منه، في حال أردت العودة إلى التّحديد الأصليّ. افترض مثلًا أنّك حدّدت قائمة غير مرتّبه، ثمّ أردت التّعديل على عناصر القائمة، ثمّ العودة مجدّدًا للعمل على القائمة غير المرتّبة، عندها بإمكانك استخدام الوظيفة .end() للرّجوع إلى التّحديد الأصليّ: $( '#my-unordered-list' ) .find('li') // نحن الآن نعمل على عناصر القائمة .addClass('special') .end() // عدنا الآن للعمل على القائمة ذاتها .addClass('super-special'); تُسهِّل الوظيفة .end() إجراء تعديلات كثيرة في جملة واحدة، إلّا أنّ هذا الأسلوب لا يُلقي بالًا لوضوح النّصّ البرمجيّ، فهو أشبه بأن تحكي قصّة دون أن تلتقط أنفاسك. لهذا السّبب لا أنصحك بالإكثار من استعماله، فهو يؤدّي في معظم الحالات إلى جعل قراءة النّصّ البرمجيّ وصيانته وتنقيحه أكثر صعوبة. فيما يلي حلّ أفضل للمشكلة ذاتها: var list = $( '#my-unordered-list' ); var listItems = list.find('li'); listItems.addClass( 'special' ); list.addClass( 'super-special' ); توفّر jQuery أيضًا الوظيفة .addBack() إن أردت إضافة تحديدك الأصليّ إلى التّحديد الحاليّ. مثال: $( 'li.special' ) .siblings() // نحن نعمل الآن على أشقّاء التّحديد السّابقة .removeClass( 'important' ) .addBack() // الآن نعمل على عناصر القائمة الأصليّة وأشقائها **معًا** .addClass( 'urgent' ); هل اختلط عليك الأمر؟ الوظيفة .addBack() تشبه الوظيفة .end() في عيوبها، فكلاهما (وإن كان لهما استخدامها) يزيدان تعقيد النّصّ البرمجيّة. الحلّ الأفضل هو استخدام الوظيفة .add() لدمج التّحديدين الأصليين معًا: var specialListItems = $( 'li.special' ); var otherListItems = specialListItems.siblings(); otherListItems.removeClass( 'important' ); specialListItems.add( otherListItems ).addClass( 'urgent' ); هناك وظائف عديدة لم نتطرّق إليها هنا، يمكنك الاطّلاع عليها في وثائق الانتقال عبر الصّفحة. التّعامل مع العناصر (Manipulation) تسمح وظائف التّعامل مع العناصر في jQuery بتغيير DOM الصّفحة بصياغة أكثر بساطة من تلك الّتي توفّرها وظائف DOM الخام. تُعيد وظائف التّعامل مع العناصر في jQuery كائن jQuery الّتي استدعيت للعمل عليه، وهذا يعني إمكانيّة ربطها في سلسلة أو دمجها مع وظائف jQuery أخرى كالّتي ناقشناها في الفقرات السّابقة. تعديل العناصر كثيرةٌ هي طرق تعديل العناصر في jQuery. سنطّلع فيما يلي على طرق إنجاز المهام الأكثر شيوعًا. إضافة أو حذف الأصناف (classes) يمكن الاستفادة من أصناف الكائنات في HTML بأن نستهدفها في CSS بغرض تنسيقها، كما يُستفاد منها في إنشاء تحديدات jQuery. فمثلًا يمكن لعنصر في الصّفحة أن يقع تحت الصّنف hidden، والّذي يُستخدم في CSS لجعل خاصّة display موافقة للقيمة none للعناصر من هذا الصّنف، ثمّ يمكن حذف هذا الصّنف أو إضافته لتغيير حالة ظهور العناصر الموافقة في jQuery: $( 'li' ).addClass( 'hidden' ); $( 'li' ).eq( 1 ).removeClass( 'hidden' ); جرّب المثال في ساحة التّجربة (تأكد من ضغط زر Run with JS في هذا المثال وكلّ الأمثلة التالية) إن تطلّبت حالتك إضافة صنفٍ أو حذفه مرارًا، فبإمكانك استخدام الوظيفة .toggleClass() الّتي تُبدّل حالة الصّنف على العنصر، فتضيفه إن لم يكن موجودًا أو تحذفه إن وُجد: $( 'li' ).eq( 1 ).toggleClass( 'hidden' ); جرّب المثال في ساحة التّجربة تغيير المظهر ملاحظة: يُفضّل دومًا استخدام الأصناف واستهدافها بقواعد CSS لتغيير طريقة عرض العناصر، والاقتصار على استخدام jQuery في إضافة هذه الأصناف أو حذفها كما ورد للتوّ. في هذه الفقرة سنتعرّف كيف نُغيّر مظاهر العناصر مُباشرةً في jQuery، ولكننا نُفضِّل دومًا الأسلوب الأوّل إن كان يُحقِّق النّتائج ذاتها. عندما تعجز عن تحقيق هدفك بإضافة الأصناف أو حذفها، فإنّ jQuery تقدّم الوظيفة .css() الّتي تسمح بتعيين مظهر العناصر مباشرةً، ولعلّ هذا يكون ضروريًّا عادةً عندما تحتاج إلى إسناد قيم عدديّة لا يمكن حسابها إلّا أثناء عمل التّطبيق، كمعلومات توضّع العناصر في الصّفحة. لا يُفضَّل استخدام الوظيفة .css() لإجراء تنسيقات بسيطة مثل display: none، بل يُفضَّل في معظم الحالات إنجاز الغاية ذاتها باستخدام الأصناف وCSS. افترض مثلًا أنّنا نريد تعيين مظهر العنصر بالاعتماد على عرض والده، وربّما يصعب أو يستحيل معرفة عرض الوالد مُسبقًا عند اعتماد تخطيط مرنٍ للصّفحة. في هذه الحالة قد نلجأ إلى الوظيفة .css() لتنسيق العنصر: var list = $( '#my-unordered-list' ); var width = Math.floor( list.width() * 0.1 ); list.find('li').each(function( index, elem ) { var padding = width * index; $( elem ).css( 'padding-right', padding + 'px' ); }); جرّب المثال في ساحة التّجربة إن احتجت إلى تعيين أكثر من خاصّة في وقت واحدٍ، مرّر كائنًا إلى الوظيفة .css() بدلًا من اسم الخاصّة وقيمتها. لاحظ أنّ عليك إحاطة أيّة خاصّة تحوي الرّمز "-" بعلامتي اقتباس: $( 'li' ).eq( 1 ).css({ 'font-size': '20px', 'padding-right': '20px' }); جرّب المثال في ساحة التّجربة تغيير قيم النّماذج (forms) تقدّم jQuery الوظيفة .val() لتعديل قيمة العناصر في النّماج مثل input وselect. بإمكانك تمرير سلسلة نصّيّة لتعيين محتوى حقول input النّصّيّة: $( 'input[type="text"]' ).val( 'new value' ); جرّب المثال في ساحة التّجربة بالنّسبة للعناصر من نوع select، بإمكانك تعيين الخيار المُختار باستخدام .val() أيضًا: $( 'select' ).val( '2' ); جرّب المثال في ساحة التّجربة أمّا لحقول input من نوع checkbox، فعليك تعيين الخاصّة checked على العنصر بالوظيفة .prop(). $( 'input[type="checkbox"]' ).prop( 'checked', 'checked' ); جرّب المثال في ساحة التّجربة ملاحظة: أُضيفت الوظيفة .prop() في الإصدارة 1.6 من jQuery؛ وقبل ذلك كانت تُستخدم الوظيفة .attr() للغرض ذاته، وهي ما تزال تعمل في الإصدارات الحديثة من jQuery، ولكنّها في حالة checked تكتفي باستدعاء .prop(). إن كنت تستخدم إصدارةً أحدث من 1.6، فأنصحك باستخدام .prop() دومًا لتعيين الخاصّة checked وخصائص عناصر DOM الأخرى. اطّلع على الوثائق لتفاصيل أكثر. تغيير الصّفات (attributes) الأخرى بإمكانك استخدام وظيفة .attr() لتغيير صفات العناصر، فيمكنك مثلًا تغيير عنوان رابط (الخاصّة title لعنصر <a>): $( 'a' ).attr( 'href', 'new title'); عند تعيين قيمة لصفة، بإمكانك تمرير دالّة في موضع المُعامل الثّاني للوظيفة، ومثلها مثل كلّ دوالّ الكتابة السّابقة، تتلقّى هذه الدّالّة مُعاملين اثنين: دليل العنصر الّذي تعمل عليه، والقيمة الحاليّة للصّفة. يجب أن تُعيد هذه الدّالة القيمة الجديدة للصّفة: $( 'a' ).attr( 'href', function(index, value) { return value + '?special=true'; }); جرّب المثال في ساحة التّجربة بإمكانك حذف الصّفات أيضًا، وذلك باستخدام .removeAttr(). الحصول على معلومات من العناصر ناقشنا في الجزء السّابق (أساسيّات jQuery) فكرة وظائف القراءة والكتابة. كلّ الوظائف الّتي يمكن استخدامها لتغيير العناصر، يمكن أيضًا استخدامها لقراءة معلومات من تلك العناصر. فيمكن مثلًا استخدام الوظيفة .val() الّتي وصفناها أعلاه كوظيفة قراءة وكتابة معًا: var input = $( 'input[type="text"]' ); input.val( 'new value' ); input.val(); // returns 'new value' وكذلك الأمر بالنّسبة للوظيفة .css()، إذ يمكن استخدامها لقراءة قيمة خصائص CSS مُفردة بإمرار اسم الخاصّة فقط دون قيمة: var listItemColor = $( 'li' ).css( 'color' ); عندما تُستخدم وظائف التّعامل مع العناصر للقراءة، فإنّها تعمل فقط مع العنصر الأول في التّحديد، باستثناء الوظيفة .text() الّتي تقرأ المحتوى النّصيّ لكلّ العناصر المُحدّدة إن لم يُمرّر معامل إليها. إضافة العناصر إلى الصّفحة سواءٌ حدّدت عنصرًا أو أنشأت واحدًا جديدًا، فبإمكانك إضافة هذا العنصر إلى الصّفحة يمكن فعل ذلك بطريقتين: باستدعاء وظيفة تتبع للعنصر (أو العناصر) المطلوب إضافته، أو باستدعاء وظيفة تتبع لعنصر مرتبط بذلك الّذي تريد إضافته. افترض مثلًا أنّك تريد نقل عنصر في قائمة من رأسها إلى ذيلها، هناك عدّة طرق لفعل ذلك. بإمكانك مثلًا إضافة العنصر إلى القائمة باستدعاء الوظيفة .appendTo() على عنصر القائمة ذاته: var listItem = $( '#my-unordered-list li' ).first(); listItem.appendTo( '#my-unordered-list' ); جرّب المثال في ساحة التّجربة وبإمكانك أيضًا إضافة العنصر باستدعاء .append() على القائمة: var listItem = $( '#my-unordered-list li' ).first(); $( '#my-unordered-list' ).append( listItem ); أو إضافته باستدعاء .insertAfter() على العنصر المُراد نقله مُمرّرًا العنصر الأخير في القائمة إلى الوظيفة: var listItems = $( '#my-unordered-list li' ); listItems.first().insertAfter( listItems.last() ); جرّب المثال في ساحة التّجربة أو إضافته باستدعاء .after() على العنصر الأخير في القائمة مُمرًّرا العنصر الأولى في القائمة إلى الوظيفة: var listItems = $( '#my-unordered-list li' ); listItems.last().after( listItems.first() ); جرّب المثال في ساحة التّجربة هناك طرق آخرى كثير لإضافة العناصر، فبإمكانك إضافتها حول عناصر أخرى أو داخلها أو خارجها بحسب حاجتك. تعتمد أكثر الطّرق كفاءة في إضافة عنصر إلى الصّفحة على العناصر الّتي تتوفّر بين يديك بالفعل. فقد ترغب في إضافة العنصر إلى القائمة غير المُرتّبة في المثال السّابق إن كنت قد حدّدت القائمة غير المرتّبة من قبل لغرض آخر؛ أو إن كنت قد حدّدت عناصر القائجة جميعها، فقد يكون إضافة العنصر الأول بعد العنصر الأخير أمرًا أسهل. عندما تختار الطّريقة المناسبة لإضافة العنصر، فلا تكتفِ بالنّظر في سهولة الطّريقة، بل فكّر في إمكانيّة صيانتها لاحقًا. تجنّب الطّرق الّتي تعتمد على افتراض بنية مُحدِّدة بدقَّة لصفحتك، فقد تقرّر تغيير هذه البنية فيما بعد. نسخ العناصر بإمكانك إنشاء نسخة من عنصر أو مجموعة عناصر باستخدام الوظيفة .clone() في jQuery، وستُنشئ النُّسخة في الذّاكرة دون أن تُدرج في الصّفحة، فعليك فعل ذلك بنفسك إن أردته. بإمكانك تعديل العناصر المنسوخة قبل إضافتها: var clones = $( 'li' ).clone(); clones.html(function( index, oldHtml ) { return oldHtml + '!!!'; }); $( '#my-unordered-list' ).append( clones ); جرّب المثال في ساحة التّجربة ملاحظة*: لن تمنعك jQuery من نسخ عنصر ذي مُعرِّف (ID)، ولكن عليك التأكّد من حذف المُعرِّف أو تغييره في العنصر المنسوخ بتعديل الصّفة id قبل إدراجه في المستند، إذ لا ينبغي أ يوجد عنصران بمُعرِّف واحدٍ في الصّفحة. حذف العناصر هناك ثلاث طرق لحذف العناصر من الصّفحة: .remove() و.detach() و.replaceWith()، ولكلّ منها غرضٌ مُختلف. يجب استخدام .remove() عند الحاجة لحذف العناصر بصورة دائمة، فهي ستحذف مع العنصر كلّ مُتوليّات الأحداث المُرتبطة به (event handlers). تُعيد الوظيفة .remove() إشارةً إلى العناصر المُحذوفة، ولكن عند إضافة هذه العناصر مرّة ثانيةً، فلن تكون أيّة أحداث مُرتبطةً بها. $( '#my-unordered-list li' ).click(function() { alert( $( this ).text() ); }); var removedListItem = $( '#my-unordered-list li' ).first().remove(); removedListItem.appendTo( '#my-unordered-list' ); removedListItem.trigger( 'click' ); // لا رسالة تنبيه! جرّب المثال في ساحة التّجربة تُفيد الوظيفة .detach() في حذف العناصر مؤقّتًا من الصّفحة، فمثلًا إن رغب في إجراء تعديلات كبيرة على بنية الصّفحة باستخدام jQuery، فقد يكون حذف العناصر مؤقّتًا من الصّفحة ثمّ إضافتها ثانيةً أفضل أداءً بمراحل. ستحتفظ العناصر المحذوفة بهذه الوظيفة بمُتولّيات الأحداث المُرتبطة بها، ويمكن بعد ذلك إضافتها إلى الصّفحة مُجدّدًا باستخدام .appendTo() أو غيرها من وظائف الإضافة. $( '#my-unordered-list li' ).click(function() { alert( $( this ).text() ); }); var detachedListItem = $( '#my-unordered-list li' ).first().detach(); // افعل شيئًا ما مُعقّدًا بعنصر القائمة detachedListItem.appendTo( '#my-unordered-list' ); detachedListItem.trigger( 'click' ); // alert! أخيرًا لدينا الوظيفة .replaceWith() الّتي تُحلِّ عنصرًا أو نصّ HTML محلّ عنصرٍ أو عناصر أخرى. تُعاد العناصر الّتي أُزيلت من الوظيفة، ولكنّ كلّ متولّيات الأحداث المرتبطة بها تُحذف، تمامًا كالوظيفة .remove(). $( '#my-unordered-list li' ).click(function() { alert( $( this ).text() ); }); var replacedListItem = $( '#my-unordered-list li' ).first() .replaceWith( '<li>new!</li>' ); replacedListItem.appendTo( '#my-unordered-list' ); replacedListItem.trigger( 'click' ); // لا رسالة تنبيه! جرّب المثال في ساحة التّجربة خاتمة تعلّمنا في هذا الجزء الطّرق المختلفة للانتقال بين العناصر في الصّفحة، وكيفيّة نقلها وتغييرها وإضافة عناصر جديدة. سنتعلّم في الجزء القادم كيف نُنصِت لتفاعل المستخدم مع صفحتنا. ترجمة (بشيء من التصرف) للجزء الثالث من سلسلة jQuery Fundamentals لمؤلّفتها Rebecca Murphey.
-
يستعرض هذا المقال الأمور الرئيسية التي كنتُ بحاجة إلى توضيحات بشأنها حتى أتمكَّن من العمل كمطور ووردبريس حر. أخبرني العديد من الأشخاص بأنَّهم يريدون البدء في مجال تطوير الووردبريس –وأغلبهم يرغبون في العمل لحسابهم الخاص كمطوِّري ووردبريس مستقلين-، ولكنَّهم لا يعلمون كيف يبدؤون. كلَّما فكَّرتُ في هذا الأمر، رأيته منطقيًا، إذ أنَّ تطوير الووردبريس مجال واسع وحدوده تتخطَّى تقنية الووردبريس (المربِكة جدًا) نفسها. في هذا المقال، سأسرد وأستعرض الأمور الجوهرية التي كنتُ بحاجة إلى اكتشافها ومعرفتها بنفسي لكي أتمكَّن من العمل كمطور ووردبريس حر ناجح، وتنقسم هذه الأمور إلى ثلاث فئات: الأمور الاستراتيجية: ما ينبغي عليك معرفته عن هذا المجال وعن الحياة نفسها لكي تنجح في العمل كمطور ووردبريس حر. الأمور العملية: التفاصيل المتعلقة بالمُعدّات والخدمات التي تحتاجها لكي تبدأ العمل بالفعل. الأمور التقنية: المواضيع التكنولوجيّة التي ينبغي عليك فهمها لكي تكون قادرًا على تقديم عمل جيِّد للعملاء الذين يستخدمون الووردبريس. ذكرتُ فيما يلي كل ما استطعت أن أذكره لمساعدتك في البدء بكل فئة من هذه الفئات، إذ تحدَّثتُ عن المسائل التي أنت حقًا بحاجة إلى أن يكون لديك حلول لها -أو على الأقل أن تكون قد فكرَّت فيها بعمق- حتى تستطيع النجاح في عملك كمطور ووردبريس حر. إحدى الأشياء التي يجدُر توضيحها هي أنَّ قسم «الأمور الاستراتيجية» قد كتبته وأنا أضع مطوِّري الووردبريس المستقلين نصب عينيّ: أي المطوِّرين أمثالي الذين يركِّزون على العمل مع عملاء، والذين يعملون لحسابهم الخاص أو يعملون كجزء من وكالات صغيرة جدًا، وهؤلاء هم الفئة الكبرى من مطوِّري الووردبريس المحترفين. هناك بالتأكيد وظائف أخرى في مجال تطوير الووردبريس إلى جانب العمل الحر! يمكنك أن تعمل لصالح وكالة كبيرة، ويمكنك أن تبيع الإضافات المدفوعة، ويمكنك أن تعمل في الدعم الفني لشركة استضافة، وغير ذلك. إذا كان لديك معرفة بسيطة جدًا بهذه الوظائف، فبرأيي أنَّه من المؤكد أنَّ قسم «الأمور التقنية» في هذا المقال سيكون ملائمًا لك مهما كانت الوظيفة التي اخترتَها في مجال تطوير الووردبريس، كما أنَّ قسم «الأمور العملية» سيكون ملائمًا إلى حدٍ ما، ولكنَّ درجة ملائمة قسم «الأمور الاستراتيجية» غير محددة. كن مطور ووردبريس حر: الأمور الاستراتيجية الأساسية التي ينبغي مراعاتها وضع دوافع وتوقعات واضحة إنَّ العمل في مجال تطوير الووردبريس -مثله مثل أي شيءٍ آخر- له إيجابيات وسلبيات، وله محاسن ومساوئ. يجب أن تكون دوافعك وتوقعاتك المتعلقة بعملك كمطور ووردبريس حر واضحة للغاية وواقعية. سأبدأ حديثي بإخبارك عن تجربتي في العمل. الأمور التي أحبُّها بشأن العمل في مجال تطوير الووردبريس باحترافية المرونة: يمكنني وضع كل ما يتعلق بعملي في حقيبة ظهر، وسيبقى هناك متسعًا كبيرًا للملابس. وبفضل هذا الأمر، تمكَّنتُ من الانتقال مع زوجتي إلى نيو أورلينزعندما أرادت ذلك، كما أنَّني أستطيع زيارة والديّ في هاواي لفترات طويلة أربع أو خمس مرَّات في السنة دون أن يؤثِّر ذلك على عملي. ولأنَّني مدير نفسي، أستطيع أخذ إجازات وقضاء أوقات في السفر بقدر ما يسمح به دخلي الخاص. شعور الإتقان: أصبحت محترفًا في تطوير الووردبريس منذ عام 2012، وأشعر الآن بأنَّني جيدٌ جدًا جدًا في عملي؛ فعندما يحتاج الناس إلى مساعدة في الجوانب التقنية المتعلقة بالووردبريس، عادةً ما أكون قادرًا على إنجازها بسرعة أكبر مما يتوقعون أو إسداء نصائح رائعة لهم تساعدهم على التقدُّم. هذا الأمر مدعاة للسرور، خصوصًا عندما تكون في صدد إصلاح مشروع ووكومرس تكلفته مائة ألف دولار قد أخفق المطوِّر السابق غير الكفء تمامًا في إنجازه، أو عندما تساهم بشكل كبير في تحديث وتحسين وجود مؤسسة -تهتم حقًا بها- على شبكة الإنترنت. إنَّ تطوير الووردبريس مهنة حقيقية، وإتقانك لها يمنحك شعورًا رائعًا. يُمكن أن يكون ممتعًا: يتضمن العمل الحر في مجال تطوير الووردبريس الكثير من التعاملات مع الناس، والكثير من عمليات حل المشكلات البسيطة أو المتوسطة، والكثير من البحث عبر الإنترنت، والكثير من الأمور التي تتطلَّب منك الإبداع. بمجرد أن تصبح خبيرًا في المجال، ستصبح عملية التطوير (وتقابلها عملية إدارة العلاقات مع العملاء) كأنَّك تقضي يومك في حل السودوكو وبناء مجسَّمات الطائرات. إنَّه ليس عملًا سيئًا. الفائدة العامة: الجميع تقريبًا يمتلكون أو يحتاجون أو يريدون موقعًا لغرضٍ أو لآخر، وغالبًا ما يكون الووردبريس هو الخيار الأمثل. لهذا، تتلاءم إمكانياتك في مجال تطوير الووردبريس بطريقة رائعة مع أي مشروع قد يقع بين يديك. الأمور التي لا أحبُّها بشأن العمل في مجال تطوير الووردبريس باحترافية قد لا تحصل على ما تسدّ به جوعك: الأجر الذي أقبضه في نهاية الشهر يكون لقاء العمل الذي أنجزتُه لأشخاص محدَّدين (الأشخاص الذين حوَّلتُهم إلى زبائن) خلال ذلك الشهر. إذا استنفدتَ كل طرق جذب العملاء المحتملين، أو إذا مررتَ بشهرٍ سيء على نحوٍ غير متوقع، فمن المحتمل جدًا ألّا تجني مالًا. بعبارة أخرى: أنت لا تملك أمانًا وظيفيًا، وكل ما تملكه هو ما توفِّره وما تعيل به نفسك. أنت عُرضَة للطلب: لا أحبِّذ -بصراحة- الأوقات التي يرن فيها الهاتف أو تصلني فيها رسالة بريد إلكتروني لأنَّه في كثير من الأحيان يتعلق الأمر بعميل لديه مشكلة مريعة (أو تبدو مريعة) يريد مني أن أحلّها، إذ يعتمد الأشخاص عليّ في ذلك. هناك طرق لإدارة التوقعات والتعامل معها بطريقة مناسبة، ولكن هذا لا يزيل التوتر الكامن في كونك مسؤولًا عن المساعدة في إيجاد الحلول لأي مشكلة قد تنشأ عن عشرات المواقع. لحسن حظي أنّني جيّد في عملي؛ فمن واقع خبرتي، يمكن أن يكون وجود أشخاص يعتمدون عليك بهذه الطريقة مزعجًا جدًا إذا لم تكن ذا معرفة بما تقوم به. من الصعب التفاوض مع العملاء حول الميزانية: بعض المطوِّرين قد لا تواجههم هذه المشكلة، ولكن طريقتي الخاصة في العمل بسيطة وغير رسمية إلى حدٍ ما -وهي تختلف كثيرًا عن طريقة الوكالات الكبيرة التي تتولّى العمل على مشاريع تبلغ تكلفتها مئات الآلاف من الدولارت ويستغرق إنجازها عدة سنوات-، إذ أميل إلى جذب أصحاب الأعمال التجارية الصغيرة الذين أُفضِّل العمل معهم على أي حال. في هذا السياق، تكون الميزانيات محدودة، وهناك حاجة دائمة إلى الشفافية. من المرهق جدًا حل المشكلات التقنية المرتبطة بالمشاريع التي تواجه مشكلات استراتيجية لا يمكنني مساعدة مالكي المواقع على التعامل معها (من الواضح أنَّهم عادةً ما يكونون مصدر هذه المشكلات)، إذ أشعر بأنَّني أساعد الناس على إنفاق أموالهم بطريقة غير عقلانية في هذه الحالة. الشعور بالصدمة: معظم عملائي لا يكونون على معرفة بي في بداية رحلتهم عبر الويب؛ بل يجدونني في منتصفها، وهم يشعرون بخيبة أمل بسبب العديد من المطوِّرين نصف المؤهلين الذين لم يكونوا على دراية بكيفية التواصل. المواقع الخاصَّة بهؤلاء العملاء تنمُّ عن الاختيارات التقنية غير الصائبة، ومن واقع ما رأيت فإنَّ معظم مواقع الووردبريس عبارة عن تجربة سيئة بالنسبة لمستخدميها النهائيين، وذلك بسبب قلة عدد "مطوِّري" الووردبريس المؤهَّلين بالفعل ولأنَّ أسوأ الأجزاء في نظام الووردبريس هي التي يتم تسويقها على النحو الأفضل، والتفكير يوميًا في هذا الأمر يبعث على الإحباط حتى لو كنت جزءًا من الحل. هذه مجرد وجهة نظري، والمغزى هو أنَّ عليك فهم ما أنت مُقبِلٌ عليه وسبب إقبالك عليه. تحدَّث إلى الأشخاص الآخرين الذين يقومون بما ترغب في القيام به، واحرص على أنَّ يكون هناك انسجام بينك وبينهم. في هذه الحالة، يمكنك العثور على الكثير من هؤلاء الأشخاص في اللقاءات التي تُعقد للحديث عن الووردبريس في مجتمعك المحلي. اعرض عليهم أن تشتري لهم وجبة غداء، وسيقبل معظمهم عرضك، كما قد يكون بعضهم -في الحقيقة- بحاجة إلى وجبة الغداء. أنصحكم أيضًا بشدة بقراءة هذا المقال الذي كتبَتْه كاري ديلز (Carrie Dils) وقد تحدَّثَتْ فيه عن مميزات أن تكون مطور ووردبريس حر، إلى جانب التحديات المصاحبة لذلك. الأمور التي قد تجعل العمل الحر في مجال تطوير الووردبريس غير مناسب لك نقطة أخيرة متعلقة بهذا الموضوع: لا أنصح أي أحد بالخوض في العمل الحر في مجال تطوير الووردبريس إذا انطبقت عليه إحدى العبارتين التاليتين أو كلتيهما: أنت لا تملك مهارات عامة قوية في الجوانب التقنية وفي حل المشكلات، وهذا يعني أنَّك لا تستطيع عمومًا التعامل مع المشاريع التقنية المعقدة (مثل مشروع jailbreak my phone) والتغلُّب على تحدياتها من خلال البحث عبر الإنترنت ومحاولة إدخال التعديلات والتحسينات عليها. تنزعج كثيرًا من خدمة العملاء، وهذا يعني أنَّك لا ترغب في التعامل مع الناس، ولا تفهم ما يريدونه، وتكره مضايقاتهم، وتكره تقديم التفسيرات، وتخوض في الجدالات بسهولة، وهكذا. إذا كنت تعاني من نقطتي الضعف السابقتين ولديك شريك يمكنه التغلُّب عليهما، فلا بأس في هذا. لكن إذا كنت تعمل لوحدك وتحاول أن تبني عملك الحر على هذا الأساس، فسوف تواجه عقبات في طريقك. المخطط الزمني والالتزام بالوقت ما هي ظروف حياتك الحالية –من حيث أوقات الفراغ ووضعك المالي- وكيف يتلاءم العمل الحر في مجال تطوير الووردبريس معها؟ هل تريد أن تتخذ من تطوير الووردبريس عملًا بدوام كامل؟ إذا كنت ستفعل ذلك، ما هو مخططك الزمني لتحقيق ذلك؟ وكيف ستشدُّ من أزر نفسك خلال عملية التحوُّل؟ تختلف الظروف من شخصٍ لآخر، لذلك لن أحاول إسداء النصائح لحالات معينة؛ بل سأذكر بعض المعلومات والحلول لتأخذها في الاعتبار مهما كانت ظروفك الحالية: ستقضي وقتًا صعبًا في سبيل الحصول على ما يكفي من الساعات مدفوعة الأجر إلى أن تؤتي الطرق التي تنتهجها لإيجاد العملاء أُكُلها، وتبدأ قائمة عملائك تمتلئ بعملاء رائعين. إذا كنت تريد أن تصبح مطور ووردبريس حر بدوام كامل، فمن المرجَّح أن يكون العائد الذي ستجنيه خلال الثلاثة أشهر الأولى على الأقل -وربما الستة أشهر- ضئيلًا، وأن تمضي سنة كاملة أو أكثر دون أن تكون واثقًا ممّا إذا كنت ستجني شهريًا ما يعادل راتب الطبقة المتوسطة. لا تستغرق الأعمال التي تقوم بها للحصول على عملاء –مثل الذهاب إلى فعاليات التشبيك، وإنشاء موقع إلكتروني لعرض نماذج أعمالك، والاستفادة من شبكة علاقاتك الحالية- 40 ساعة أسبوعيًا، إذ ينتهي بك المطاف إلى قضاء الوقت في انتظار أن يتواصل معك أحد العملاء المحتملين، أو في انتظار أن يحين موعد فعالية التشبيك الأسبوعية التالية، وما إلى ذلك. بعبارة أخرى: من الصعب جعل «عملية الحصول على عملاء» عملًا بدوام كامل إلا إذا لم تكن تمانع التسويق باستخدام أسلوب الاتصال البارد (cold calling)، أو توزيع النشرات الإعلانية الخاصة بالأعمال التجارية المحلية، وغيرها. لن تكون لك قدم ثابتة في الجوانب التقنية لمدة عام على الأقل، وهذا يعني أنَّه ستواجهك باستمرار مشكلات لا تعرف كيفية حلّها. هذه النقطة هي مجرد تنبيه لك حتى تستعد لخوض فترة صعبة وبعض اللحظات المروِّعة. (ألق نظرة على بند «من الذي سيكون طوق نجاتك» المذكور لاحقًا للتعرُّف على المزيد من الاقتراحات المتعلِّقة بهذا الأمر.) لا أعلم ما إذا كان من الأفضل مواجهة هذ الفترة من خلال العمل كمطور ووردبريس بدوام كامل أم بدوام جزئي، ولكن ربما يكون العمل بدوام كامل هو الأفضل لأنَّه لن يكون لديك خيار سوى التصدِّي للعقبات عندما تعترض طريقك. ذكرتُ هذه النقطة هنا لأنَّه ينبغي عليك أن تنظِّم أمورك المالية لفترة طويلة نسبيًا بينما تحاول التسويق لنفسك بصفتك مطور ووردبريس يتقاضى أجرًا، دون أن تكون متأكدًا ما إذا كنت ستحصل حقًا على المال. غالبًا ما يبدأ العمل الحر في مجال تطوير الووردبريس بالنمو ببطء، كغيره من الأمور الأخرى. لذا، أنصحك بأن يكون لديك قدرًا لا بأس به من الادخار الشخصي، أو أن تحافظ على التزاماتك الحالية إلى أن تصبح متأكدًا من أنَّ عملك في مجال الووردبريس سيكفيك مؤنتك. في الحقيقة، لم أفعل ذلك وقد انتهى الأمر على ما يرام، إذ أنَّ الطريقة الصعبة التي انتهجتُها كانت مفيدة جدًا، ولكنَّها لم تكن ممتعة. كيف تحدِّد تسعيرة عملك؟ أنا أُفضِّل أن يكون تسعير الأعمال في مجال تطوير الووردبريس على أساس الساعة، ما لم يكن لديك سبب قوي لاختيار أسلوب آخر. الكثير من الأشخاص لا يعجبهم التسعير على أساس الساعة، ويفضِّلون التسعير على أساس المشروع أو التسعير على أساس القيمة (value pricing)، ولكنّني شخصيًا وجدتُ أنَّ جميع الأساليب عدا التسعير على أساس الساعة من الصعب جدًا على المستقل أن يطبِّقها مع معظم العملاء. يؤدِّي التسعير على أساس المشروع إلى الخوض في عمليات طويلة لتقدير قيمة المشروع والتفاوض مع الزبائن، أما التسعير على أساس القيمة يوقعك في حبال العمل التجاري الخاص بالزبون على نطاق أوسع. لا بأس بهذه الأساليب إذا كنت ستساهم على نحو كبير لمدة سنوات في توجيه دفة العديد من الجوانب الاستراتيجية الواسعة للعمل التجاري الخاص بالعميل، ولكن إذا كانت وظيفتك مقتصرة على تقديم الحلول التقنية لجزء واحد من أجزاء العمل التجاري (هذا هو حال أغلب مشاريع العمل الحر)، فستصبح وكأنَّك سبَّاكًا يتقاضى أجره من خلال الحصول على حقوق ملكية عقارية! إرشادات عامة بشأن التسعير فيما يلي بعض الإرشادات العامة بشأن تسعير الأعمال في مجال تطوير الووردبريس على أساس الساعة (حسب ما هو متعارف عليه في الولايات المتحدة لمطوري الووردبريس المستقلين): ينبغي عليك ألا تطلب سعرًا أقل من 50$ في الساعة مقابل خدماتك. يُعَدُّ 50$ أو 60$ سعرًا متواضعًا ومناسبًا في بدايات عملك، ولكن ينبغي عليك أن تتطلَّع إلى أن يصل السعر إلى ما لا يقل عن 75$ في غضون سنة، وإلى ما لا يقل عن 100$ في غضون سنتين. ملاحظة: تختلف الأسعار من بلدٍ لآخر، وغالبًا ما تكون الأسعار في البلاد العربية أقل بكثير من الأسعار التي سبق ذكرها. ما يهم حقًا هو مدى براعتك في الأمور التي تتقاضى أجرًا على أساس الساعة للقيام بها. بالنسبة لي، أطلب إما 100$ أو 125$ مقابل الساعة. خبرتي أكبر من خبرة المطورين المبتدئين وتكلفة توظيفي أرخص بكثير من تكلفة توظيف مطور مبتدئ يطلب 50$ مقابل الساعة، إذ أنَّ هؤلاء المطورين سيكلِّفونك آلاف الدولارات بسبب حلولهم السيئة، وسيبقون عالقين في مسألة لساعات، وبعدها سيضعون الحل الخطأ. لقد تطلَّبت مني حوالي 80% من مشاريع العمل الحر التي عملتُ على إنجازها قضاء الساعات لتعديل العمل الذي قام به المطور السابق الذي لم يكون كفئًا، ومن الأمثلة على تلك المشاريع: بناء برمجي متهالك وغير متوافق مكوَّن من 50 إضافة، أو التعامل مع تركيب تكنولوجي سيء (HostGator، وقالب Divi، ومئات الإعدادات للحقول المخصصة المتطورة [AFC]، و Visual Composer)، أو أخطاء تعرقل عمل الموقع، أو مشكلات في SEO، وما إلى ذلك. ملاحظة مهمة: هذه الأسعار من وجهة نظر الكاتب وموقعه وقد لا تنطبق على العالم العربي وتكون أقل من ذلك بكثير، فأرجو أخذ ذلك بالحسبان. ارفع أسعارك دائمًا عندما ترتقي في سلَّم الثقة والكفاءة، ينبغي عليك أن ترتفع أسعارك وفقًا لذلك. لا أستطيع أن أرسم لك منحى محدَّد يوضح كيف ومتى تغيِّر أسعارك، ولكنَّني سأقول: ارفع أسعارك فحسب؛ فالعملاء لا يبالون بالقدر الذي تظنه، كما أنَّ المال الإضافي الذي ستكسبه واقعي جدًا. فيما يلي بعض المصادر الجيِّدة التي يمكن أن تساعدك في البدء في فهم الأمور الماليّة كمطور ووردبريس حر، وفي معرفة كيفية تحديد أسعارك الخاصة على أساس الساعة: حاسبة تكلفة العمل الحر على أساس الساعة تكاليف تطوير مواقع الووردبريس المخصصة مقدار الوقت الذي يستغرقه إنجاز مشاريع الووردبريس تكلفة إنشاء إضافة ووردبريس (التعامل مع أسئلة العملاء ذات النهايات المفتوحة بخصوص التكلفة) دليل جيِّد يتحدَّث عن استراتيجيات التسعير التي لا تبيع بأسعار أقل من المنافسين (على اعتبار أنَّك متعاقد) دورة تدريبية مجانية عبر البريد الإلكتروني حول التسعير للمستقلين كيفية العثور على عملاء بالنسبة لمطوِّري الووردبريس المستقلين، فإنَّ الإجابة عن سؤال «كيف أحصل على عملاء؟» هي التي تحدد ما إذا كانوا سيكسبون مالًا أم لا. لو كان لهذا السؤال إجابة سهلة، لكنتَ تعرفها بالفعل، ولكن هناك إرشادات جيِّدة تساعدك على البدء. أقترح عليك الاطلاع على هذين المقالين -هنا وهنا-، إذ يلقيان نظرة عميقة على هذا الموضوع. أضع أمامك أيضًا القواعد الرئيسية التي أظنُّها فعّالة في بداية انطلاقتك: حضور فعاليات التشبيك بين الأشخاص. استغلال شبكة علاقاتك الشخصية الحالية. التخصُّص وإقامة العلاقات مع من يعملون في مجالك. استحضار قائمة الأشخاص المرجعيين من عملائك الأوائل القلائل، وحتى من الأشخاص الذين عرفتهم من خلال وظائفك السابقة أو التدريبات أو المشاريع التطوعية، وغيرها. ملخَّص العناصر الأربعة السابقة هو: تحدَّث شخصيًا إلى أي شخص يمكنك الحديث معه داخل شبكة علاقاتك الحالية أو خارجها. قد تكون الاستراتيجيات طويلة المدى –مثل التسويق بالمحتوى والتسويق عبر وسائل التواصل الاجتماعي- ممتازة، ولكنَّها من غير المحتمل أن تكون مصدرًا للحصول على العملاء المحتملين في المدى القريب. من الذي سيكون طوق نجاتك في المواقف الصعبة دائمًا ما كان شريكي ديفيد هو سلاحي السري في مجال تطوير الووردبريس؛ فهو مطوِّر أمهر مني باستمرار ويسبقني في المجال التفني بمقدار 12 إلى 24 شهرًا. لقد تعاملتُ مع الكثير من استراتيجيات العمل وعلاقات العملاء، وأعلم -حتى هذا اليوم- أنَّ ديفيد سيكون موجودًا لينتشلني إذا ما تعرَّضت إلى مسألة تقنية صعبة (مثل أوامر Git المعقدة). بالنسبة للذين ليس لديهم شريك موهوب يعمل كمهندس برمجيات، أدرك أهمية امتلاكهم طريقة لـِ "السباحة" عوضًا عن "الغرق" عندما يواجهون موضوع تقني لا يفهمونه أثناء عملهم على مشروع لأحد العملاء. ما الذي أنصح به؟ بصراحة، لا يوجد حاليًا شيء متين وراسخ يمكن اعتباره طوق النجاة لمطور الووردبريس الحر، ولكن هذه أفضل ثلاثة اقتراحات يمكنك تطبيقها في وقتنا الحالي: اذهب إلى اللقاءات التي تُعقد للحديث عن الووردبريس في مجتمعك المحلي؛ فهذه اللقاءات تكون ممتلئة بالمطوِّرين الذين ستكون سعيدًا بمساعدتهم لك في تعلُّم أشياء لا تعرفها؛ بل حتى في تعلُّم أشياء لا تعرف أنَّك لا تعرفها. انضم إلى مجموعة IWP ومجموعة AWP على فيسبوك واستغلّهما بأريحية. حاول أن تقيم علاقة مع مطوِّر متمكِّن في مجالك، واعرض عليه أن تعطيه أجرًا على أساس الساعة مقابل أن يساعدك في استكشاف الأخطاء التقنية وإصلاحها عند الحاجة. في ماذا تتخصَّص؟ ليس من السهل أن تكون «مجرَّد مطور ووردبريس»؛ فما يقع تحت هذا المُسَّمى ضيِّق إلى حدٍ ما، كما أنَّك قد تسمع الأسئلة الآتية من العملاء: من الرائع أنَّك قمت بتثبيت الإضافة المناسبة، ولكنَّها تبدو الآن سيئة للغاية، هل يمكنك أن تجعلها أكثر أناقة وعصرية ومتناغمة مع هوية علامتنا التجارية؟ يخبروننا أنَّنا من المفترض أن يكون لدينا قسم المدونة، ولكن لا أملك أدنى فكرة عمّا أكتب فيه. أريد أن يكون موقعي الإلكتروني متوافقًا مع محركات البحث، هل تستطيع تحقيق ذلك؟ هل ينبغي علينا إنشاء نشرة بريدية؟ هل نحن بحاجة إلى أن يكون لدينا حساب إنستجرام وماذا ننشر عليه؟ متى سيبدأ الموقع الإلكتروني في تحقيق المبيعات؟ تشير كل هذه الأسئلة إلى مجموعة من المهارات التي تقع خارج حدود المهارات الأساسية الخاصة بتطوير الووردبريس، ومن المؤكَّد أنَّك ستجذب لنفسك المزيد من الانتباه في سوق العمل إذا كنت قادرًا على تقديم المساعدة في مجالات متعددة. على حد علمي، فإنَّ أفضل تخصُّص من التخصصات الواقعة ضمن الحدود التقنية لتطوير الووردبريس هو التجارة الإلكترونية، خاصةً الووكومرس. إنَّه في الوقع عالم قائم بذاته، وهناك الكثير من الأموال التي يمكن جنيها من خلاله لأنَّ العملاء أنفسهم في هذا المجال يجنون الأموال. اقتراحي الوحيد هو أن تبدأ التعامل مع العملاء الذين يستخدمون الووكومرس بتواضع؛ فالووكومرس يتطلَّب بضعة مئات من الساعات حتى تتمكَّن من فهمه جيدًا لأنَّ الزبائن سيأتونك بمختلف الحالات الفريدة، وإذا كنت تتقدَّم بغرور، فمن الممكن أن تتسبَّب في انهيار أعمال ومشاريع حقيقية، وليس مدونات مختصَّة بالسفر. المهارات التكميلية لتطوير الووردبريس أفضل ما يمكن القيام به -من وجهة نظري- هو أن تبني مجموعة مهارات خارج إطار تطوير الووردبريس، وأن تبيع خدماتك كحزمة واحدة. تشمل المسمَّيات الوظيفية الرئيسية الأخرى -غير «مطور ووردبريس»- التي يحتاجها معظم العملاء ما يلي: خبير SEO. مصمِّم ويب وجرافيك. مسوِّق إلكتروني: التسويق عبر وسائل التواصل الاجتماعي والتسويق بالمحتوى. كاتب محتوى (يتطلَّب فهمًا عميقًا لتحسين محركات البحث والتسويق بالمحتوى). إذا كنت تمتلك ذوقًا بصريًا، فمن الرائع أن تكون مصمِّمًا/مطوِّرًا. إذا كنت تجيد المهارات العامة لحل المشكلات، فمن المرجَّح أن يكون تعلُّم واحتراف SEO أقل تعقيدًا من تعلُّم تطوير الووردبريس بالنسبة لك، كما أنَّهما يشكِّلان معًا مزيجًا رائعًا. إذا كنت شخصًا اجتماعيًا، فإنَّ الكثير من العملاء لا يملكون أدنى فكرة عن كيفية التسويق لأنفسهم وهم بحاجة ماسَّة تمامًا إلى توضيحات بشأن هذا الأمر. إذا كنت تستطيع الكتابة، فهذا رائع، ولكنَّك أيضًا ستحتاج معظم الأمور المذكورة أعلاه. تحديد الأشياء غير الملموسة التي تجعلك متفرِّدًا لقد خاض العديد من الأشخاص الكثير من التجارب السيئة مع مطوِّري الووردبريس. كيف تميِّز نفسك عنهم بناءً على هذه المعلومة؟ هل أنت ودود على نحو استثنائي؟ متجاوب على نحو استثنائي؟ هل أنت شريك في الاستراتيجية الخاصَّة بالعميل (على العكس من شخص ينجز ما يطلبه الناس منه فحسب)؟ هل لديك أسلوب تسعير استثنائي يتَّسم بالوضوح والشفافية؟ أو قدرة استثنائية على التغيير والتحسين بسرعة وفاعلية؟ أو قدرة استثنائية على التكيُّف مع ميزانية ضئيلة؟ تكون الإجابات في الوضع المثالي «نعم»، ولكن ما يهم هو قضاء بعض الوقت في معرفة الأسباب التي ستجعل العملاء سعداء بتوظيفك أنت بدلًا من توظيف شخص آخر بنفس السعر لإنجاز نفس العمل. ما هي الأشياء غير الملموسة المرتبطة بطريقتك في إنجاز الأعمال بصفتك مطور ووردبريس حر والتي تجعل العمل معك هو الخيار الأمثل لعملائك المحتملين؟ عندما تكون مدركًا لهذه الأشياء غير الملموسة، وعندما تدعمها بطريقة تعاملك على الهاتف، وطريقة عرضك لإنجازاتك وشهاداتك وما إلى ذلك، سيبدأ الناس حينها في إيلاء الاهتمام لك. التعاقد مع محترفين في المجالات الأخرى في الحقيقة، لا يستطيع شخص واحد فقط أو حتى شخصان امتلاك جميع المهارات التي يحتاجها العملاء العاديون لجعل مشاريعهم ناجحة في سوق العمل، ولذلك ستحتاج إلى تكوين علاقات مع أشخاص محترفين يمتلكون المهارات التي لا تمتلكها، وستُحيل إليهم عددًا من الأعمال، والأمر الرائع أنَّهم سيُحيلون إليك أعمالًا أيضًا! خلاصة الموضوع هي أنَّ الأعمال التي قد تحتاج إلى أن تسندها للغير تتضمن الآتي: خبير SEO. مصمِّم ويب وجرافيك. مسوِّق إلكتروني: التسويق عبر وسائل التواصل الاجتماعي والتسويق بالمحتوى. كاتب محتوى (يتطلَّب فهمًا عميقًا لتحسين محركات البحث والتسويق بالمحتوى). إذا كنت لا تعلم أين تبدأ في العثور على هؤلاء الأشخاص، فاذهب إلى اللقاءات المحلية التي تُنظَّم للحديث عن المهارة التي تبحث عنها. كن مطور ووردبريس حر: الأمور العملية الأساسية التي ينبغي مراعاتها هذا القسم هو الأقل أهمية من بين الأقسام الثلاثة، وهو يتحدَّث عن الأشياء الملموسة التي ينبغي أن تقوم بها لكي تصبح جاهزًا للانطلاق في رحاب العمل الحر في مجال تطوير الووردبريس. إجمالًا، ينبغي أن يكون توجُّهك مبنيًا على السرعة والبساطة؛ افعل أبسط وأرخص الأشياء بقدر ما تستطيع لأنَّ الأمر برُمَّته مرتبط بأن تعثر على العملاء المناسبين (جانب استراتيجي) وأن تعرض عليهم القيمة أو الخدمة المناسبة (جانب استراتيجي وتقني) حتى ينجح عملك ويستمر. سنتحدَّث الآن عن التفاصيل. تسجيل عملك ليصبح رسميًا يمكنك تأجيل هذا الأمر حتى تجد نفسك جادًّا بشأنه، ولكن هناك مزايا من حيث الضرائب والالتزامات لكونك مسجَّلًا رسميًا عندما تبدأ في الحصول على عوائد حقيقية. لقد سجَّلنا أنفسنا كشركة تجارية صغيرة (مدرجة تحت تصنيف S Corp في الولايات المتحدة) من خلال شركة Rocket Lawyer (شركة LegalZoom تقدِّم خدمات مماثة)، وكانت تكلفة ذلك رخيصة نسبيًا ولم تتجاوز 500$. عمومًا، كلَّما استطعت أن تولي اهتمامًا أقل لهيكل الشركة، كان ذلك أفضل من واقع تجربتنا. بناء موقع إلكتروني لعرض نماذج أعمالك بصفتك مطور ووردبريس حر قد بدأ رحلته للتو، فسوف تحتاج إلى مراعاة المعايير الثلاثة التالية عندما تبني موقعًا إلكترونيًا تعرض فيه نماذج أعمالك: أن يبدو احترافيًا. أن يبيِّن مكانتك التي ترغب في إظهارها. أن يكون رخيص الثمن ويُبنى بسرعة. لا ينبغي عليك الاهتمام كثيرًا بتفاصيل الموقع الذي ستعرض فيه أعمالك وكأنَّه جزء مهم جدًا من عملك؛ بل يكفي أن تجعل هدفك هو أن يبدو الموقع احترافيًا وأن يعرض علامتك التجارية بطريقة مناسبة، ولا يجب أن يكون مبتكَرًا للغاية أو مبنيًا من نقطة الصفر (ربما تودُّ القيام بهذا لكي تثبت أنَّك قادرٌ على بنائه؟!) أو ما شابه ذلك. إذا كنت لا تعلم من أين تبدأ، فأقترح عليك إلقاء نظرة على متاجر القوالب المذكورة فيما بعد. لا بأس في أن تدفع بضعة مئات من الدولارات لمصمِّم جيِّد مقابل حصولك على نصائح بخصوص الشعار وتصميم الموقع إذا لم تكن متمكِّنًا في هذا المجال. لكن -إجمالًا- ينبغي أن يكون هذا المشروع رخيص الثمن وبسيطًا، وأن يكون التركيز منصبًا على المحتوى: كيف ستُظهِر مكانتك من خلاله؟ هل يبيِّن موقعك للزوَّار لماذا ينبغي عليهم أن يختاروك أنت بدلًا من اختيار غيرك بطريقة مقنعة؟ تحتاج -أيضًا- إلى أن يكون في موقعك قسم يعرض نماذج أعمالك حتى تثبت للآخرين أهليتك. إذا كنت جديدًا في عالم التطوير، ففي هذه الحالة عليك أن تكون مبدعًا؛ فمثلًا: إذا كنت قد تطوَّعت في المكتبة المحلية وأجريت بعض التحسينات على الموقع الإلكتروني الخاص بها، يمكنك أن توضِّح ذلك في معرض أعمالك. يعتبر وجود عنصر أو عنصرين في معرض أعمالك كافيًا للبدء في العمل الحر في مجال تطوير الووردبريس، إلى جانب قدرتك على أن تشير إلى خبرتك السابقة أثناء تفاعلك مع العملاء. العتاد أقصد بكلمة «عتاد» المعدَّات والأجهزة التي تحتاجها للقيام بعملك، وأهم ما يمكنني إخبارك به في هذا السياق هو أنَّ طراز العتاد لا يهم. سأذكر فيما يلي قائمة المعدَّات التي أستخدمها لتنفيذ عملي بصفتي مطور ووردبريس حر: حاسوب محمول يمكن لأي حاسوب محمول قد صُنع خلال السنوات العشر الماضية أن يؤدِّي الغرض. أنا أستخدم جهازًا يعمل بنظام ويندوز، ولكن إذا كنتَ شخصًا قابلًا للتكيُّف، فمن الأفضل لك استخدام جهاز ماك. يكره الأشخاص التقنيّون نظام ويندوز، ويفترضون أنَّك تستخدم نظام الماك عندما يكتبون شروحاتهم. يعتبر سطر الأوامر في نظام ويندوز سيئًا، ولكن لن يشكِّل هذا مشكلة حقيقية لعملك إلا إذا كنت تقضي زمنًا حقيقيًا وأنت تعمل على سطر الأوامر، وحتى لو كان الحال كذلك فهو ليس بدرجة كبيرة من السوء. هاتف لقد أضعت هاتفي القديم مؤخرًا، لذلك أحضرتُ بديلًا له من متجر وول مارت بقيمة 30$، ولكن من الضروري امتلاك هاتف في جميع الأحوال. سماعات الرأس السماعات التي تحجب الضوضاء جيِّدة حقًا، ولكن لا بأس في سماعات الأذن رخيصة الثمن إذا كانت ميزانيتك محدودة. ميكروفون أستخدم ميكروفون Blue Yeti حوالي مرتين في الشهر لتسجيل مقاطع فيديو، كما أستخدمه إذا لم يكن صوتي واضحًا أثناء إجراء المكالمات عبر برنامج Zoom أو برنامج Skype، ولكن من المؤكَّد أنَّ الميكروفون من الأجهزة التي يمكن تأجيل شرائها. البرامج العملية المطلوبة لا تساعدك هذه البرامج في تطوير الووردبريس بطريقة مباشرة، ولكنَّها مهمة لتنظيم وإنجاز عملك. برامج إدارة الوقت أنت بحاجة إلى معرفة الطريقة التي تمضي بها وقتك، وذلك لزيادة الوقت الذي تتقاضى عليه أجرًا ولتحديد مقدار المال الذي ستطلبه من زبائنك. إنَّ برنامج Toggl جيِّد لهذا الغرض. برامج إدارة الحسابات وجدول الرواتب يُعَدُّ برنامج QuickBooks Online جيّدًا لإدارة الحسابات وإعداد الفواتير، ويمكنك استخدامه أيضًا لجدول الرواتب إذا أردت. نحن نلجأ إلى شركة محاسبة قانونية محلية معتمدة، وهذا يفيدنا جدًا لأنَّها تتولّى كل أمورنا المتعلقة بالاستقطاعات والضرائب، ونحن واثقين من صحة ما تقوم به. تصل قيمة التكاليف الخاصة بنا إلى 60$ شهريًا مقابل الرواتب وحوالي 700$ سنويًا مقابل الضرائب. برامج مكالمات الفيديو إنَّ برنامج Zoom ممتاز. ينبغي أيضًا أن يكون لديك برنامج Skype، ولكن أرى أنَّه يزداد سوءًا منذ أن اشترته شركة مايكروسوفت. برامج تخزين الملفات أحبُّ استخدام دروب بوكس وجوجل درايف، والنسخة المدفوعة من دروب بوكس جديرة بالشراء إذا لم تكن تعاني من ضائقة مالية. برامج إدارة المشاريع يُعَدُّ برنامج Trello رائعًا، وهو مناسب للاستخدام الفردي، ولإدارة المشاريع مع فريق العمل، ولإدارة المشاريع الخاصة بالعملاء أيضًا. برامج الدردشة والمحادثة إذا كان لديك شركاء في العمل، فقد تحتاج إلى امتلاك حساب مجاني في برنامج Slack حتى تتعاونوا مع بعضكم بعضًا. برامج تعديل الصور بطبيعة الحال، من المهم أن يكون لديك معرفة بسيطة بكيفية تعديل الصور. يعدُّ برنامج GIMP جيّدًا جدًا ومجانيًا وهو نسخة مقلَّدة من برنامج الفوتوشوب. أنصحكم بالحصول عليه وتعلُّم أساسياته. كن مطور ووردبريس حر: الأمور التقنية الأساسية التي ينبغي مراعاتها على الأرجح أنَّك كنتَ تظنُّ أن يكون محور حديث المقال كلّه حول هذا القسم التقني، والذي ستتعرف من خلاله على المهارات البرمجية التي أنت بحاجة إلى امتلاكها حتى تبدأ في التسويق لنفسك كمطور ووردبريس حر. من المؤكَّد أنَّ هذا القسم مهم جدًا، وبدونه لن تقوم لك قائمة في العمل الحر في مجال تطوير الووردبريس. سنتناول فيما يلي بشيء من التفصيل عناصر الووردبريس التقنية الأساسية التي ينبغي أن تكون على علم بها بصفتك مطور ووردبريس حر. ما المشاريع التي تصلح الووردبريس في تطويرها؟ لماذا؟ متى تستخدمها؟ ما الذي يجعل الووردبريس مُجديًا؟ لماذا هو أفضل من Joomla ومن Drupal؟ لماذا ينبغي أن أستخدم الووردبريس في تطوير موقعي؟ أخبرني رئيسي أنَّ الووردبريس غير آمنة، فهل هذا صحيح؟ يوجد لدى موقع GoDaddy منشئ صفحات خاص به، فلماذا لا أستخدمه؟ أليس تكلفة إنشاء المواقع باستخدام Wix أرخص بكثير إذا أخذنا في الاعتبار الاستضافة وغيرها من الأمور؟ تحتاج إلى أن يكون لديك إجابات ذكية عن هذه الأسئلة، وليس ذلك لكي تخبرها لعملائك فحسب، ولكن لكي تكون أيضًا مدركًا للخدمات التي تقدِّمها في سوق العمل. إنَّ تحديد البرامج التي ستستخدمها ومعرفة طبيعة عملها -ما يمكنها القيام به وما لا يمكنها القيام به وكيف تتوافق مع البرامج الأخرى- هو من المسائل التقنية. ستقدِّم لك المقالات التالية إرشادات عامة بشأن الأسباب التي تدفعك إلى استخدام الووردبريس، وبشأن الحالات المناسبة لاستخدامها: المقال الأول: يستعرض مخطط يعطي فكرة بسيطة ومفيدة عن أنواع المشاريع التي تكون الووردبريس مناسبة لها وأنواع المشاريع التي لا تكون الووردبريس مناسبة لها. المقال الثاني: يتحدَّث فيه شريكي ديفيد عن الأسباب التي تدفعك لاستخدام الووردبريس. المقال الثالث: يقدِّم مقدمة عن Squarespace، ويبيِّن الحالات التي يكون فيها استخدام Squarespace أنسب من استخدام الووردبريس والعكس. البرامج المخصَّصة للمطورين ينطبق هنا ما ذكرناه سابقًا وهو أنَّ «طراز العتاد لا يهم»، إذ ينبغي أن تكون البرامج التي تستخدمها للتفاعل تقنيًا مع الووردبريس بسيطة جدًا. أخبرني بيبين ويليامسون (Pippin Williamson) ذات مرة بأنَّ البرامج المثبَّتة على حاسوبه المحمول بسيطة لدرجة أنَّه يستطيع إلقائه في بحيرة وأن يكون جاهزًا بعد 30 دقيقة للعمل على حاسوب جديد. أن يأتي هذا الكلام من المسؤول عن شركة تقدَّر قيمتها عدة ملايين من الدولارات وتعمل في مجال تطوير إضافات الووردبريس، فهذا يعني أنَّ مطوِّري الووردبريس المستقلين بإمكانهم أن يقوموا بالشيء ذاته. البرامج التي أحتاجها لإنجاز أي مشروع عادي هي: Sublime Text لتحرير النصوص البرمجية. FileZilla لنقل الملفات عبر بروتوكول نقل الملفات. WAMP الذي يمكن من خلاله تشغيل برامج الويب وتطويرها على شبكة محلية (أو MAMP لمستخدمي نظام الماك). متصفح ويب؛ أُفضِّل استخدام متصفح جوجل كروم وأدوات المطوِّر التي يوفرها. في الحقيقة، هذه البرامج فقط هي البرامج التي ستحتاجها للعمل على معظم المشاريع، وجميعها مجانية، ولن يستغرق معك تعلُّم أساسيات كلٍ منها أكثر من ساعة واحدة. المعرفة الأساسية باللغات التقنية اللغات الأساسية الأربعة اللازمة لتطوير الووردبريس -مرَّتبة حسب أهميتها- هي: PHP، وHTML، وCSS، وJavaScript. من الجيِّد أن يكون لديك خبرة بسيطة باللغات الثلاثة الأولى، ولكن حتى لو لم يكن لديك خبرة في لغة PHP، فإنَّه يمكنك -إلى حدٍ ما- أن تتعلَّمها من خلال تعلُّمك للنظام الأساسي الخاص بالووردبريس. لذا، إذا كنت لا تعرف استخدام لغة PHP، فأقترح عليك أن تتعلَّم PHP بينما تتعلَّم كتابة الشيفرات البرمجية في الووردبريس، لا أن تتعلَّمها على حدة، إذ أنَّ الووردبريس لا تستخدم إلا جزءًا صغيرًا من لغة PHP، وما تستخدمه في الواقع مخصَّص لها فقط بدرجة كبيرة. بعبارة مشابهة: من الأفضل لك أن تتعلَّم كيفية إنشاء أحواض السباحة بدلًا من أن تحصل على شهادة في الهندسة المعمارية بهدف أن تتمكَّن من إنشاء أحواض السباحة (إذا كان ذلك منطقيًا). إذا حاولتَ تعلُّم شروحات تطوير الووردبريس ووجدتَ نفسك تائهًا، فقد تكون بحاجة إلى علاج سريع لمواطن قصورك في أي لغة من اللغات السابق ذكرها والتي تمنعك من إحراز أي تقدُّم. نصيحتي لك هي اللجوء إلى موسوعة حسوب التي تقدِّم معلومات وافية عن كل لغة من هذه اللغات. إذا كان لديك معلومات تقنية عامة، يمكنني القول بأنَّ أسبوعًا من التعلُّم الجادّ للغات PHP و HTML و CSS كافٍ جدًا للدخول إلى صُلب الموضوع ألا وهو تعلُّم تطوير الووردبريس. أساسيات تطوير الووردبريس أعرض فيما يلي قائمة تحتوي على عدد من مفردات الووردبريس العشوائية التي تستثير ذاكرتك لكي تختبر مدى تقدُّمك في مجال تطوير الووردبريس، وينبغي أن تحفِّز كل مفردة من هذه المفردات مطوِّري الووردبريس المتمرِّسين على استحضار الكثير من الارتباطات والخبرات والذكريات والأفكار. add_action, add_filter, functions.php, stylesheet, customizer, wp_enqueue_script, wp_enqueue_style, the Loop, get_template_part, add_image_size, get_post_meta, get_the_content, get_the_ID, the_title, new WP_Query, template hierarchy, $args, foreach, is_singular, get_header, get_footer, Plugin Name: , Template: , while, wp_reset_postdata, update_option, get_option, add_shortcode, do_shortcode, get_the_terms إذا بدا لك كل ما في القائمة مألوفًا، فمن المؤكَّد أنَّك مطور ووردبريس بدرجة ما. كلَّما زاد عدد المفردات الغامضة بالنسبة لك، كان هذا مؤشِّرًا على أنَّك بحاجة إلى المزيد من الدراسة والمزيد من الخبرات حتى تصبح ضليعًا في تطوير الووردبريس. ملاحظة بشأن هذا التمرين: تتضمن القائمة السابقة بعض المفردات الأساسية التي اختيرت عشوائيًا والتي ينبغي على كل مطور ووردبريس أن يعلمها، ولا تحتوي القائمة على جميع -أو حتى معظم- المفاهيم الأساسية في مجال الووردبريس. يجب على جميع مطوِّري الووردبريس أيضًا أن يعلموا كيف يتناغم كل مفهوم من مفاهيم التطوير مع النظام التقني الكلي للووردبريس لكي يتمكَّنوا من استخدامه بالطريقة السليمة. إنَّ هذا التمرين هو مجرَّد اختبار عشوائي لتحديد مدى إلمامك ببعض المفردات الأكثر شيوعًا في مجال تطوير الووردبريس. أدوات تقنية أساسية تابعة لأطراف خارجية هذه الأدوات هي عبارة عن تقنيات الووردبريس الخارجية -مثل: القوالب، والإضافات، ومواقع الاستضافة، وغيرها- التي تؤثِّر بطريقة مباشرة على قدرتك على تقديم قيمة لعملائك. ينبغي عليك أن تحدِّد بعض الحلول التقنية التي ستلجأ إليها لكي تقدِّم المساعدة لعملائك عند الحاجة. شركة استضافة ينبغي أن تكون على علم دائم بشركة الاستضافة التي ستنصح عملاءك بالتعامل معها. أقترح أن يقع اختيارك المبدئي على شركة SiteGround (أو شركة WP Engine إذا احتاج العميل أو طلب استضافة مُدارة (managed hosting)). يمكنك معرفة المزيد من التفاصيل عن الأسباب التي جعلتنا نفضِّل هذا الخيار من خلال هذا الرابط. ينبغي أن تعلم أيضًا ما إذا كان نقل الموقع إلى استضافة أخرى يستحق العناء. بوجه عام، تكون عملية النقل ملائمة أكثر في الحالات التالية: هناك موقع واحد فقط على حساب الاستضافة. لا يزال الموقع في بداياته؛ وذلك حتى لا تضطر إلى ترحيل عشرات الرسائل الإلكترونية على سبيل المثال. المشكلات الموجودة في الاستضافة الحالية تُعيق الموقع عن النجاح؛ وليست مجرَّد مصادر إزعاج. ينبغي توجيه الانتباه للحالة الثالثة، إذ أنَّ الاستضافة البطيئة حد الإزعاج والمشكلات المرتبطة ببروتوكول SSL والدعم التقني السيئ وغيرها جميعها مصادر إزعاج رئيسية، ولكن لا تشكِّل هذه المشكلات عوائقًا استراتيجية أمام نجاح الموقع إلا في بعض الأحيان. إذا شعرت بأنَّ الاستضافة السيئة عائق استراتيجي، فاشرع في عملية النقل. أمَّا إذا كانت مجرَّد مصدر إزعاج، فتكيَّف معها. من الصعب التمييز بين الأمرين، ولكن سيزداد ذلك سهولة بمرور الزمن. منشئ النماذج (Form Builder) على الأغلب أنَّ النماذج هي أكثر الطرق شيوعًا لتفاعل المستخدم على مواقع الووردبريس، وتعتبر نماذج الاتصال (Contact forms) من الأمثلة الواضحة عليها. يمكننا إنشاء النماذج لأي غرض نريده بما في ذلك التسجيل للفعاليات أو حتى من أجل تفاعلات المستخدم المعقدة مثل التطوع لتبنِّي حيوان أليف. بالنسبة لي، أستخدم إضافة Gravity Forms لإنشاء النماذج. مع أنَّ هناك بعض الأشياء التي لا يمكنها القيام بها، إلا أنَّها خيار أولي ممتاز لإنشاء أي نموذج أحتاجه تقريبًا إلى أن يدفعني المشروع على استخدام خيار آخر. تُعَدُّ إضافة Ninja Forms وإضافة Caldera Forms من الإضافات الجيِّدة أيضًا، كما أنَّ إضافة Contact Form 7 مجانية وممتازة في إنشاء نماذج الاتصال. سأكون مرتابًا حيال استخدام أي إضافة لم أتطرَّق إلى ذكرها لإنشاء النماذج؛ فمع أنَّ هذا سيكون جائرًا بحق المشاريع الآخرى وبحق مطوِّريها، إلا أنَّ الإضافات التي ذكرتُها هي الخيارات الجيِّدة ذائعة الصيت، ومن غير المحتمل أن تحلَّ الخيارات الأخرى مشكلات لا تستطيع هذه الإضافات أن تحلَّها. منشئ الصفحات (Page Builder) يوجد في وقتنا الحالي إضافة ووردبريس جيِّدة جدًا لإنشاء الصفحات تُسمَّى Beaver Builder، وقد أحدثت تغييرًا جذريًا على الطريقة التي أعمل بها في مجال الووردبريس. من وجهة نظري، ينبغي عل كل مطور ووردبريس حر أن يحصل عليها وأن يتعلم كيفية استخدامها وأن تكون خياره الأول عندما يطلب منه العملاء إنشاء صفحة بتخطيط مخصَّص. إذا كنت ترغب في معرفة سبب تفضيلي لإضافة Beaver Builder عن برمجيات إنشاء الصفحات الرئيسية الأخرى، فقد كتبتُ مقالاً يقارن بطريقة مفصَّلة بين أربعة منها، ويمكنك الاطّلاع عليه من خلال هذا الرابط. ماذا عن استخدام Gutenberg؟ ماذا عن استخدام حلول إنشاء الصفحات التي توفِّر خدمة الاستضافة مثل Squarespace؟ دائمًا ما كنتُ متحمِّسًا لتجربة تأليف وتحرير المحتوى في الووردبريس، ولذلك كتبتُ الكثير بشأن هذا الموضوع خلال السنوات القليلة الماضية، وكتبتُ خصوصًا عن طريقة التفاعل المعقَّدة بين تقنيات معينة مثل Squarespace و Beaver Builder و Gutenberg، وألخِّص فيما يلي النقاط الرئيسية: لن تتسبَّب Gutenberg في اندثار إضافات الووردبريس مثل Beaver Builder في وقت قريب، حتى بعد صدور نسخة ووردبريس 5.0. أصبحت إضافة Beaver Builder أفضل من ذي قبل بعد صدور النسخة 2.0 منها (وهو من أفضل الإضافات لإنشاء صفحات الووردبريس من وجهة نظري). تجربة تأليف المحتوى باستخدام Squarespace أكثر روعة منها في Beaver Builder، كما يعتبر Squarespace تقنية أبسط من الووردبريس بوجه عام إذا أخذنا في الاعتبار الاستضافة وغيرها، وهو خيار جيِّد للمواقع البسيطة جدًا. أمّأ Beaver Builder فهو يوفِّر تجربة مشابهة للمشاريع التي تتطلَّب استخدام الووردبريس. ينبغي عليك أن تبتعد عن معظم إضافات الووردبريس الأخرى الخاصَّة بإنشاء الصفحات. من الصعب جدًا تطوير منشئ صفحات جيِّد للووردبريس، وقد بُنيت معظم المشاريع التي تهدف لذلك على نهج خطأ تمامًا (خاصةً اعتماد عناصر تخطيط الصفحة على الأكواد المختصرة). يعدُّ Visual Composer وDivi Builder أضخم مشروعين ولكنَّهما –أيضًا- من أسوأ المشاريع. تعدُّ إضافة Elementor من الإضافات الجيِّدة، ولكنَّني شخصيًا أُفضِّل Beaver Builder. القوالب ومتاجر القوالب من الصعب العثور على القوالب الجيِّدة، إذ أنَّ سوق القوالب يعجُّ بالقوى السوقية التي تعطي أولوية للمظاهر الفارغة على حساب محتوى القوالب وتصميمها المتقَن. إنَّ بناء موقعك الإلكتروني بالاعتماد على قالب سيئ هو أحد أسهل الطرق التي تجعل المشروع فظيعًا. من المؤكد أنَّه ينبغي عليك العثور على المتجر الذي تراه مناسبًا، ولكن أنصحك بالابتعاد عن متجر ThemeForest، وأقترح عليك متاجر القوالب الأتية: Solo Pine Elmastudio ThemeBeans Codestag قد ترغب في الاستغناء تمامًا عن القوالب التجارية نتيجة التطوُّر الكبير الذي طرأ على برامج إنشاء الصفحات. عمومًا، يُعجبني Understrap كقالب يمكن استخدامه لجميع الأغراض، وStorefront كقالب يمكن استخدامه للووكومرس، ولكن عليك أن تعلم بأنَّ قالب Understrap متقدم للغاية (يملك حوالي 8000 ملف على شكل اعتماديات وجميعها مرتبطة بمنفذات مهام [task runners] ومدراء الاعتماديات [dependency managers] وأوراق أنماط Sass المُصرَّفة وما إلى ذلك)، أمَّا قالب Storefront فيعتمد على مبدأ الخطافات (hook-based) بدرجة كبيرة. من الجيِّد أيضًا أن تتعلَّم كيفية تقييم القوالب قبل شرائها من خلال هذا الرابط. ينبغي عليك أيضًا أن تبتعد عن صنفين من القوالب وهما: القوالب القبيحة متعددة الأغراض الموجودة على متجر ThemeForest، وأي قالب يوفِّره موقع Elegant Themes بما في ذلك قالب Divi بصورة خاصة (يؤسفني قول هذا). حلول النسخ الاحتياطي وتصدير البيانات شخصيًا، لستُ مواظبًا على القيام بالنسخ الاحتياطي اليدوي كما "ينبغي" أن أكون، وذلك لأنَّ شركة SiteGround تحتفظ بنسخ احتياطية، ودائمًا ما أنقذني هذا في الحالات النادرة التي أفسدتُ فيها شيئًا. تجدر الإشارة -أيضًا- إلى نظام النسخ الاحتياطي الأوتوماتيكي الرائع الخاص بشركة WP Engine](e بسبب الخدمات التي تقدِّمها. من المؤكَّد أنَّ عملية النسخ الاحتياطي مهمة، وتعتبر إضافة BackupBuddy خيارًا جيِّدًا للقيام بها. إنَّ إضافة All-in-One WP Migration هي من حلول النسخ الاحتياطي وتصدير البيانات التي تعجبني بشدة. يمكنني الجزم بأنَّ هذه الإضافة يمكن الاعتماد عليها وهي توفِّر عليك الوقت على نحوٍ لا يُصدَّق، كما أنَّها تقدِّم حلًا كاملًا لإجراء النسخ الاحتياطي -كما هو واضح من اسمها-، إذ أنَّها تخزِّن بيانات موقعك بالكامل. الخلاصة تحدَّثنا في هذا المقال عن كيفية الاستعداد للانطلاق في العمل الحر في مجال تطوير الووردبريس، وقد تحدَّثنا عن أمور كثيرة، أليس كذلك؟ لا تُجهد نفسك، إذ أنَّك سوف تتقن هذه الأمور بمرور الزمن دون أن تضطر إلى التخطيط لجميع هذه الأمور مسبقًا. هذا المقال بمثابة الدليل الذي سيرشدك إلى "عيش حياة سعيدة". هناك الكثير من الأمور التي ينبغي التفكير فيها، ولكن لا يُشترط التفكير فيها جميعًا دفعة واحدة ولا قبل أن يحين وقتها. أتمنى أن يكون هذا المقال قد بيَّن لك الطريق الذي عليك أن تسلكه لكي تصبح مطور ووردبريس حر، وأن يكون أيضًا قد نبَّهك إلى نقاط ربما كنتَ غافلًا عنها. معظم الأمور التي ذكرتُها هي أمور تجاهلتُها حتى لم يعد أمامي خيار سوى التعامل معها، ولذلك كان الطريق الذي سلكتُه كمطور ووردبريس حر أطول وتشوبه الكثير من الصعوبات. إذا كان لديك أفكار أخرى عن كيفية الاستعداد للانطلاق في العمل الحر في مجال تطوير الووردبريس، فأخبرنا بها من خلال التعليقات. ترجمة -وبتصرف- للمقال Become a Freelance WordPress Developer: How to Make a Career of It لصاحبه Fred Meyer
-
- 5
-
- تطوير الويب
- تصميم المواقع
- (و 3 أكثر)
-
Lighthouse هو أداة مُؤَتمتة (Automated) مفتوحة المصدر لتحسين صفحات الويب. يمكن تطبيق الأداة على أي صفحة ويب سواء كانت عامّة أو تحتاج للاستيثاق (Authentication). يمكن استخدام الأداة للتدقيق في الأداء، قابليّة الوصول (Accessibility)، صفحات الويب التقدميّة (Progressive web apps) وغيرها. تستطيع تشغيل Lighthouse من أدوات المُطوّر في Chrome أو سطر الأوامر أو بصيغة وحدة Node. تستقبل الأداة Lighthouse رابط URL لتدقيقه فتُشغِّل سلسلة من التدقيقات على الصفحة ثم تولّد تقريرًا عن حالة الصفحة. اعتمد على التقرير واستخدم التدقيقات التي أخفقت فيها الصفحة دليلا لكيفية تحسينها. يوجد في كلّ تدقيق توثيق مرجعي يشرح أهميّة التدقيق وكيف تصلح الصفحة لتتوافق معه. البداية اختر سير عمل Lighthouse الذي يناسبك: أدوات التطوير في Chrome. دقّق الصفحات التي تحتاج الاستيثاق بسهولة واقرأ التقارير بصيغة مفهومة للمستخدم. عبر سطر الأوامر. أتمت تشغيلات Lighthouse بسكربتات Shell. وحدة Node. ادمج Lighthouse في نظام التكامل المستمر (Continuous integration) الخاصّ بك. ملحوظة: تتطلّب كل واحدة من طرق العمل في Lighthouse وجود Google Chrome مثبَّت على جهازك. شغّل Lighthouse من أدوات تطوير Chrome يشغّل Lighthouse لوحة Audits في أدوات تطوير Chrome. اتبع الخطوات التالية لتشغيل تقرير: نزّل Google Chrome للأجهزة المكتبية. استخدم Google Chrome لتصفّح الصفحة التي تودّ تدقيقها. يمكنك تدقيق أي صفحة على الوِب. افتح أدوات التطوير DevTools في Chrome. انقر على اللسان Audits. يظهر في يسار الشاشة الإطار المعروض من الصفحة التي ستُدقَّق. تظهر في اليمين لوحة التدقيقات (Audits) التي يشغّلها Lighthouse. انقر على Perform an audit. تظهر أدوات التطوير قائمة بتصنيفات التدقيق. اتركها جميعا مُعلَّمة. انقر على Run audit. يعطيك Lighthouse بعد 60 إلى 90 ثانية تقريرًا عن الصفحة. تثبيت سطر أوامر Node وتشغيله اتبع الخطوات التالية لتثبيت وحدة Node: 1- نزّل Google Chrome للأجهزة المكتبية. 2- ثبّت الإصدار طويل الدعم الحالي من Node. 3- ثبّت Lighthouse. يشير الخيار -g إلى تثبيت الوحدة على مستوى النظام. npm install -g lighthouse 4- نفّذ الأمر التالي لتنفيذ تدقيق: lighthouse <url> 5- لعرض خيارات التدقيق: lighthouse --help تشغيل وحدة Node برمجيا راجع استخدام هذا الرابط لمثال على تشغيل Lighthouse برمجيًّا على صورة وحدة Node. تشغيل Lighthouse عن طريقة إضافة Extension على Chrome ملحوظة: يُفتَرض استخدام خطة سير عملا مبنية على أدوات المطوِّر في Chrome بدلا من هذه الإضافة، إلا إذا كان لديك سبب خاصّ. تُوفّر أدوات المطوّر في Chrome نفس الفوائد التي توفّرها الإضافة، علاوةً على كون الأدوات لا تحتاج لتثبيت. اتبع الخطوات التالية لتثبيت الإضافة: نزّل Google Chrome للأجهزة المكتبية. ثبّت إضافة Lighthouse من مخزن إضافات Chrome. اتبع الخطوات التالية لتشغيل تدقيق: استخدم Google Chrome لتصفّح الصفحة التي تودّ تدقيقها. انقر أيقونة Lighthouse. يُفتَرَض أن توجد الأيقونة بعد شريط العنوان في Chrome. إن لم تكن هناك، افتح القائمة الرئيسية في Chrome وانقر على الأيقونة في أعلى القائمة. تتمدّد قائمة Lighthouse بعد النقر على الأيقونة. انقر على الزرّ Generate report. يدقّق Lighthouse الصفحة النشطة ثم يفتح لسانًا جديدًا يحوي تقريرًا عن نتائج تدقيق الصفحة. شارك التقارير واعرضها على الشبكة استخدم Lighthouse Viewer (عارض Lighthouse) لعرض التقارير ومشاركتها على الشبكة. شارك التقارير بصيغة JSON يحتاج Lighthouse Viewer إلى مُخرج بصيغة JSON من تقرير Lighthouse. تشرح الخطوات أدناه كيفية الحصول على مُخرج بصيغة JSON، حسب طريقة العمل التي اخترتها. بالنسبة لأدوات التطوير: انقر على تنزيل التقرير (السهم المتّجه إلى الأسفل). سطر الأوامر: lighthouse --output json --output-path <path/for/output.json> إضافة Chrome: انقر على زرّ التصدير Export ثم Save as JSON. لمعاينة بيانات التقرير: افتح Lighthouse Viewer في متصفّح Chrome. اسحب ملف JSON إلى العارض ثم أفلته، أو انقر في أي مكان في العارض لفتح متصفّح الملفّات لديك واختيار الملفّ. مشاركة التقارير عبر GitHub Gists إن لم تكن ترغب في تمرير تقاريرك يدويّا بصيغة ملفات JSON فيمكنك مشاركتها بسريّة عبر خدمة GitHub Gists. أحد فوائد الخدمة هو الحصول على تحكّم مجاني في الإصدارات Version control. اتبع الخطوات التالية لتصدير التقارير إلى GitHub Gists عبر إضافة Lighthouse على Chrome: انقر على Export ثم Open In Viewer. يُفتَح التقرير في العارض المتوفّر على الرابط https://googlechrome.github.io/lighthouse/viewer/. انقر على المشاركة Share في العارض. ستطلُب منك نافذة منبثقة في المرة الأولى السماح بالوصول إلى بياناتك الأساسية على GitHub، وصلاحية القراءة والكتابة على GitHub Gists. أنشئ Gist يدويًّا ثم انسخ التقرير بصيغة JSON وألصقه، إن أردت تصدير التقرير إلى GitHub Gists من سطر الأوامر. يجب أن ينتهي اسم Gist الذي يحوي مُخرَج JSON باللاحقة lighthouse.report.json. راجع هذا الرابط لمثال على كيفية توليد مُخرَج JSON من سطر الأوامر. اختر إحدى الطريقتيْن التاليّتين لعرض تقرير محفوظ على GitHub Gists: . أضف ?gist=<ID> إلى رابط العارض، حيثُ ID هو معرّف Gist: https://googlechrome.github.io/lighthouse/viewer/?gist=<ID> افتح العارض وألصق فيه رابط Gist المساهمة في Lighthouse Lighthouse مفتوح المصدر، ويرحّب مطوّروه بالمساهمة فيه. تحقّق من متتبّع المشاكل Issues tracker في المستودع للعثور على علل (Bugs) يمكنك إصلاحها، أو تدقيقات يمكنك إنشاؤها أو تحسينها. يعدّ متتبّع المشاكل مكانا جيّدا للنقاش حول قياسات التدقيق أو أفكار لتدقيقات جديدة أو أي أمر آخر له علاقة بأداة Lighthouse. ترجمة - بتصرّف - للمقال Lighthouse من موقع مطوّري Chrome.
-
- إضافات كروم
- سهولة الوصول
- (و 4 أكثر)
-
هذا المقال تمت كتابته بتعاون بين Joe Richardson و Robin Rendle ومجموعة من فريق موقع CSS-Tricks. أراد Joe إضافة مقال بخصوص BEM التي أحببناها وكان لدى كل منا أفكارًا وآراءً حولها، لذلك قررنا أن نتعاون سويًا لكتابة هذا المقال. تُعدُّ منهجية BEM (وهي اختصار لهذه الكلمات معًا Block و Element و Modifier) مصطلح تسمية شائع يستخدم من أجل الأصناف في HTML و CSS تم تطويره بواسطة فريق في Yandex؛ هدفها هو مساعدة المطورين في فهم العلاقة بين HTML و CSS في مشروع معين بشكل أفضل. فيما يلي مثال حول ما يكتبه مطور CSS في نمط BEM: /* مكون كتلة */ .btn {} /* عنصر يعتمد على كتلة */ .btn__price {} /* مُعدِّل يعدِّل تنسيق الكتلة */ .btn--orange {} .btn--big {} في شيفرة CSS السابقة، الكتلة (Block) عبارة عن عنصر جديد في أعلى مستوى من التجريد (top-level abstraction) على سبيل المثال زر: .btn{}. يجب اعتبار الجملة البرمجية هذه بمثابة أحد الأبوين، إذ يمكن وضع العناصر الأبناء (elements) في الداخل ويتم الإشارة إليها بواسطة شرطتين سفليتين يتبع اسم الكتلة أو الحاوية البرمجية تلك مثل .btn__price{}. أخيرًا، يمكن للمُعدلات (modifiers) معالجة الحاوية البرمجية (Block) بحيث يمكننا تمييز أو تصميم ذلك المكون المحدد دون إحداث تغييرات على بقية الحاويات البرمجية الأخرى يتم ذلك عن طريق إلحاق شرطتين باسم الحاوية البرمجية Block تمامًا مثل btn--orange. تبدو الشيفرة كما في المثال التالي: <a class="btn btn--big btn--orange" href="http://css-tricks.com"> <span class="btn__price">$9.99</span> <span class="btn__text">Subscribe</span> </a> لو كتب مطور آخر هذه الشيفرة ولم يكن لدينا خبرة في CSS، فيجب أن نأخذ فكرة جيدة عن أي الأصناف ومسؤوليتها وكيف تعتمد على بعضها بعضًا. يستطيع المطورون آنذاك بناء مكوناتهم الخاصة وتعديل الحاويات (الكتل) الموجودة إلى المحتوى الذي يريدونه. يحتمل بدون كتاب مثل شيفرة CSS هذه أن يتمكن المطورون من كتابة عدة مجموعات مختلفة من الأزرار ببساطة عبر تعيير صنف في الشيفرة: في البداية، قد تبدو هذه الصياغة أبطأ من بناء صنف جديد لكل نوع من أنواع الأزرار، ولكن هذا غير صحيح لعدة أسباب سنذكرها. لماذا علينا أخذ BEM في الحسبان؟ إذا كنا نريد إنشاء تصميم جديد لعنصر معين، يمكننا أولًا النظر في الحاويات البرمجية لمعرفة أي المُعدِّلات، والعناصرالفرعية موجودة بالفعل. ربما ندرك أننا لسنا بحاجة لكتابة أي تعبير CSS برمجي آخر لأن هناك معدّل موجود مسبقًا يفي بالغرض. إذا كنا نقرأ الوسوم بدلاً من تعابير CSS البرمجية، يجب أن نكون قادرين على الحصول بسرعة على فكرة حول العنصر الذي يعتمد على عنصر آخر؛ في المثال السابق، يمكننا رؤية أن العنصر .btn__price يعتمد على العنصر .btn، حتى لو لم نكن على دراية بعمل أي من تلك العناصر. يمكن للمصممين والمطورين تسمية العناصر لتسهيل الاتصال بين فريق المطورين بمعنى آخر، يوفر BEM لكل مطور في المشروع تسمية صيغة إعلانية للعناصر يمكنه مشاركتها بحيث تكون في نفس الصفحة. حدد Harry Roberts فائدة رئيسية أخرى لاستخدام صيغة برمجية مثل BEM حين كتب التالي عن تحسين ثقة المطور: "هذا هو السبب الرئيسي الذي يجعلنا ننتهي من قواعد الشفرة المتضخمة المليئة بشيفرات برمجية قديمة وغير قابلة للتعديل من CSS. نحن نفتقر إلى الثقة في أن نكون قادرين على العمل مع الأنماط الحالية وتعديلها لأننا نخشى عواقب أن تعمل CSS عالميًا، إذ هي مشهورة بحد ذاتها. تتلخص كل المشكلات تقريبًا المتعلقة بـ CSS على نطاق واسع في الثقة (أو عدم وجودها)، لذلك لا يقومون بإجراء تغييرات لأنهم لا يعرفون ما هي الآثار لهذه التغييرات على المدى البعيد." وبالمثل، يناقش Philip Walton حل لهذه المشكلة وهو إلتزام عدد كاف من المطورين بمبادئ BEM: "على الرغم من أن الشيفرة القابلة للتنبؤ بنسبة 100٪ غير متوافرة، من المهم فهم المفاضلات التي تجريها مع الطريقة المتبعة في كتابة التعابير البرمجية التي تختارها. إذا كنت تتبع طريقة BEM الصارمة، فستكون قادرًا على تحديث تعابير CSS وإضافة الشيفرات البرمجية الخاصة بك إليها في المستقبل بثقة تامة بأن هذه التغيرات لن يكون لها أي آثار جانبية." لذلك، إذا كان بإمكان المطورين العمل في مشروع بطريقة أكثر ثقة، فإنهم على يقين من اتخاذ قرارات أكثر ذكاءً حول كيفية استخدام هذه العناصر المرئية. قد لا تكون هذه الطريقة حلًا مثاليًا لجميع هذه المشاكل، لكنها بالتأكيد تمنح المطورين معيارًا لكتابة جمل برمجية أفضل وأكثر قابلية للصيانة في المستقبل. هناك جانب آخر جيد في منهجية BEM، وهو أن كل مجموعة جمل برمجية خاصة بعنصر معين توجد داخل حاوية خاصة به ولا يوجد شيء متداخل مما يجعل خصوصية CSS سلسة جدًا ومنخفضة وهذا هو المطلوب. أي أنك لن تجهد نفسك فيما يتعلق بخصوصية تعابير CSS البرمجية. دعونا نلقي نظرة على بعض المشاكل مع BEM. مشاكل مع BEM CSS لن يقوم أحد بمعاقبتك بالطبع إذا خرجت عن قواعد BEM. لا يزال بإمكانك كتابة محدد CSS كالتالي: .nav .nav__listItem .btn--orange { background-color: green; } يبدو أن المثال السابق يحتوي أجزاء من منهجية BEM، لكنه ليس كذلك فهو يحتوي على محددات متداخلة، ولا يصف المُعدِّل (modifier) بدقة ما يحصل في هذه الجمل البرمجية. إذا فعلنا ذلك، فسنكون فشلنا في تحقيق مبدأ الخصوصية وهذا مفيد جدا لمنهجية BEM. يجب ألا تَبطل كتلةٌ (مثل .nav) عمل كتلة أخرى أو معدل آخر (مثل .btn --orange) وإلا فإن هذا سيجعل من المستحيل تقريبًا قراءة ملف HTML وفهم عمل هذا العنصر. في هذه العملية، نحن ملزمون الى حد كبير أن نكون أهلًا لثقة مطور آخر في البرنامج، هذا ينطبق على HTML أيضًا. ماذا تتوقع إذا رأيت الشيفرة التالية؟ <a class="btn" href="http://css-tricks.com"> <div class="nav__listItem">Item one</div> <div class="nav__listItem">Item two</div> </a> ربما ما يحدث في المثال السابق، هو أن عنصرًا في الحاوية البرمجية block يشتمل على الشيفرة التي يحتاجها المطور، لكن العناصر الأبناء لا تحتاج إلى الصنف .nav على أنه عنصر أب. هذه المشكلة تجعل البرنامج استثنائيًّا وغير متسق ومتناقض مع نفسه وينبغي تجنبها بأي ثمن. لذلك، يمكننا تلخيص هذه المشكلات في: عدم استخدام المُعدلات في الحاويات البرمجية block غير المترابطة. تجنب صنع عناصر رئيسية غير ضرورية عندما يكون العنصر الفرعي موجودًا بشكل جيد بدون أي مشاكل. المزيد من الأمثلة العملية على BEM قائمة قابلة للطي: في هذا المثال، هناك حاوية برمجية block واحدة وعنصران ومُعدِّل واحد. يمكننا هنا إنشاء مُعدِّل مثل .accordion__copy-open يتيح لنا معرفة أنه يجب ألا نستخدمه في حاوية برمجية block أو عنصر آخر. قائمة تنقل: يحتوي هذا المثال على كتلة block واحدة و 6 عناصر ومُعدِّل واحد. من الجيد تمامًا إنشاء حاويات برمجية blocks بدون معدلات على الإطلاق. يمكن للمطور في مرحلة ما في المستقبل أن يربط هذه الحاوية بمعدلات جديدة طالما بقيت ثابتة. عيوب BEM ربما لا تحب استخدام شرطة مزدوجة. حسنًا، استخدم شيئًا آخر فريدًا تستخدمه باستمرار. هنا رأي آخر: هذه الثلاثة محددات الأخيرة جميعها لها مستويات خصوصية مختلفة. تحتمل أن يكون لها عنصر رئيسي أو لا بدون أي قواعد معمول بها، هل من الممكن أن يكون هذا المثال الصغير جيد بالنسبة لك؟ ربما. ولكن كلما زاد عدد تعابير CSS البرمجية في المشروع، زاد عدد الأشياء الصغيرة مثل هذه، وبالتالي زادت مشاكل الخصوصية والتعقيد. ليس بالضرورة اختيار رأي صموئيل هنا، ولكن آراءه شاركها الكثير من الناس لذلك فهو مثال جيد. بخصوص من يرفضون BEM تمامًا فلا بأس بذلك، لكنني أعتقد أنه سيكون من الصعب القول بأن وجود مجموعة من القواعد التي تساعد في الفهم والحفاظ على CSS قابل للتعديل هو فكرة سيئة. في منهجية SMACSS، من المحتمل أن تجد اسم صنف CSS متكون من ثلاثة أحرف. تتبع المُعدِّلات بعدئذٍ اسم الوحدة النمطية باستخدام شرطة: /* مثال عن وحدة */ .btn { } /* btn معدِّل الصنف */ .btn-primary { } /* مع حالة Btn الوحدة */ .btn.is-collapsed { } هذه مجرد طريقة تسمية مختلفة لنفس المشكلة. إنه مشابه إلى حد ما، لكن تكون أكثر تحديدًا بشأن التبعيات والحفاظ على خصوصية التفاصيل. في OOCSS، الحاويات البرمجية هي عامة بالغالب. /* مثال عن وحدة */ .mod { } /* جزء من الوحدة */ .inner { } /* Talk الوحدة */ .talk { } /* تغيير جزء داخل الوحدة */ .talk .inner { } لذلك، يمكنك استخدام أصناف متعددة في HTML للحالات المختلفة. لم يتم تسمية الجزء الداخلي مثل التابع له، لذلك فهو أقل وضوحًا ولكنه قابل لإعادة استخدامه. ستقوم BEM بعمل .mod__inner و .mod--talk و mod-talk__inner.. هذه مجرد اختلافات في المنهجية. تذكر أن لا أحد يجبرك على استخدامها، فهذه قواعد مفروضة ذاتيًا حيث تأتي القيمة من متابعتها. BEM و Sass لأولئك الذين يستخدمون Sass ويستمتعون بتشعيب (nesting) العناصر كوسيلة لتحديد النطاقات لتنسيقات، لازال بإمكانك أن تكون المسؤول عن الصيغة المتشعبة ولكن يمكنك الحصول على CSS غير متشعب، باستخدام @at-root: ملف Scss: .block { @at-root #{&}__element { } @at-root #{&}--modifier { } } يولد ملف CSS التالي: .block { } .block__element { } .block--modifier { } ويمكنك الحصول على ملخص كما تريد! تحقق من منشئ BEM الذي يخص Danield Guillan أو Anders Schmidt Hansen من أجل BEM التعبيرية. الخلاصة أعتقد أنه من الإنصاف القول إنه على الرغم من أن BEM لن يحل جميع مشاكلنا، إلا أنه مفيد بشكل كبير في بناء واجهات قابلة للتطوير والصيانة حيث يجب أن يكون لدى كل فرد في الفريق فكرة واضحة عن كيفية تطوير تلك الأشياء. ذلك لأن الكثير من التطوير في الواجهة الأمامية لا يتعلق فقط بالخدع اللطيفة التي تحل مشكلة صغيرة واحدة على المدى القصير؛ نحتاج إلى اتفاقات وعقود ملزمة بين المطورين بحيث يمكن لبرنامجنا التكيف مع مرور الوقت وعلى المدى البعيد. بشكل عام، أود أن أفكر في BEM كإجابة على سؤال نيكولاس غالاغر: ترجمة -وبتصرف- للمقال BEM 101 لصاحبها Robin Rendle.
-
مُقدّمة بعد أن تعرّفنا على كيفيّة إنشاء بعض حقول HTML باستخدام مكتبة WTForms في تطبيقات إطار العمل فلاسك مثل حقل مساحة النّص وحقول التّاريخ والأعداد الصّحيحة. عندما نتحدّث عن نماذج HTML فإنّنا لا نعني الحقول التّي تُمكّن المُستخدم من الكتابة داخلها فقط، فهناك حقول ومكوّنات أخرى مثل القوائم المُنسدلة وأزرار الانتقاء Radio button ومربّعات التّأشير Checkbox كذلك. وقد حان الوقت للتعّرف على بقيّة الحقول التّي تُوفّرها المكتبة، وسنتعرّف في هذا الدّرس خصّيصا على كيفيّة إنشاء قوائم مُنسدلة وتقديمها، أزرار الانتقاء ومربّعات التّأشير لمنح المُستخدم طرقًا أسهل لإرسال البيانات إلى الخادوم. إنشاء وتقديم قائمة مُنسدلة سننظر في هذا الجزء إلى كيفيّة إنشاء قائمة مُنسدلة لتوفير حقل اختيار للمُستخدم. لإنشائها، فإنّ القائمة المُنسدلة تحتاج إلى قيمتين، القيمة الأولى هي ما يظهر للمُستخدم والقيمة الثّانيّة هي ما يُرسَل إلى الخادوم، فمثلا يُمكن أن تُوفّر للمُستخدم إمكانيّة اختيار بلد إقامته، وستكون القيمة الأولى عبارة عن الاسم الكامل للبلد، أمّا القيمة الثّانيّة (أي ما سيستقبله إلى الخادوم) فستكون عبارة عن الرّمز المُختصر للبلد لتكون الاختيارات كما يلي: MA => المغرب AU => أستراليا BH => البحرين DZ => الجزائر ولإنشاء القائمة المُنسدلة فإنّنا نقوم باستيراد الصّنف SelectField من مكتبة WTForms ونقوم بإنشاء مُتغيّر من هذا الصّنف كما سبق، الاختلاف هنا هو أنّنا نُمرّر الاختيارات إلى مُعامل باسم choices أثناء تعريف المُتغيّر: في المثال التّالي، نقوم بإنشاء حقل خيارات مُتعدّدة ليختار المُستخدم لغة برمجة مُعيّنة: from wtforms import SelectField class PastebinEntry(Form): language = SelectField( u'Programming Language', choices=[('cpp', 'C++'), ('py', 'Python'), ('rb', 'Ruby')] ) يُمكنك أن تُلاحظ بأنّ ما نُمرّره إلى المُعامل choices عبارة عن قائمة بمجموعات من عنصرين، وكما قلت سابقا، فالعنصر الأول هو ما سيصلك عندما يُرسل المُستخدم البيانات، أمّا العنصر الثّاني فسيظهر للمُستخدم لذا إن اختار المُستخدم الخيار Python فما سيصلك أنت عند جانب الخادوم هو السّلسلة النّصيّة 'py'. بعد إنشاء كائن من هذا الصّنف وتقديمه إلى ملفّ HTML فستتمكّن من تقديم الخيارات في صفحة HTML بنفس الطّريقة التّي كنّا نعرض بها الحقول سابقا: {{form.language.label}} <br> {{form.language}} {% if form.language.errors %} <ul class=errors> {% for error in form.language.errors %} <li>{{ error }}</li> {% endfor %} </ul> {% endif %} ولتفهم سبب توفير قيمتين لكل خيار، فتخيّل أنّ الخيارات طويلة جدا، ولو اخترت مثلا الخيار Python فإنّ قيمة form.language.data ستكون py وبالتّالي ستستطيع مُقارنتها مع قيمة أخرى بسهولة وبشيفرة أقصر. حقل الاختيارات المُتعدّدة تُمكّننا مكتبة WTForms من تقديم حقل اختيارات آخر يسمح للمُستخدم باختيار أكثر من خيار واحد، ويُمكننا إنشاء هذا الحقل عن طريق الصّنف SelectMultipleField والذي يجب عليك استيراده: from wtforms import SelectMultipleField أمّا طريقة توفير الخيارات فهي نفسها الطّريقة المُتّبعة لإنشاء قائمة منسدلة عاديّة، استبدل فقط الصّنف SelectField بالصّنفSelectMultipleField: language = SelectMultipleField( u'Programming Language', choices=[('cpp', 'C++'), ('py', 'Python'), ('rb', 'Ruby')] ) وطريقة تقديم النّموذج هي نفسها، مع إمكانيّة توفير عدد الخيارات بتمريره إلى الخاصيّة size في لغة HTML ليكون الحقل أكثر تناسقا، وطريقة توفير عدد الخيارات هو كما يلي: {{form.language(size=3)}} هكذا ستتمكّن من اختيار أكثر من خيار واحد بجرّ فأرة الحاسوب أو الضّغط بشكل مُستمرّ على مفتاح CTRL من لوحة المفاتيح أثناء الاختيار. عندما تُرسل الخيارات فإنّها تكون داخل قائمة بايثون في form.language.data ، وتستطيع الوصول إليها والتّعامل معها كما تتعامل مع قائمة عاديّة. أزرار الانتقاء أزرار الانتقاء أو Radio buttons تُشبه كثيرا القائمة المُنسدلة، إذ أنّها مُجرّد طريقة أخرى لتوفير خيارات للمُستخدم، إذ تُوفّر سؤالا للمُستخدم وتطلب منه الإجابة باختيار أحد الخيارات، ويُعتبر هذا الحقل مناسبا للأسئلة التّي تقبل جوابًا واحدًا مع توفير خيارات كإجابات مُحتملة (مثل طرح سؤال وتمكين المُستخدم من الإجابة بنعم أو لا عبر اختيار الإجابة المرغوبة). يُمكنك إنشاء حقل لأزرار انتقاء عبر الصّنف RadioField الذي يُمكنك استيراده كذلك من مكتبة WTForms، والتّالي مثال على كيفيّة إنشاء حقل به خياران، Yes و No: radio = SelectField( u'Are you happy?', choices=[('yes', 'Yes'), ('no', 'No')] ) مُجدّدًا، العنصر الأول هو ما سيُرسل إلى الخادوم، أمّا العنصر الثّاني فهو ما يُعرض للمُستخدم. أمّا عرض الأزرار على صفحة HTML فإنّه يكون مُختلفا بعض الشّيء، إذ نقوم هذه المرّة بالدّوران حول كل زر وعرضه على حدة، والتّالي مثال على كيفيّة عرض ما أنشأناه أعلاه: {% for subfield in form.radio %} <tr> <td>{{ subfield }}</td> <td>{{ subfield.label }}</td> </tr> {% endfor %} وكما تُلاحظ، فإنّنا نعرض الزرّ ثمّ اللصيقة Label الخاصّة به. مُربّع التأشير Check Box تُستخدم مُربّعات التّأشير لتمكين المُستخدم من اختيار حقل مُعيّن ليبقى افتراضيّا، مثل مُربّع “تذكّرني” تحت نماذج تسجيل الدّخول، ولأنّه يُعنى بالحصول على المُوافقة أو الرّفض من المُستخدم، فهذا يعني بأنّه يقبل قيمتين منطقيّتين فقط، إمّا أن يؤشّر عليه المُستخدم (أي القيمة المنطقيّة True)، أو يتركه فارغًا ( القيمة المنطقيّة تكون False). لذا ففي WTForms يُمكننا استخدام مُربّع التأشير هذا باستيراد الصّنف BooleanField من المكتبة. تعريف الحقل يكون كما يلي: remember_me = BooleanField('Remember Me') وطريقة العرض على صفحة HTML هي نفسها طريقة عرض الحقل السّلسلة النّصيّة القصيرة TextField: {{form.remember_me}} {{form.remember_me.label}} {% if form.remember_me.errors %} <ul class=errors> {% for error in form.remember_me.errors %} <li>{{ error }}</li> {% endfor %} </ul> {% endif %} لاحظ في أول سطر أعلاه بأنّنا نعرض المربّع أولا ثمّ اللصيقة ليكون الحقل أكثر تناسقًا. عندما تُرسل بيانات النّموذج، فمُحتوى هذا الحقل يكون إمّا القيمة المنطقيّة True إذا ما أشّر المُستخدم على المُربّع، أو القيمة المنطقيّة False إن ترك المُربّع فارغًا. لذا يُمكنك استخدام شرط منطقي في شيفرتك كما يلي: if form.remember_me.data: remember_user() مع افتراض أنّ الدّالة remember_user() تقوم بحفظ بيانات المُستخدم في جلسة طويلة الأمد ليتمكّن من الوصول إلى حسابه حتى ولو أغلق المُتصفّح. إن كان المُستخدم قد أشّر على المُربّع فستكون قيمة form.remember_me.data صحيحة وبالتّالي ستُستدعى الدّالة remember_user() وأمّا إن لم يؤشّر المُستخدم على المُربّع فالقيمة ستكون False وبالتّالي سيتم تجاهل ذلك الجزء من الشّيفرة ولن تُستدعى الدّالة remember_user(). الوصول إلى نوعيّة الحقل قد ترغب بالتّأكد من نوعيّة الحقل الذي تتعامل معه، فمثلًا قد تجد نفسك تتعامل مع الكثير من الحقول، ولكل نوع من هذه الحقول طريقة عرض خاصّة، لذا فمن المُفيد معرفة ماهية الحقل لعرضه بالطّريقة المُلائمة. لمعرفة نوع الحقل تستطيع إلحاق type بعد الحقل كما يلي: form.username.type #=> 'TextField' form.password.type #=> 'PasswordField' form.remember_me.type #=> 'BooleanField' وكما تُلاحظ فالنّوع يكون اسم الصّنف على شكل سلسلة نصيّة، لذا تستطيع كتابة جملة شرطيّة كما يلي: {% if field.type == "BooleanField" %} <div>{{ field }} {{ field.label }}</div> {% endif %} وهذا الأمر مُفيد كثيرًا إذا كنت تستعمل ميّزة الماكرو المُتواجدة في مُحرّك القوالب Jinja، وسنتطرّق إلى الأمر في الفقرة التّاليّة. تفادي تكرار شيفرة عرض الحقول باستخدام الدّوال في مُحرّك القوالب Jinja هل لاحظت بأنّ هناك الكثير من التّكرار في شيفرة عرض الحقول؟ إن لم تلاحظ بعد، فتأمّل الشّيفرة التّاليّة: {% if form.username.errors %} {% for error in form.username.errors %} {{ error }} {% endfor %} {% endif %} {% if form.password.errors %} {% for error in form.password.errors %} {{ error }} {% endfor %} {% endif %} الشّيفرة السّابقة تعرض حقلين فقط، والاختلاف الوحيد بينهما هو أنّ الأول حقل نص قصير، والثّاني حقل كلمة مرور، وسيكون من الجميل إن وضعنا الشّيفرة التّي تتكرّر في دالّة تقبل مُعاملًا يُعبّر عن الحقل. يُوفّر لنا مُحرّك القوالب Jinja ما يُسمّى بالماكرو Macro، ويُشبه كثيرا الدّوال العاديّة في لغة بايثون، والاختلاف الواضح أنّ الماكرو يستعمل بنية جملة مُحرّك القوالب، والتّالي الماكرو الخاص بعرض الحقول: {% macro render_field(field) %} <dt>{{ field.label }} <dd>{{ field(**kwargs)|safe }} {% if field.errors %} <ul class=errors> {% for error in field.errors %} <li>{{ error }}</li> {% endfor %} </ul> {% endif %} </dd> {% endmacro %} الماكرو يبدأ بالكلمة المفتاحيّة macro، ثمّ تُحدّد اسمًا له، وتُحدّد المُعاملات التّي يأخذها (في هذه الحالة يأخذ مُعاملًا واحدا يُمثّل الحقل)، بعدها نعرض اللصيقة الخاصّة بالحقل، ثمّ نعرض الحقل مع تمرير المُعاملات المفتاحية Keyword Arguments ونُنبّه مُحرّك القوالب بأنّ هذا الحقل آمن (لأنّ المُحتوى مكتوب بلغة HTML وjinja يقوم بمسح مُكوّنات HTML للتأمين من هجمات XSS)، بعدها يتم التّحقّق من أنّ هناك أخطاء من المُصادقين لعرضها، وستُلاحظ أنّ الماكرو ينتهي بالكلمة المفتاحيّة endmacro للدّلالة على أنّ ذلك الجزء من الشّيفرة قد انتهى. الآن، كل ما عليك فعله هو وضع هذا الماكرو أعلى ملفّ HTML، وستستطيع استعماله باستدعائه وتمرير الحقل إليه كما تُمرّر مُعاملًا إلى دالّة عاديّة في لغة بايثون. عند استعمالك للماكرو أعلاه، تستطيع تحويل الشّيفرة الطّويلة أعلاه إلى سطرين فقط: {{ render_field(form.username) }} {{ render_field(form.password) }} خاتمة تعرّفنا في هذا الدّرس على بقيّة الحقول ومكوّنات HTML التّي تُوفّرها لنا مكتبة WTForms، وبالتّالي تستطيع الاعتماد كليّا على هذه المكتبة عوضًا عن كتابة نماذج تطبيقاتك مُباشرة بلغة HTML، وبالتّالي تأمين تطبيقاتك أكثر. في الدّرس القادم، سنتعرّف على كيفيّة التّحقق من مُدخلات المُستخدم باستخدام مبدأ المُصادقين validators الذي تمنحه لنا مكتبة WTForms للتّحقق من أنّ ما يُرسله المُستخدم إلى الخادوم يُطابق صيغة أو شكلا مُعيّنا (كبريد إلكتروني أو مقطع نصي بطول مُحدّد).
-
AJAXAJAX هي اختصار للعبارة "asynchronous JavaScript and XML"، وهي وسيلة لجلب البيانات من الخادوم دون الحاجة لإعادة تحميل الصّفحة، وهي تقوم على استخدام كائن مُتاح في المتصفّح اسمه XMLHttpRequest (أو XHR اختصارًا) لإرسال الطّلب إلى الخادوم ثمّ التّعامل مع البيانات الّتي يُجيب بها الخادوم. تُوفّر jQuery الوظيفة $.ajax (ووظائف أخرى مرافقة مُختصرة) لتسهيل العمل مع طلبات XHR في جميع المتصفّحات. $.ajaxبإمكاننا استخدام الوظيفة $.ajax() المُرفقة مع jQuery بعدّة أساليب: إحداها أن نُمرّر إليها كائنًا يحوي الإعدادات فقط، أو أن نُمرّر الرّابط مع أو بدون كائن الإعدادات. لنُلقِ نظرة على الأسلوب الأول: // أنشئ دالّة الاستدعاء الرّاجع الّتي ستُنفّذ عندما ينجح طلب AJAX var updatePage = function( resp ) { $( '#target').html( resp.people[0].name ); }; // وعندما يفشل var printError = function( req, status, err ) { console.log( 'something went wrong', status, err ); }; // أنشئ كائن الإعدادات الذي يصف الطّلب var ajaxOptions = { url: '/data/people.json', dataType: 'json', success: updatePage, error: printError }; // أرسل الطّلب $.ajax(ajaxOptions);بإمكانك طبعًا أن تُمرّر كائنًا حرفيًّا مباشرةً إلى الوظيفة$.ajax() وأن تستخدم دالّة مجهولة محلّ success وerror، هذا الأسلوب كتابته أسهل، وصيانته في المستقبل أسهل: $.ajax({ url: '/data/people.json', dataType: 'json', success: function( resp ) { $( '#target').html( resp.people[0].name ); }, error: function( req, status, err ) { console.log( 'something went wrong', status, err ); } });كما قلنا، بإمكانك استخدام الوظيفة$.ajax() بأسلوب ثانٍ، وذلك بتمرير الرّابط أوّلًا ثمّ كائن الإعدادات ثانيًا (ليس إلزاميًّا). يُفيدك هذا في حال رغبت في استخدام الإعدادات المبدئيّة للوظيفة أو في حال رغبت في استخدام كائن الإعدادات نفسه لأكثر من رابط: $.ajax( '/data/people.json', { type: 'GET', dataType: 'json', success: function( resp ) { console.log( resp.people ); }, error: function( req, status, err ) { console.log( 'something went wrong', status, err ); } });في المثال السّابق، لا تشترط الوظيفة سوى الرّابط، ولكنّ إضافة كائن الإعدادات تسمح لنا بإخبار jQuery بنوع البيانات الّتي نُرسلها، وأي فعل HTTP نستخدمه (POST، GET، إلخ...)، وما نوع البيانات الّتي نتوقّع استقبالها من الخادوم، وما الّذي يجب فعله إن نجح الطّلب أو فشل... اطّلع على وثائق الوظيفة$.ajax() لقراءة كامل الخيارات الّتي يمكن إضافتها إلى كائن الإعدادات. A في AJAX تعني "لامتزامن"تجري طلبات AJAX بصورة لا متزامنة، وهذا يعني أنّ الوظيفة$.ajax تنتهي قبل انتهاء الطّلب، وقبل أن تُستدعى دّالة success، أيّ أنّ جملة return تُنفّذ قبل أن يصل جواب الطّلب. فالدّالة getSomeData في المثال التّالي ستُعيد قيمة data قبل أن تُعرّف، مما يؤدّي إلى وقوع خطأ: تحذير: نصّ برمجيّ غير سليم var getSomeData = function() { var data; $.ajax({ url: '/data/people.json', dataType: 'json', success: function(resp) { data = resp.people; } }); return data; } $( '#target' ).html( getSomeData().people[0].name );X في AJAX تعني JSON!وضع المصطلح AJAX عام 2005 ليصف طريقة لجلب البيانات من الخادوم دون الحاجة لإعادة تحميل كامل الصّفحة. في ذلك الوقت، كانت الصّيغة الأكثر شيوعًا للبيانات الّتي تُرسلها الخوادم هي XML، أمّا اليوم، فإنّ JSON هي الصّيغة الّتي تعتمدها أكثر التّطبيقات الحديثة. صيغة JSON في أساسها هي سلسلة نصّيّة (string) تُمثّل البيانات، وتبدو مُشابهة كثيرًا لكائن JavaScript عاديّ، ولكنّها لا تستطيع تمثيل كلّ أنواع البيانات الّتي يستطيع كائن JavaScript تمثيلها. فمثلًا: لا يمكن لـJSON تمثيل كائنات التّاريخ (Date) ولا الدّوال (functions). فيما يلي مثال عن نصّ JSON، لاحظ كيف تُحاط كلّ أسماء الخصائص بعلامتي اقتباس مُضاعفتين: { "people" : [ { "name" : "Ben", "url" : "http://benalman.com/", "bio" : "I create groovy websites, useful jQuery plugins, and play a mean funk bass. I'm also Director of Pluginization at @bocoup." }, { "name" : "Rebecca", "url" : "http://rmurphey.com", "bio" : "Senior JS dev at Bocoup" }, { "name" : "Jory", "url" : "http://joryburson.com", "bio" : "super-enthusiastic about open web education @bocoup. lover of media, art, and fake mustaches." } ] }تذكّر أنّ JSON هو تمثيل نصّيّ لكائن، ما يعني أنّه يجب تفسير السّلسلة النّصيّة لتحويلها إلى كائن JavaScript عاديّ قبل التّعامل معها. عندما تعمل مع جواب ورد من الخادوم بصيغة JSON، فإنّ jQuery تتولّى هذه المهمّة عنك. ولكن من المهمّ التمييز بين الكائنات الفعليّة، وطريقة تمثيلها في JSON. ملاحظة: إن أردت إنشاء سلسلة JSON نصّيّة من كائن JavaScript أو تفسير سلسلة JSON نصّيّة لتحويلها إلى كائن JavaScript دون الاستعانة بـjQuery، فإنّ المُتصفّحات الحديثة تُقدّم الوظيفتين JSON.stringify() وJSON.parse()، ويمكن إضافة هذه الخصائص إلى المُتصفّحات القديمة باستخدام المكتبة json2.js. توفّر jQuery أيضًا وظيفة jQuery.parseJSON()، الّتي توافق الوظيفة JSON.parse() في المتصفّحات، إلّا أنّها لا توفّر وظيفة تُقابل JSON.stringify(). وظائف مُختصرةإن كان كلّ ما نريده إرسال طلب بسيط، دون الاهتمام بالتّعامل مع الأخطاء الّتي قد تقع، فإنّ jQuery تُوفّر وظائف مُختصرة تسمح لنا بفعل ذلك. تستقبل كل وظيفة مُختصرة رابطًا وكائن إعدادات غير إلزاميّ، ودالّة تُستدعى عند نجاح الطّلب فقط: $.get( '/data/people.html', function( html ){ $( '#target' ).html( html ); }); $.post( '/data/save', { name: 'Rebecca' }, function( resp ) { console.log( resp ); });إرسال البيانات والعمل مع النّماذجبإمكاننا إرسال بيانات مع طلبنا بتعيين قيمة للخاصة data في كائن الإعدادات، أو تمرير كائن كمُعامل ثانٍ للوظائف المُختصرة. ستُضاف هذه البيانات إلى الرّابط في طلبات GET بصورة "جملة استعلام" (query string)، أمّا في طلبات POST فإنّها ستُرسل كبيانات نموذج. توفّر jQuery وظيفة مُفيدة .serialize() الّتي تستقبل مُدخلات نموذج وتُحوّلها إلى صيغة "جملة استعلام" (مثل field1name=field1value&field2name=field2value...): $( 'form' ).submit(function( event ) { event.preventDefault(); var form = $( this ); $.ajax({ type: 'POST', url: '/data/save', data: form.serialize(), dataType: 'json', success: function( resp ) { console.log( resp ); } }); });jqXHRتُعيد$.ajax() والوظائف المُختصرة المرافقة لها، كائن jqXHR (اختصارًا لـjQuery XML HTTP Request) والّذي يتضمّن وظائف مُفيدةً كثيرة. بإمكاننا إرسال طلب باستخدام $.ajax() ثمّ حفظ كائن jqXHR في مُتغيّر: var req = $.ajax({ url: '/data/people.json', dataType: 'json' });بإمكاننا استخدام هذا العنصر لربط الاستدعاءات الرّاجعة بالطّلب، حتّى بعد أن يكتمل الطّلب. بإمكاننا مثلًا استخدام الوظيفة .then() (ثُمَّ) لإرفاق استدعاءي نجاح الطّلب وفشله، إذ تقبل .then() دالّة أو اثنتين، تستدعى الأولى عند نجاح الطّلب، والثّانية إن فشل: var success = function( resp ) { $( '#target' ).append( '<p>people: ' + resp.people.length + '</p>' ); console.log( resp.people ); }; var err = function( req, status, err ) { $( '#target' ).append( '<p>something went wrong</p>' ); }; req.then( success, err ); req.then(function() { $( '#target' ).append( '<p>it worked</p>' ); });بإمكاننا استدعاء .then() على كائن الطّلب قدر ما نشاء، وستُنفّذ الاستدعاءات الرّاجعة بالتّرتيب ذاته الّتي أرفقت وفقه. إن لم نُرد إرفاق استدعاءي النّجاح والفشل معًا، فبإمكاننا استخدام الوظيفتين .done() و.fail() على كائن الطّلب: req.done( success ); req.fail( err );لو أردنا إرفاق استدعاء راجعٍ يُنفَّذ دومًا، بغض النّظر عن نجاح الطّلب أو فشله، فيمكننا استخدام الوظيفة .always() على كائن الطّلب: req.always(function() { $( '#target' ) .append( '<p>one way or another, it is done now</p>' ); });JSONPيستغرب كثيرٌ من المبتدئين في JavaScript فشل طلبات XHR الّتي يرسلونها إلى نطاق آخر على الإنترنت، فمثلاً: يحاول بعض المُطوّرين جلب بيانات من واجهة برمجيّة من طرف ثالث (third-party API)، ليفاجؤوا بفشل الطّلب باستمرار. السّبب وراء ذلك أنّ المُتصفّحات لا تسمح بإرسال طلبات XHR إلى نطاقات إنترنت أخرى لأسباب أمنيّة، ولكنّ بعض الواجهات البرمجيّة تُعيد البيانات بصيغة JSONP (اختصارًا لـJSON with Padding)، الّتي تسمح للمُطوّرين بجلب البيانات متجاوزين حظر المُتصفّح. الحقيقة أن JSONP ليس طلب AJAX فعليًّا، فهو لا يستخدم طلب XHR الّذي يوفّره المُتصفّح، بل يعمل بإدراج وسم <script> في صفحة الويب، الّذي يحوي بدوره البيانات المطلوبة، مُحاطة بدالّة تُعيد هذه البيانات عند استدعائها. ليس هذه التّفاصيل مهمّة الآن، لأنّ jQuery تسمح لك بطلب JSONP كما لو كان XHR باستخدام الوظيفة $.ajax() بتعيين نوع البيانات dataType إلى 'jsonp' في كائن الإعدادات. $.ajax({ url: '/data/search.jsonp', data: { q: 'a' }, dataType: 'jsonp', success: function( resp ) { $( '#target' ).html( 'Results: ' + resp.results.length ); } });ملاحظة: عادةً ما توفّر الواجهات البرمجيّة خيارًا لتعيين اسم الدّالّة الّتي تُحيط بالبيانات والّتي ستُستدعى في عنوان الرّابط. عادةً ما يكون هذا اسم مُعامل الرّابط callback، وهذا ما تتوقّعه jQuery مبدئيًّا، إلّا أن بإمكانك تغييره بتعيين قيمة للخاصة jsonp في كائن الإعدادات الّذي تُمرّره لـ $.ajax(). بإمكانك أيضًا استخدام الوظيفة المُختصرة $.getJSON() لإرسال طلب JSONP، حيث تستطيع jQuery تمييزه من خلال وجود callback=? أو ما يشبهها في الرّابط: $.getJSON( '/data/search.jsonp?q=a&callback=?', function( resp ) { $( '#target' ).html( 'Results: ' + resp.results.length ); } );مشاركة الموارد عبر الأصول (cross-origin resource sharing أو CORS اختصارًا) هي خيارٌ آخر للسّماح بالطّلبات العابرة للأصول. ولكنّها غير مدعومة في المتصفّحات القديمة، كما أنّها تحتاج تهيئة خاصّة على الخادوم وتعديل ترويسات الطّلبات في XHR لتعمل. الكائنات المُؤجّلة (Deferreds)ليست كائنات jqXHR الّتي تعرّفنا عليها إلا "نكهة" خاصّة ممّا يُعرف "بالكائنات المؤجّلة". تسمح jQuery لك بإنشاء كائنات مؤجّلة بنفسك، والّتي يمكن الاستفادة منها في تسهيل التّعامل مع الأوامر اللامتزامنة، فهي توفّر طريقة للاستجابة لعمليّة تجري بصورة غير متزامنة بعد نجاحها أو فشلها، وتجنّبك الحاجة لكتابة استدعاءات راجعة مُتداخلة فيما بينها. $.Deferredبإمكانك إنشاء كائنٍ مؤجّل باستخدام $.Deferred(). في المثال التّالي نُنفّذ دالة داخل setTimeout، ثمّ "نفي" (resolve) بوعدنا بإعادة القيمة الّتي تُرجعها الدّالة هذه. نُعيد الوعد (promise)، وهو كائن يمكن ربط الاستدعاءات الرّاجعة به، ولكنّه لا يؤثّر في نتيجة الكائن المؤجّل بحدّ ذاته. بإمكاننا "الإخلاف" (reject) بالوعد إذا وقع خطأ ما أثناء عمل الدّالّة: function doSomethingLater( fn, time ) { var dfd = $.Deferred(); setTimeout(function() { dfd.resolve( fn() ); }, time || 0); return dfd.promise(); } var promise = doSomethingLater(function() { console.log( 'This function will be called in 100ms' ); }, 100);.then() و.done() و.fail() و.always()يمكننا ربط دوالّ تتولّى حالات الخطأ والنّجاح بالوعود، تمامًا كما في كائنات jqXHR: function doSomethingLater( fn, time ) { var dfd = $.Deferred(); setTimeout(function() { dfd.resolve( fn() ); }, time || 0); return dfd.promise(); } var success = function( resp ) { $( '#target' ).html( 'it worked' ); }; var err = function( req, status, err ) { $( '#target' ).html( 'it failed' ); }; var dfd = doSomethingLater(function() { /* ... */ }, 100); dfd.then( success, err );.pipe()بإمكاننا استخدام الوظيفة .pipe() للوعود للاستجابة إلى القيمة الّتي تُوفى وذلك بتعديلها ثمّ إعادة كائن مؤجّل جديد. تعمل الوظيفة .then() بدءًا من الإصدارة 1.8 من jQuery كما تعمل الوظيفة .pipe(). function doSomethingLater( fn, time ) { var dfd = $.Deferred(); setTimeout(function() { dfd.resolve( fn() ); }, time || 0); return dfd.promise(); } var dfd = doSomethingLater(function() { return 1; }, 100); dfd .pipe(function(resp) { return resp + ' ' + resp; }) .done(function(upperCaseResp) { $( '#target' ).html( upperCaseResp ); });التّعامل مع العمليّات الّتي قد تكون لامتزامنةأحيانًا تكون لدينا وظيفة قد تعمل بصورة متزامنة أو لا متزامنة وفق ظروف مُعيّنة، فمثلًا: دالّة تقوم بعمليّة لا متزامنة أوّل مرّة تُستدعى فيها، ثمّ تُخزّن القيمة الّتي أنتجتها العمليّة لتُعيدها مباشرةً عند استدعاءها مُستقبلًا. في هذه الحالة يمكننا الاستفادة من $.when() للاستجابة لكلا الحالتين: function maybeAsync( num ) { var dfd = $.Deferred(); // أعِد وعدًا مؤجّلًا عندما num === 1 if ( num === 1 ) { setTimeout(function() { dfd.resolve( num ); }, 100); return dfd.promise(); } // أنهِ مباشرة فيما سوى ذلك، مُعيدًا num return num; } // هذا سيُجرى بصورة غير متزامنة ويعِد بإعادة 1 $.when( maybeAsync( 1 ) ).then(function( resp ) { $( '#target' ).append( '<p>' + resp + '</p>' ); }); // هذا سُيعيد 0 مُباشرةً $.when( maybeAsync( 0 ) ).then(function( resp ) { $( '#target' ).append( '<p>' + resp + '</p>' ); });بإمكانك أيضًا تمرير أكثر من معامل إلى $.when()، الأمر الّذي يسمح لك بدمج عمليّات متزامنة ولا متزامنة معًا ثمّ الحصول على نتائج تنفيذها كلّها كُمعاملات للاستدعاء الرّاجع: function maybeAsync( num ) { var dfd = $.Deferred(); // أعد وعدًا مؤجّلًا عندما num === 1 if ( num === 1 ) { setTimeout(function() { dfd.resolve( num ); }, 100); return dfd.promise(); } // أنهِ مباشرةً فيما سوى ذلك، مُعيدًا num return num; } $.when( maybeAsync( 0 ), maybeAsync( 1 ) ) .then(function( resp1, resp2 ) { var target = $( '#target' ); target.append( '<p>' + resp1 + '</p>' ); target.append( '<p>' + resp2 + '</p>' ); });عندما يكون إحدى مُعاملات $.when() كائن jqXHR، فإنّنا نحصل على مصفوفة من المُعاملات تُمرّر إلى استدعائنا الرّاجع: function maybeAsync( num ) { var dfd = $.Deferred(); // أعد وعدًا مؤجّلًا عندما num === 1 if ( num === 1 ) { setTimeout(function() { dfd.resolve( num ); }, 100); return dfd.promise(); } // أنهِ مباشرةً فيما سوى ذلك، مُعيدًا num return num; } $.when( maybeAsync( 0 ), $.get( '/data/people.json' ) ) .then(function( resp1, resp2 ) { console.log( "Both operations are done", resp1, resp2 ); });مصادر إضافيةتوثيق AJAXكائن jqXHRالكائنات المؤجّلة في jQueryترجمة (بشيء من التصرف) للجزء السادس من سلسلة jQuery Fundamentals لمؤلّفتها Rebecca Murphey.
-
- javascript
- http
-
(و 6 أكثر)
موسوم في:
-
code { font-size: 1rem !important; }تجعل jQuery إضافة التأثيرات الحركيّة على الصّفحة أمرًا سهلًا للغاية، ويمكن لهذه التأثيرات أن تعتمد الإعدادات المبدئيّة أو إعدادات يُعيّنها المُطوّر. بإمكانك أيضًا إنشاء حركاتٍ مُخصّصة من خصائص CSS عشوائيّة. اطّلع على وثائق التأثيرات لتفاصيل أكثر عن تأثيرات jQuery. ملاحظة مهمّة عن الحركات: يكون إنجاز الحركات باستخدام CSS بدل JavaScript أكثر كفاءةً في المُتصفّحات الحديثة، وخصوصًا في الأجهزة المحمولة. تفاصيل إنجاز هذه الحركات خارجةٌ عن نطاق السّلسلة، ولكن إن كنت تستهدف المُتصفّحات والأجهزة المحمولة الّتي تدعم حركات CSS، فقد ترغب بتعيين الإعداد jQuery.fx.off إلى القيمة true على الأجهزة ذات المواصفات الضّعيفة؛ فهذا من شأنه إبطال الحركات والوصول بالعنصر المطلوب تحريكه إلى حالته النّهائية مباشرةً دون تطبيق الحركة. التأثيرات المُرفقة مع jQueryتُرفَق الحركات المُستخدم بكثرة مع jQuery كوظائف يمكنك استدعاؤها على أي كائن jQuery: .show(): أظهر العناصر المُحدّدة..hide(): أخفِ العناصر المُحدّدة..fadeIn(): حرّك ظلاليّة العناصر (opacity) المُحدّدة إلى 100%..fadeOut(): حرّك ظلاليّة العناصر المُحدّدة إلى 0%..slideDown(): أظهر العناصر المُحدّدة بحركة سحب شاقوليّة..slideUp(): أخفِ العناصر المُحدّدة بحركة سحب شاقوليّة..slideToggle(): أخفِ العناصر المُحدّدة أو أظهرها بحركة سحبٍ شاقوليّة، اعتمادًا على كون العناصر المُحدّدة مخفيّة أو ظاهرة.يسهل تطبيق إحدى هذه التأثيرات على التّحديد بعد إنشائه: $( '.hidden' ).show();جرّب المثال في ساحة التّجربة (تأكد من ضغط الزرّ Run with JS في هذ المثال وكلّ الأمثلة التّالية) بإمكانك أيضًا تحديدُ مدّة للتأثيرات السّابقة، وهناك طريقتان لتحديدها، الأولى: تعيين الوقت بالميللي ثانيّة: $( '.hidden' ).show( 300 );جرّب المثال في ساحة التّجربة والثّانية استخدام إحدى السُرعات المُعرّفة مُسبقًا: $( '.hidden' ).show( 'slow' );جرّب المثال في ساحة التّجربة عُرِّفت هذه السُرعات في الكائن jQuert.fx.speeds؛ ممّا يعني أنّ بإمكانك تعديله لتغيير القيم المبدئيّة، أو إضافة سُرعات جديدة إليه: // أعد تعيين سرعةٍ مُعرّفة jQuery.fx.speeds.fast = 50; // عرّف سرعة جديدة jQuery.fx.speeds.turtle = 3000; // بما أنّنا غيّر قيمة السّرعة `fast`، فإنّ هذه الحركة ستستغرق 50 ميللي ثانية $( '.hidden' ).hide( 'fast' ); // بإمكاننا استخدام السّرعات الّتي عرفناها بأنفسنا تمامًا كتلك المُعرّفة مسبقًا $( '.other-hidden' ).show( 'turtle' );كثيرًا ما يرغب المُطوّر بفعل شيءٍ ما بعد انتهاء الحركة مباشرةً، فإن حاول فعله قبل انتهاء الحركة، فقد يسبّب تشوّه الحركة وتقطّعها، أو قد يحذف سهوًا عناصر تتحرّك في لحظة حركتها. بإمكانك تمرير استدعاء راجع (callback) إلى وظائف الحركة إن رغبت بتنفيذ أمرٍ ما بعد انتهاء التأثير، وتُشير this داخل هذا الاستدعاء إلى عنصر DOM الخام الّذي طُبقّت عليه الحركة، ومثلها ومثل دوالّ تولّي الأحداث، يمكن إحاطة this بالوظيفة $() لاستخدامها ككائن jQuery: $( 'p.old' ).fadeOut( 300, function() { $( this ).remove(); });جرّب المثال في ساحة التّجربة إن لم يحوِ التّحديد أيّة عناصر، فلن تُستدعى الدّالة. إن احتجت إلى استدعاء الدّالة بصرف النّظر عن وجود العناصر أو غيابها في التّحديد، بإمكانك إنشاء دالّة تتعامل مع الحالتين: var oldElements = $( 'p.old' ); var thingToAnimate = $( '#nonexistent' ); // هذه الدّالة ستكون الاستدعاء الرّاجع للوظيفة `show` في حال وجود عناصر نريد إظهارها، فإن لم توجد أيّة عناصر، فإنّنا نستدعيها مباشرةً بأنفسنا. var removeOldElements = function() { oldElements.remove(); }; if ( thingToAnimate.length ) { // ستُستدعى وظيفتنا بعد انتهاء الحركة thingToAnimate.show( 'slow', removeOldElements ); } else { removeOldElements(); }جرّب المثال في ساحة التّجربة تأثيرات مُخصّصة باستخدام .animate()إن لم تُلبِّ الحركات المُرفقة مع jQuery حاجتك، فبإمكانك استخدام الوظيفة .animate() لإنشاء حركات مخصّصة قائمة على خصائص CSS مُتعدّدة (إحدى الاستثناءات: الخاصّ' color الّتي لا يمكن تحريكها، ولكن تتوفّر إضافة تسمح بذلك). تقبل الوظيفة .animate() ثلاثة مُعاملات على الأكثر: كائن يُحدّد الخصائص الّتي يُراد تحريكهامدّة الحركة، مُقدّرة بالميللي ثانيةدالّة تُستدعى عند انتهاء الحركةيمكن أن تُعيّن قيمة الحركة بكتابة القيمة النّهائيّة المُراد التّحريك إليها، أو كتابة المقدار الّذي يجب تحريكه (الفرق بين موضعي الحركة): $( '.funtimes' ).animate({ left: '+=50', // زد بمقدار 50 opacity: 0.25, fontSize: '12px' }, 300, function() { // تنفّذ عند انتهاء الحركة } );جرّب المثال في ساحة التّجربة ملاحظة: إن أردت تحريك خاصّة CSS يحوي اسمها على الإشارة "-"، فعليك تحويل الاسم إلى صيغة camelCase أوّلًا إن لم تشأ إحاطة اسم الخاصّة بعلامات اقتباس، فمثلًا الخاصّة font-size تُصبح fontSize. إدارة الحركاتتُوفّر jQuery وظيفتين مُهمّتين لإدارة الحركات: .stop(): تُوقف الحركات الجارية على العناصر المُحدّدة..delay(): تُؤخِّر بدء الحركة القادمة بالمقدار الذي يُمرّر إليها (بالميللي ثانية).تُوفّر jQuery أيضًا وظائف لإدارة تعاقب الحركات وتنظيمها في "طوابير"، وإنشاء طوابير مُخصّة، وإضافة دوالّ مُخصّصة إلى هذه الطّوابير. مناقشة هذه الوظائف موضوع أكبر من هذه السّلسلة، ولكن قد ترغب بالاطّلاع عليها في وثائق jQuery. ترجمة (بشيء من التصرف) للجزء الخامس من سلسلة jQuery Fundamentals لمؤلّفتها Rebecca Murphey.
- 1 تعليق
-
- web development
- animations
- (و 5 أكثر)
-
تُسهّل jQuery الاستجابة لتفاعل المُستخدم مع صفحات الويب. معنى هذا أنّ بإمكانك تنفيذ أمرٍ ما عندما ينقر المُستخدم على جزءٍ مُعيّن من الصّفحة، أو عندما يُحرّك مؤشّر الفأرة فوق عنصر في نموذج مثلاً. في المثال التّالي، لدينا أمر يُنفَّذ عندما ينقر المُستخدم فوق أيّ عنصر قائمة في الصّفحة: $( 'li' ).click(function( event ) { console.log( 'clicked', $( this ).text() ); });جرّب المثال في ساحة التّجربة (تأكد من ضغط الزرّ Run with JS في هذ المثال وكلّ الأمثلة التّالية) يُحدّد النّصّ السّابق كلّ عناصر القائمة ويُسند إليها دالّة تتولّى حدث النّقر على كلّ عنصر، باستخدام وظيفة .click() في jQuery. توفّر jQuery وظائف مُختصرةً عديدةً لربط الأحداث، وكلّ من هذه الوظائف يوافق حدث DOM أصليًّا: td {direction:ltr; }اسم الحدث الأصليّ الوظيفة المُختصرةclick.click()keydown.keydown()keypress.keypress()keyup.keyup()mouseover.mouseover()mouseout.mouseout()mouseenter.mouseenter()mouseleave.mouseleave()scroll.scroll()focus.focus()blur.blur()resize.resize()تستخدم هذه الوظائف المُختصرة الوظيفة .on() ما وراء الكواليس، وهي وظيفة يمكنك استخدامها بنفسك لمرونةٍ أكبر. وعند استخدامك لها، فإنّك تُمرّر اسم الحدث الأصليّ كمُعامل أوّل للوظيفة، ثمّ دالّة تتولى الحدث كمعامل ثانٍ: $( 'li' ).on( 'click', function( event ) { console.log( 'clicked', $( this ).text() ); });جرّب المثال في ساحة التّجربة ما إن "تربط" مُتولّي الحدث بعنصرٍ من العناصر، فبإمكانك إثارة هذا الحدث بـjQuery أيضًا: $( 'li' ).trigger( 'click' );وإن كان للحدث الّذي تُريد إثارته وظيفةٌ مختصرة (كما ورد في الجدول السّابق)، فبإمكانك إثارة الحدث باستدعاء الوظيفة المختصرة ذاتها: $( 'li' ).click();ملاحظة: عندما تُثير حدثًا باستخدام .trigger()، فإنّك تستدعي مُتولّيات الأحداث الّتي أُنشئت في JavaScript فقط ولا تستدعي السّلوك الافتراضيّ للحدث. فمثلًا إن أثرت حدث النّقر على رابط (عنصر <a>) فلن ينتقل المتصفّح إلى الرّابط المُسند إليه في صفة href (مع أنّ بإمكانك كتابة أوامر تُنفّذ هذه الغاية). بعد أن تربط حدثًا بُعنصر، بإمكانك فكّ هذا الارتباط باستخدام الوظيفة .off() الّتي تُزيل أية مُتولّيات ارتبطت بهذا الحدث: $( 'li' ).off( 'click' );حصر الأحداث ضمن فضاء أسماءمن المزايا الّتي تُتيحها .on() إمكانيّة حصر الأحداث ضمن "فضاء أسماء". قد تتساءل عن الحاجة لذلك. افترض مثلًا أنّك تريد ربط بعض الأحداث بعنصر ما، ثمّ إزالة بعض المُتولّيات، يمكنك أن تفعل ما فعلناه في الفقرة الماضية: تحذير: أسلوب برمجيّ غير مُفضّل $( 'li' ).on( 'click', function() { console.log( 'a list item was clicked' ); }); $( 'li' ).on( 'click', function() { registerClick(); doSomethingElse(); }); $( 'li' ).off( 'click' );إلّا أنّ هذا الأسلوب سيُزيل كلّ مُتولّيات النقر على كلّ عناصر القوائم، وليس هذا ما نريد. إذا ربطت متولّيًا للأحداث محصورًا ضمن فضاء أسماء، فبإمكانك استهدافه بدقّة: $( 'li' ).on( 'click.logging', function() { console.log( 'a list item was clicked' ); }); $( 'li' ).on( 'click.analytics', function() { registerClick(); doSomethingElse(); }); $( 'li' ).off( 'click.logging' );هذا الأسلوب لا يؤثّر على الأحداث المرتبطة بالنّقر والمُتعلّقة بأغراض إحصاءات الاستخدام في الصّفحة، بينما يزيل أحداث النّقر المُتعلّقة بالسّجلّات. بإمكاننا استخدام ميزة حصر الأحداث لإثارة أحداثٍ مُحدّدة: $( 'li' ).trigger( 'click.logging' );ربط أحداث مُتعدّدة في وقت واحدميزة أخرى تُوفّرها .on()، وهي إمكانيّة ربط أحداث مُتعدّدة في وقتٍ واحد. افترض مثلًا أنّك تريد تنفيذ أمرٍ مُعيّن عندما يُمرّر المستخدم الصّفحة أو يغيّر قياس النّافذة. فهذه الوظيفة تُتيح لك تمرير الحدثين معًا مفصولين بمسافة في سلسلة نصيّة، يتبعهما الدّالّة الّتي تريد أن تتولّى الحدثين: $( 'input[type="text"]' ).on('focus blur', function() { console.log( 'The user focused or blurred the input' ); }); $( window ).on( 'resize.foo scroll.bar', function() { console.log( 'The window has been resized or scrolled!' ); });جرّب المثال في ساحة التّجربة تمرير دوالّ مُسمّاة كُمتولّيات الأحداثفي كلّ أمثلتنا السّابقة، كنّا نُمرّر دوالّ مجهولة كمُتولّيات للأحداث، ولكن يمكننا إنشاء دالّة قبل إمرارها وحفظها في مُتغيّر ثمّ تمرير هذا المُتغيّر كمُتولّي الحدث. هذا يُفيد في حال أردت استخدام الدّالة نفسها لتتولّى أحداثًا مُختلفة أو أحداثًا من عناصر مُختلفة: var handleClick = function() { console.log( 'something was clicked' ); }; $( 'li' ).on( 'click', handleClick ); $( 'h1' ).on( 'click', handleClick );كائن الحدثفي كلّ مرّة يُثار فيها حدثٌ ما، تستقبل الدّالّة المُتولّية للحدث مُعاملًا واحدًا، وهو كائن الحدث الّذي يتبع معايير مُتّفقًا عليها بين كلّ المُتصفّحات. ولهذا الكائن خصائص مُفيدة كثيرة، منها: $( document ).on( 'click', function( event ) { console.log( event.type ); // نوع الحدث، مثل: "click" console.log( event.which ); // الزرّ أو المفتاح الّذي ضغط console.log( event.target ); // العنصر الّذي انطلق منه الحدث console.log( event.pageX ); // موقع مؤشّر الفأرة على المحور X console.log( event.pageY ); // موقع مؤشّر الفأرة على المحور Y });جرّب المثال في ساحة التّجربة داخل مُتولّي الأحداثعندما تُحدِّد الدّالة المُتولّية لحدث ما، فإنّه يُتاح لهذه الدّالّة وصول إلى عنصر DOM الخام الّذي أطلق الحدث كسياق الدّالّة this، فإن أردت استخدام jQuery للتّعامل مع الحدث، فأحطه بـ$(): $( 'input' ).on( 'keydown', function( event ) { // this: العنصر الخام الّذي أطلق الحدث // event: كائن الحدث // غير لون الخلفية إلى أحمر إذا ضغط زر مسح الحرف، أو إلى أخضر فيما سوى ذلك $( this ).css( 'background', event.which === 8 ? 'red' : 'green' ); });جرّب المثال في ساحة التّجربة منع السّلوك المبدئيّقد ترغب أحيانًا في منع السّلوك المبدئيّ لحدثٍ ما، كأن ترغب في تولّي النّقر فوق رابط باستخدام AJAX، بدلًا من بدء إعادة تحميل كاملةٍ للصّفحة (وهو السّلوك المبدئيّ). يصل العديد من المُطوّرين إلى هذه الغاية بإعادة false من مُتولّي الحدث، ولكنّ لهذا تأثيرًا جانبيًّا آخر: فهو يمنع تفشّي الحدث (propagation) أيضًا (سنشرحه بعد قليل)، ممّا قد يعطي نتائج غير مرغوبة. الطّريقة السّليمة لمنع السّلوك المبدئيّ لحدث تكون باستدعاء .preventDefault() على كائن الحدث: $( 'input' ).on( 'keydown', function( event ) { // this: العنصر الخام الّذي أطلق الحدث // event: كائن الحدث // غير لون الخلفية إلى أحمر إذا ضغط زر مسح الحرف، أو إلى أخضر فيما سوى ذلك $( this ).css( 'background', event.which === 8 ? 'red' : 'green' ); });جرّب المثال في ساحة التّجربة صعود الأحداث (Event bubbling)تمعّن النّص البرمجيّ التّالي: $( 'a' ).on( 'click', function( event ) { // امنع الحدث المبدئيّ. event.preventDefault(); // سجّل ما حدث. console.log( 'I was just clicked!' ); });جرّب المثال في ساحة التّجربة يربط هذا النّص مُتولّيًا للنقر على كلّ العناصر في الصّفحة (وهو أمر يجب ألّا تفعله نهائيًّا في المواقع الحقيقيّة)، بالإضافة إلى عنصري النّافذة والمُستند. ولكن ما الّذي يحدث عندما تنقر على عنصر <a> مُدرج داخل عناصر أخرى؟ الحقيقة أنّ الحدث سيُثار على العنصر <a> وعلى كلّ العناصر الّتي تُحيط به صعودًا حتّى الوصول إلى العنصرين document وwindow. يُسمّى هذا السّلوك "صعود الأحداث"، فالحدث يُثار على العنصر الّذي نقر عليه المُستخدم، ثمّ ينتقل صاعدًا إلى كلّ العناصر الّتي تحويه وصولًا إلى أعلى DOM، إلّا إن استدعيت الوظيفة .stopPropagation() على كائن الحدث. بإمكانك فهم ذلك بسهولة أكبر في هذا المثال: <a href="#foo"><span>I am a Link!</span></a> <a href="#bar"><b><i>I am another Link!</i></b></a>$( 'a' ).on( 'click', function( event ) { event.preventDefault(); console.log( $( this ).attr( 'href' ) ); });عندما تنقر على "I am a Link!"، فإنك لا تنقر فعليًّا على العنصر <a>، بل على العنصر <span> داخله، ولكن الحدث "يصعد" نحو العنصر <a> ويُثير حدث النّقر المُرتبط به. تفويض الأحداث (Event delegation)يسمح لنا مفهوم "صعود الأحداث" بإنجاز فكرة "تفويض الأحداث"، أي ربط الأحداث بعناصر في مستوى أعلى، ثمّ اكتشاف أيّ عنصر فرعيّ ضمنها أثار الحدث. بإمكاننا مثلًا ربط حدث بقائمة غير مُرتّبة، ثمّ تحديد أيّ العناصر أثار الحدث: $( '#my-unordered-list' ).on( 'click', function( event ) { console.log( event.target ); // يُسجّل العنصر الّذي أثار الحدث });جرّب المثال في ساحة التّجربة بالطّبع ستتعقّد الأمور إذا احتوت عناصر القائمة على عناصر فرعيّة ضمنها، ولهذا تُقدّم jQuery وظيفةً مُساعدة تسمح لنا بتحديد أي العناصر نهتمّ بها، مع الاحتفاظ بالحدث مُرتبطًا بالعنصر ذي المُستوى الأعلى: $( '#my-unordered-list' ).on( 'click', 'li', function( event ) { console.log( this ); // يُسجّل عنصر القائمة الّذي أثار الحدث });جرّب المثال في ساحة التّجربة لتفويض الأحداث فائدتان اثنتان: أولاهما أنّه يسمح بربط عددٍ أقلّ من مُتولّيات الأحداث مقارنة بالعدد الّذي نحتاجه لو قرّرنا ربط الأحداث بالعناصر المُنفردة، وهذا يُحسّن الأداء في الصّفحة بصورة كبيرة. وثاني الفائدتين أنّه يسمح لنا بربط الأحداث بالآباء (كالقائمة غير المرتّبة في مثالنا)، مع اطمئنانا إلى أنّ الأحدث ستُثار حتّى وإن تغيّرت مُحتويات العنصر الأب. هذا النّصّ مثلًا، يُضيف عنصر قائمةٍ جديدًا بعد تفويض الحدث إلى العنصر الأب، والنّقر فوق هذا العنصر سيُثير الحدث كما ينبغي، دون الحاجة لربط أيّة أحداث جديدة: $( '#my-unordered-list' ).on( 'click', 'li', function( event ) { console.log( this ); // يُسجّل عنصر القائمة الّذي نُقر عليه }); $( '<li>a new list item!</li>' ).appendTo( '#my-unordered-list' );جرّب المثال في ساحة التّجربة خاتمةتعلّمنا في هذا الجزء الوسائل المُختلفة للإنصات إلى تفاعل المُستخدم مع صفحتنا، بما في ذلك كيفيّة الاستفادة من التفويض لتحسين كفاءة ربط الأحداث بالعناصر. سنتعرّف الجزء القادم كيف نُحرّك العناصر باستخدام وظائف التأثيرات الحركيّة في jQuery. ترجمة (بشيء من التصرف) للجزء الرابع من سلسلة jQuery Fundamentals لمؤلّفتها Rebecca Murphey.
-
- تطوير الويب
- javascript
-
(و 4 أكثر)
موسوم في:
-
تُسهِّل مكتبة jQuery التّعامل مع محتويات صفحة HTML بعد أن يعرضها المتصفّح، وتوفّر أدوات تُساعدك في متابعة تفاعل المستخدم مع الصّفحة، وتحريك العناصر فيها، والتّواصل مع الخواديم دون إعادة تحميل الصّفحة. سنشرح هذه الأدوات بعد قليل. لنبدأ أوّلًا بالاطّلاع على أساسيّات jQuery، وكيف يمكن استخدام وظيفتها الأساسيّة: الوصول إلى عناصر مُحدَّدة في الصفحة وفعل شيءٍ ما بها. ملاحظة: يفترض هذا الدّليل أنّك على علم بأساسيّات HTML ومُحدِّدات CSS. إن لم تكن تألف كيف يمكن استخدام مُحدّدات CSS للوصول إلى عناصر مُحدّدة في الصّفحة، فعليك أوّلًا تعلّم ذلك قبل الشروع في متابعة هذا الدّليل. ما هذا الرمز: $؟توفّر مكتبة jQuery الدّالّة jQuery، التي تتيح لك تحديد العناصر بمُحدّدات CSS. var listItems = jQuery( 'li' );إن قرأت من قبل برامج تستخدم jQuery، فلا بدّ أنّك اعتدت على هذا: var listItems = $( 'li' );كما ناقشنا في الجزء السّابق (أساسيّات JavaScript)، فكلّ الأسماء تكاد تكون سّليمة في JavaScript ما لم تبدأ برقم أو تحوي إشارة "-". ولذا فالاسم $ في المثال الأخير ليس إلّا اسمًا مُختصرًا للدّالّة jQuery، ولو اطّلعت على مصدر jQuery، لقرأت هذا قرب نهايته: // Expose jQuery to the global object window.jQuery = window.$ = jQuery;عندما تستدعي الدّالّة $() وتمرّر لها مُحدّدًا، فإنّك تحصل على كائن jQuery جديدٍ. الدّوالّ في JavaScript هي الأخرى كائنات، وهذا يعني أنّ للدّالّة $ (وjQuery بالطّبع) خصائص ووظائف أيضًا. مثلاً: يمكنك استخدام الخاصّة $.support لمعرفة ما الميزات الّتي يدعمها المتصفّح الحاليّ، كما يمكنك استخدام الوظيفة $.ajax لإرسال طلب AJAX. ملاحظة: من الآن فصاعدًا سنستخدم $ بدلًا من jQuery في هذه السّلسلة سعيًا للاختصار. لاحظ أنّه إن احتوت صفحتك أكثر من مكتبة واحدة، فقد يُستخدم الاسم $ من مكتبة أخرى، ممّا يمنع عمل jQuery، فإن واجهتك مشكلة كهذه، جرّب استخدام jQuery.noConflict قبل تحميل المكتبات الأخرى. $(document).ready()قبل استخدام jQuery لفعل أيّ شيء في الصّفحة، علينا التأكّد من كون الصّفحة قد بلغت حالةً تسمح بتعديل محتوياتها. يمكن تنفيذ ذلك في jQuery بإحاطة برنامجنا ضمن دالّة ثمّ إمرار هذه الدّالة إلى $(document).ready(). كما ترى في المثال التّالي، يمكن للدّالّة الّتي نمرّرها أن تكون مجهولة (بلا اسم): $(document).ready(function() { console.log( 'ready!' ); });هذا سيؤدّي إلى استدعاء الدّالّة الّتي مرّرناها إلى .ready() بعد أن يصبح المُستند (الصفحة) جاهزًا. ما الذي يحدث هنا؟ استخدمنا $(document) لإنشاء كائن jQuery من document في الصّفحة، ثمّ استدعينا الدّالّة .ready() على هذا الكائن، مُمرِّرين إليها الدّالّة الّتي نريد تنفيذها. بما أنّك ستجد نفسك تُعيد كتابة هذا النّصّ مرارًا، فإنّ jQuery تقدّم لك طريقةً مُختصرةً لإنجازه، إذ تقوم الدّالّة $() بمهمّة مُختلفة عند إمرار دالّة إليها بدلًا من مُحدِّد CSS، وعندها تتصرّف وكأنّها اسم بديلٌ للوظيفة $(document).ready(): $(function() { console.log( 'ready!' ); });ملاحظة: من الآن فصاعدًا، سنفترض أنّ النّصوص الّتي ترد في هذه السّلسلة مُحاطة بالعبارة $(document).ready(function() { ... });، وسنترك هذه العبارة بغرض الإيجاز. الوصول إلى العناصرأبسط ما يمكن إنجازه بـjQuery تحديد بعض العناصر ثمّ فعل شيء ما بها. إن كنت تفهم مُحدّدات CSS، فستجد أنّ الوصول إلى بعض العناصر سهل ومباشر: ليس عليك إلا إمرار المُحدِّد المناسب إلى $(). $( '#header' ); // حدّد العنصر الّذي مُعرِّفه 'header' $( 'li' ); // حدّد كل عناصر القوائم في الصّفحة $( 'ul li' ); // حدّد كل عناصر القوائم الموجودة في قوائم غير مُرتّبة $( '.person' ); // حدّد كل العناصر ذات الصّنف 'person'من المهمّ أن تفهم أنّ أيّ تحديد تُجري لن يتضمّن إلّا العناصر الموافقة للمُحدّد والتي كانت موجودة في اللّحظة الّتي أجريت فيها التّحديد، بمعنى أنّك إذا كتبت var anchors = $( 'a' ); ثمّ أضفت عنصر <a> إلى الصّفحة لاحقًا، فلن تحوي anchors العنصر الجديد. طرق أخرى لإنشاء كائن jQueryبالإضافة إلى إمرار مُحدّد بسيط إلى الدّالة $()، يمكن إنشاء كائنات jQuery بطرق أخرى: // أنشئ كائن jQuery من عنصر DOM $( document.body.children[0] ); // أنشئ كائن jQuery من قائمة بعناصر DOM $( [ window, document ] ); // أجرِ التّحديد بسياق عنصر DOM var firstBodyChild = document.body.children[0]; $( 'li', firstBodyChild ); // أجرِ التّحديد ضمن تحديد سابق var paragraph = $( 'p' ); $( 'a', paragraph );هل يحتوي التّحديد الّذي أجريته على أيّة عناصر؟ترغب أحيانًا في تنفيذ بعض الأوامر عندما يُطابق تحديدك عنصرًا أو أكثر فقط، ولكنّ الدّالّة $() تُعيدُ دومًا كائن jQuery، وهذا الكائن دائمًا صائب (truthy)، ولذا عليك فحص محتوى التّحديد لمعرفة إن كان يحوي أيّة عناصر. تحذير: نصّ برمجيّ غير سليم if ( $( '#nonexistent' ) ) { // خطأ! الأوامر هنا ستُنفَّذ دومًا! } if ( $( '#nonexistent' ).length > 0 ) { // صحيح! لن تُنفّذ الأوامر هنا إلّا إن احتوت الصّفحة على كائن مُعرّفه 'nonexistent' }بإمكاننا اختصار هذا الفحص أكثر بالاعتماد على كون 0 قيمة خاطئة (falsy): if ( $( '#nonexistent' ).length ) { // لن تُنفّذ الأوامر هنا إلّا إن وجد عنصر مُطابق }الوصول إلى عناصر مُفردة من تحديدإن كنت تحتاج التّعامل مع عنصر DOM خام من تحديد، فعليك الوصول إلى هذا العنصر من كائن jQuery. لنفترض مثلًا أنّك تريد الوصول إلى الخاصّة value لكائن <input> مباشرةً، عليك إذن التّعامل مع عنصر DOM الخام: var listItems = $( 'li' ); var rawListItem = listItems[0]; // أو listItems.get( 0 ) var html = rawListItem.innerHTML;لاحظ أنّه ليس بإمكانك استدعاء وظائف jQuery على عناصر DOM الخام، فلن يعمل المثال التّالي: تحذير: نصّ برمجيّ غير سليم var listItems = $( 'li' ); var rawListItem = listItems[0]; var html = rawListItem.html(); // Object #<HTMLInputElement> has no method 'html'إن أردت العمل مع عنصر مُفرد في تحديد وأردت استخدام وظائف jQuery معه، فعليك إنشاء كائن jQuery جديد انطلاقًا منه باستخدام الدّالّة .eq()، وإمرار دليل العنصر الّذي تريده: var listItems = $( 'li' ); var secondListItem = listItems.eq( 1 ); secondListItem.remove();جرب المثال في ساحة التّجربة (تأكد من ضغط زر Run with JS في هذا المثال وكل الأمثلة التالية) إنشاء كائنات جديدةللدّالّة $ دورٌ ثالث أخير: إنشاء عناصر جديدة. إن مرّرت قصاصة HTML إلى $()، فستُنشئ كائنًا جديدًا في الذّاكرة، بمعنى أنّ الكائن يُنشأ ولكن لا يُضاف إلى الصّفحة إلى أن تفعل ذلك بنفسك. $( '<p>' ); // يُنشئ عنصر <p> بلا محتوى $( '<p>Hello!</p>' ); // يُنشى عنصر <p> فيه نصّ $( '<p class="greet">Hello!</p>' ); // يُنشى عنصر <p> فيه نصّ وله صنفبإمكانك أيضًا إنشا عنصر جديد بإمرار كائنٍ يحوي معلومات تصف كيفيّة إنشاء العنصر: $( '<p>', { html: 'Hello!', 'class': 'greet' });لاحظ أنّه يجب أن نُحيط class بعلامتي اقتباس، لأنّ class كلمة محجوزة في JavaScript، وعدم إحاطتها بالعلامتين سيسبّب وقوع أخطاء في بعض المتصفّحات. راجع وثائق jQuery لتفاصيل الخصائص المختلفة الّتي يمكنك تضمينها في هذا الكائن. سنتعرّف كيف نُضيف العناصر في الصّفحة في الجزء القادم من السّلسلة، الّذي يشرح الانتقال عبر الصّفحة وتعديل محتوياتها. التّعامل مع التحديداتبعد إنشائك كائن jQuery يحوي تحديدًا، فإنّك غالبًا ما تريد فعل شيء ما به، وقبل ذلك عليك أن تتعرّف على أسلوب jQuery في التّعامل مع الكائنات. فحص تحديدبإمكاننا معرفة إن كان تحديد ما يُطابق معايير مُعيّنة باستخدام الوظيفة .is(). أكثر الطّرق شيوعًا لاستخدام هذه الوظيفة تزويدها بمُحدِّد كمُعاملٍ مفرد لها، وعندها تُعيد true أو false حسب مُطابقة التّحديد للمُحدِّد: $( 'li' ).eq( 0 ).is( '.special' ); // false $( 'li' ).eq( 1 ).is( '.special' ); // trueبإمكانك تمرير كائن jQuery أيضًا إلى الوظيفة .is()، أو حتّى كائن DOM خام، أو حتّى دالّة لإجراء اختبار أكثر تعقيدًا إن لزم. راجع الوثائق لمزيد من التّفاصيل. وظائف القراءة والكتابة والسّرد الضّمنيّبعد عمل التّحديد، تتوفّر وظائف عديدة يمكنك استدعاؤها. تقع هذه الوظائف عمومًا في إحدى مجموعتين: وظائف القراءة (getters) ووظائف الكتابة (setters). فالأولى تعطينا معلومات عن التّحديد، والثّانية تُغيّر التّحديد بشكل من الأشكال. وفي معظم الحالات يقتصر عمل وظائف القراءة على العنصر الأول في التّحديد (.text() إحدى استثناءات هذه القاعدة)؛ أمّا وظائف الكتابة فتشمل بعملها كلّ العناصر في التّحديد، مستخدمةً ما يُعرف بالسّرد الضّمنيّ (implicit iteration). معنى السّرد الضّمنيّ أنّ jQuery ستمرّ تلقائيًّا على كلّ العناصر في التّحديد عندما تستدعي وظيفة كتابة على هذا التّحديد، أيّ أنّه ليس عليك استدعاء وظيفة على كلّ عنصر في التّحديد بمفرده عندما تريد فعل شيء على كل العناصر في تحديد واحدٍ، بل اكتفِ باستدعاء هذه الوظيفة على التّحديد نفسه، وستفهم jQuery أنّ عليها تنفيذه على كلّ العناصر في التّحديد. لنفترض أنّنا نريد تغيير نصّ HTML في كل عناصر القوائم في الصّفحة، ولفعل ذلك علينا استخدام الوظيفة .html() الّتي تقوم بتغيير نصّ HTML في كلّ عناصر القوائم المُحدّدة. $( 'li' ).html( 'New HTML' );جرب المثال في ساحة التّجربة بإمكانك أيضًا إمرار دالّة إلى وظائف الكتابة في jQuery، وستُستخدم القيمة المُعادة منها باعتبارها القيمة الجديدة، وتستقبل هذه الدّالة مُعاملين اثنين: دليل العنصر (index) في التّحديد، والقيمة القديمة للشّيء الذي تحاول تغييره، وهذا مُفيد في حال احتجت معلومات عن حالة العنصر الحاليّة لتعيين حالته الجديدة بشكل صحيح. $( 'li' ).html(function( index, oldHtml ) { return oldHtml + '!!!' });جرب المثال في ساحة التّجربة السّرد الصّريح (Explicit Iteration)في بعض الأحيان، لن تلبّي وظائف jQuery الأصليّة المهمّة الّتي تريد إنجازها بدقّة، وسيكون عليك حينها المرور على العناصر في التّحديد بشكل صريح، وهذا ما تتيحه الوظيفة .each(). في المثال التّالي نستخدمها لإضافة وسم <b> في بداية عنصر القائمة، يحوي دليل العنصر: $( 'li' ).each(function( index, elem ) { // this: عنصر DOM الخام الحالي // index: دليل العنصر الحالي في التّحديد // elem: عنصر DOM الخام الحالي (مثل this) $( elem ).prepend( '<b>' + index + ': </b>' ); });جرب المثال ساحة التّجربة ملاحظة: ستلاحظ أنّ عنصر DOM الخام مُتاح ضمن الدّالّة الّتي نُمرّرها إلى .each() بطريقتين: الأولى عبر this والثّانية عبر elem. وكما ناقشنا في الجزء السّابق (أساسيّات JavaScript)، فإنّ this كلمة خاصّة في JavaScript تُشير إلى الكائن الّذي يُمثّل سياق الدّالّة الحاليّ. وفي jQuery فإنّ this تُشير في معظم الحالات إلى عنصر DOM الخام الّذي تعمل عليه الدّالّة الحاليّة. لذا فإنّها تُشير في حالة .each() إلى العنصر الحاليّ في مجموعة العناصر الّتي نسردها. السَّلسَلة (Chaining)من أكثر الأمور فائدةً في jQuery إمكانيّة "سَلسَلة" الوظائف معًا. هذا يعني أنّ بإمكاننا استدعاء سلسِلة من الوظائف على تحديدٍ ما دون الحاجة لإعادة التّحديد أو حفظه في متغيّر. بإمكاننا حتّى إنشاء تحديدات جديدة بناء على التّحديد السّابق، دون كسر السّلسلة: $( 'li' ) .click(function() { $( this ).addClass( 'clicked' ); }) .find( 'span' ) .attr( 'title', 'Hover over me' );الأمر ممكن لأنّ كل دالّة كتابة (setter) في jQuery تُعيد التّحديد الذي اُستدعيت لتعمل عليه. وهذا أمر عظيم الفائدة، حتّى أنّ مكتبات كثيرة اعتمدته تأثّرًا بـjQuery. ولكن يجب الحذر عند استخدامه. فالسّلاسل الطّويلة تجعل النّصّ البرمجيّة صعب القراءة والتّعديل والتنقيح لا قاعدة واضحة تفرض طولًا مناسبًا للسّلسلة، ولكن حتّى السلاسل القصيرة قد تحتاج إلى إعادة الصّياغة تسهيلًا لقراءتها. var listItems = $( 'li' ); var spans = listItems.find( 'span' ); listItems .click(function() { $( this ).addClass( 'clicked' ); }); spans.attr( 'title', 'Hover over me' );خاتمةلدينا الآن معلومات ممتازة عن تفاصيل عمل jQuery؛ وسنستعرض في الجزء القادم كيف يمكننا تطبيق هذه المعلومات لإنجاز أشياء حقيقيّة بها! مصادر إضافيةوثائق الواجهة البرمجيّة لـjQueryوثائق المُحدّداتترجمة (بشيء من التصرف) للجزء الثاني من سلسلة jQuery Fundamentals لمؤلّفتها Rebecca Murphey.
-
- 2
-
- تطوير الويب
- web development
-
(و 3 أكثر)
موسوم في:
-
بُنيت jQuery على لغة جافاسكريبت، وهي لغةٌ غنيّة وقويّة في حدّ ذاتها. يُغطّي هذا الدّرس أساسيّات لغة جافا سكريبت، وبعض الأخطاء الشّائعة الّتي يرتكبها المبتدئون بها. يُفيد هذا الدّرس القادمين الجدد إلى عالم البرمجة، ويفيد أيضًا المبرمجين بلغات أخرى الّذين لم يسبق لهم الاطّلاع على الجوانب المميّزة لـJavaScript. فيما يلي برنامج JavaScript بسيط يُضيف رسالةً إلى صفحة ويب: // أنشئ دالّة لإلقاء التّحية على شخص // وأسندها إلى المُتغيّر `greet` var greet = function( person, message ) { var greeting = 'Hello, ' + person + '!'; log( greeting + ' ' + message ); }; // استخدم الدالّة لتحيّة Jory، بإمرار اسمها ورسالة التّحيّة greet( 'Jory', 'Welcome to JavaScript' ); // استخدم الدالّة لتحيّة Rebecca، بإمرار اسمها ورسالة مختلفة greet( 'Rebecca', 'Thanks for joining us' );مُلاحظة: في المثال السابق، استخدمنا الدّالّة log. وهي دالّة مُساعِدة متوفّرة في الأمثلة في هذه السّلسلة فقط، وليست متوفّرة تلقائيًّا في JavaScript، يمكن استخدام log في محرّر النّصوص البرمجيّة في هذه السّلسلة، ولكن ستحتاج إلى استخدام console.log محلّها في النّصوص البرمجيّة خارج السّلسلة، وعندها ستُطبع نتائج النّصّ إلى طرفيّة المتصفّح الّذي تستعمله. // create a function that will greet a person, // and assign the function to the `greet` variable var greet = function( person, message ) { var greeting = 'Hello, ' + person + '!'; log( greeting + ' ' + message ); }; // use the function to greet Jory, passing in her // name and the message we want to use greet( 'Jory', 'Welcome to JavaScript' ); // use the function to greet Rebecca, passing in her // name and a different message greet( 'Rebecca', 'Thanks for joining us' );النّتيجة النّتيجة مطالعةلم نخض في أعماق لغة JavaScript بعدُ. شبكة مُطوّري موزيلّا (MDN) مصدر ممتاز (بالإنكليزيّة) لتعلّم JavaScript بتفاصيلها، وخصوصًا دليل JavaScript على الشّبكة. أكثر المواضيع أهمّيّة لك الآن: نظرة عامّة على JavaScriptالقيم والمتغيّرات والمكوّنات الحرفيّةالدّوالّعبارات الدّوالّ المُستدعاة فورًاالمصفوفاتمصادر إضافيةشبكة مُطوّري موزيلّا: JavaScriptChrome Developer Tools OverviewFixing these jQuery: A Guide to DebuggingChrome Developer Tools Cheat SheetChrome Dev Tools: 12 Tricks to Develop Quicker (فيديو)ترجمة (بشيء من التصرف) للجزء الأول من سلسلة jQuery Fundamentals لمؤلّفتها Rebecca Murphey.
-
- 2
-
- javascript
- jquery
- (و 5 أكثر)