لوحة المتصدرين
المحتوى الأكثر حصولًا على سمعة جيدة
المحتوى الأعلى تقييمًا في 10/26/15 في كل الموقع
-
أُحِبّ كثيرا النّظر إلى الماضي حينَ كنتُ على وشك ولوجِ عالمِ الشركات الناشئة وأجدُ أنَّ هناك أسطورةً يعتقدها الكثيرون من القادمين لهذا العالم كما أنّها في رأيي السّبب الرئيسي وراء عدم إقدامهم حتّى على المحاولة. تقول الأسطورة أنّه عليك الإلمام بجميع الأمور وأنّه يتوجب عليك لِزامًا أنْ تقوم بها بشكلٍ مثالي. ليس من المفاجئ أنْ يُفكّرَ أحدهم بهذا الشكل لأن رؤية الشركات الناشئة الناجحة تدفع بالمرء للتّخيل بأنّ أصحابها قد قاموا بكل الأمور بشكلٍ صحيح لكنني أعتقد أن الحقيقة بعيدة عن هذا التّخَيُّل كما بدأت أعتقد أنّه من المفيد والصّحي للمشروع أن تتمتَّع بقدر كافٍ من السَّذاجة عند الشّروع فيه. مغالطة ترقّب النّمو الهائل scale anticipation fallacyأحد أبرز أمثِلة ما أعتقد أنه يقع على عاتق "السذاجة الصّحيّة" هو تجنُّبُ الوقوع في ما أسميته "ترقّب النّمو الهائل"ومَكْمَنَ الخطأ هنا هو الاعتقاد أنه لبناء ما قد يَنمو لِيَشْمَلَ مليون مُسْتَعْمِلٍ عليه أن يُبْنى من البداية ليستوعب هذا الرقم حتَّى ينجح. عندما بدأت شركتي الأخيرة كانت لي جداول غير مُعدّة بشكل أمثل في قاعدة البيانات الخاصة بي، كنت أقوم بعمليات بحث عديدة في قواعد البيانات للحصول على البيانات التي كنت أدور في حلقاتها. ليس هذا وحسب، بل كنت أقوم بعمليات بحث queries زائدة للحصول على البيانات التي أحتاجها. فلم تكن لديّ أدنى فكرة عن ما قد يعنيه مُصطلح Index في عالم قواعد البيانات وبالتالي قمت بكل ما لا يُنصح بالقيام به. ومع ذلك، في البداية لم يكن هذا الأمر بالغَ الأهميّة لأنّه لم يكن لديَّ أيُّ مُستخدِمين. مع مرور الوقت واجهتني عقبات "سعِدتُ بلقائها" كما أن الخَادوم في برنامجي كافح قليلا ولم يكن لديّ أيّةُ مشكلةٍ لتحسين الأمور بالطريقة التي تلائمني. من خلال تجربتي وصلت لنتيجة أن عدم اهتمامي للجوانب المُتعلّقة بالنّمو الهائل لمشروعي قد ساعدني للوصول إلى هذه المرحلة أين أصبح التّفكير في هذا النّمو مُهمّا. في المقابل أجِدُني أتساءَلُ إنْ أنَا اهتممت بهذا الأمر (النّمو الهائل لمشروعيscalability) سابقا هل كنت سأصل إلى المرحلة أين يصبح هذا الأخير مهمّا حقَّا؟ أنت لا تعلَمُ ما لسْتَ تَعْلَمُهْأكبر التحديّات التيّ قد تواجهك عند بداية مشروعك المصَّغر أنك تعيش في عالمٍ مُسْتَقْبَلُهُ غامضٌ وغَيْرُ مَضْمُونٍ بتاتًا فأنت في مواجهة المَجْهُول. لقد أَثَرْتُ هذه النقطة سابقًا وأعتقدُ أنَّ الحلَّ يَكْمُنُ في الكفاحِ للحصول على المعرفة، المعلومة والتَّعلم من ردود الأفعال. على كلِّ حال، أجدُ أنّ إِمْعَانِي التفكير في محاولاتي السابقة لبناءِ مشاريعٍ ناشئةٍ حتَّى يومِنَا هذا يُمَكِنُنِي من القول أنّ أحد أسباب نيْلي هذا القِسط من النَّجاح هو أنّي لم أدرك تمامًا المِقدار اللَّازِم عَلَيَّ أَنْ أتعلّمَهُ لأنجح. هذا هو نوع السّذاجةِ الذّي أعْتقِدُه شيئًا جيّدًا بل سأذهب بعيدا باعتقادي هذا لدرجةِ القول أنّني خائفٌ من أنّه في المُستقبل سأكون على اطّلاع لأيِّ مدى ستكون الأمور صعبة. لقد تكلّمَ ستيف بلانك في هذا الصدد في مقالته "يافع جدّا ليعلم أن الأمر لا يمكن إنجازه" وأعجبني تحديدا قوله: كن فخورا بسذاجتك ولْتَخَفْ مِنْ معرفتك الواسعةمغالطةُ ترقّب النّمو الهائل هي واحدٌ من الأمثلة التّي تَدُلُّ على سذاجتي التي اتضح فيما بعد أنها ميزةٌ فالأمر المهم عند إنشاء المشاريع المصّغرة ليس مدى سوء تعليماتك البرمجية أو أي شيء آخر بل كل ما يهم هو أن تخرج لِلْعَلَنِ بشيء يُريدُه النَّاس. لقد اخترتُ محاولة بدء مشروع جديد فور التخرج من الجامعة عِوَضَ هَدْرِ الوقت في أمور أخرى وقد كان مُضِيُّ عامين ارتكبتُ فيهما الكثير مِنَ الأخطاءِ صعبًا عليَّ لكنَّنِي تحصلتُ أخيرا على قليلٍ من النجاح. ومع ذلك، فإنّ الشّيء الرّئيسيَّ الذّي تعلّمتُهُ ليس "كيفية إنجاز المهمَّات بِمثاليَّة" بل أن التَّوازن المطلوب هو أن أقوم بالأمور بطريقة جيدة كفاية في الوقت الحاضر. البعض قد يطلق على هذا مبدأ 20/80 أو مبدأ باريتو. أعتقد أنّنّي لو أمضيت وقتا في مجال آخر لكنت جلبت المهارات التي تعلمتها في محاولة بدء مشروع مصغر سنوات من اليوم ولربّما حاولت القيام بكل شيء بمثالية وهذا ما سيكون غلطة كبيرة. أعتقد أن التّشبّث بعقل المبتدإ أمر هام للغاية وكما قال ستيف جوبز: ما رأيك حول تأثير السّذاجة في بناء المشاريع المصّغرة؟ ترجمة -وبتصرّف- للمقال Healthy naivety لصاحبه جويل غاسكوين (مؤسس Buffer).1 نقطة
-
كما هو موضح في العنوان فإنّك في هذا الدرس سوف تتعلم كيفية إنشاء تأثير وكأنّك تتصفح كتابًا ما. وسوف نستخدم في هذا الدرس إضافة تدعى BookBlock، والفكرة من هذا الدرس هو أنّك سوف تقوم بإنشاء تأثير يُمكّن الزوار من تصفح موقع ما وكأنهم يتصفحون أحد الكتب. الفكرة هي أنّك سوف تتصفح صفحات الموقع باستخدام سهمين سوف يكونان موجودين في أعلى الصفحة أو أزرار لوحة المفاتيح أو حتى بالسحب باستخدام الفأرة وأيضًا سيكون هناك قائمة جانبية سوف تظهر عندما تقوم بالضغط على أيقونة ما. وسوف تحتوي القائمة الجانبية على روابط لصفحات الموقع وعندما تقوم بالضغط على أحد هذه الروابط فإنّها سوف تنقلك إلى الصفحة المطلوبة. سوف نستخدم أيضًا إضافة اسمها jScrollPane وذلك للحصول على شريط تمرير (scrollbar) يظهر عندما يكون المحتوى أطول من ارتفاع المتصفح. وهذه قائمة بإضافات jQuery التي سوف نستخدمها: BookBlockCustom jQuery++jScrollPanejQuery Mouse Wheel PluginCustom Mdernizerيمكنك معاينة المثال الموضح في هذا الدرس من هنا. كما يمكنك تحميل الملفات المصدرية. بنية ملف HTMLفي البداية يجب أن يكون لدينا حاوٍ رئيسي لاحتواء جميع العناصر، وداخل هذا الحاوي سوف يكون هناك عنصر <div> للقائمة الجانبية وسوف نعطيه فئة (class) بالاسم "menu-panel" وسوف يكون هناك عنصر <div> آخر يحتوي على المحتوى الرئيسي للموقع وسوف نعطيه فئة بالاسم "bb-custom-wrapper". وفي داخل كل قسم سوف يكون هناك حاوٍ للمحتوى وعنصر <div> سوف نحتاجه من أجل شريط التمرير الذي ذكرناه سابقًا. <div id="container" class="container"> <div class="menu-panel"> <h3>Table of Contents</h3> <ul id="menu-toc" class="menu-toc"> <li class="menu-toc-current"><a href="#item1">Self-destruction</a></li> <li><a href="#item2">Why we die</a></li> <li><a href="#item3">The honeymoon</a></li> <li><a href="#item4">A drawing joke</a></li> <li><a href="#item5">Commencing practice</a></li> </ul> </div> <div class="bb-custom-wrapper"> <div id="bb-bookblock" class="bb-bookblock"> <div class="bb-item" id="item1"> <div class="content"> <div class="scroller"> <h2>Self-destruction</h2> <p>...</p> </div> </div><!-- /content --> </div><!-- /bb-item --> <div class="bb-item" id="item2"><!-- ... --></div> <div class="bb-item" id="item3"><!-- ... --></div> <div class="bb-item" id="item4"><!-- ... --></div> <div class="bb-item" id="item5"><!-- ... --></div> </div><!-- /bb-bookblock --> <nav> <a id="bb-nav-prev" href="#">←</a> <a id="bb-nav-next" href="#">→</a> </nav> <span id="tblcontents" class="menu-button">Table of Contents</span> </div><!-- /bb-custom-wrapper --> </div><!-- /container -->سوف نقوم بربط عناصر القائمة الجانبية بصفحات الموقع (التي تحمل الفئة "bb-item)، وسوف نُضيف أيضًا سهمين في أعلى الصفحة من أجل التنقل بين الصفحات وزر يقوم بفتح وإغلاق القائمة الجانبية. لنقم الآن بإضافة تنسيقات CSS. تنسيقات CSSلن نتحدث هنا عن التنسيقات التي تأتي مع إضافة BookBlock لأنك سوف تجدها داخل ملف bookblock.css، وإنّما سوف نُركّز على التنسيقات الأخرى المهمة. لنبدأ التنسيقات بإضافة سطر يقوم بجلب الخط المسمى "Lato" من خدمة Google web fonts: @import url(http://fonts.googleapis.com/css?family=Lato:300,400,700);سوف نقوم بإعطاء الوسم <html> الخاصية height: 100% وذلك لأننا سوف نحتاج أن نجعل بعض العناصر تتمدد على ارتفاع المتصفح كاملًا: html { height: 100%; }سوف نستخدم أيضًا الخاصية box-sizing: border-box وذلك حتى نستخدم قيم مئوية لكل من العرض والإرتفاع أثناء استخدام padding دون القلق حول أبعاد العناصر والقيام بعمليات حسابية نحن بغنىً عنها: *, *:after, *:before { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; padding: 0; margin: 0; }لنقم الآن بتعريف الخط الذي سوف نستخدمه في الموقع (العنصر body) ونُعطيه ارتفاع بقيمة 100% (تذكّر أننا نريد ارتفاع بهذه القيمة لأنه سوف يكون هناك عناصر تتموضع بشكل مطلق (absolute positioning) وسوف تحتاج أن تتمدد على ارتفاع المتصفح كاملًا): body { font-family: 'Lato', Calibri, Arial, sans-serif; font-weight: 400; font-size: 100%; color: #333; height: 100%; }سوف نستعمل أيضًا إضافة Modernizr وسوف نُضيف الفئة "no-js" إلى وسم <html>، فإذا كانت الجافاسكربت مفعّلة فإنّ Modernizr سوف يستبدل تلك الفئة بالفئة "js". وهذا سوف يساعدنا على إعطاء خصائص CSS معينة لبعض العناصر التي لا نريدها إذا كانت الجافاسكربت معطّلة. لاحظ أيضًا أننا نحتاج أن يكون عرض الصفحة وارتفاعها بقيمة 100% فقط إذا كانت الجافاسكربت مفعّلة وعندها فقط نريد من العنصر body أن يكون له خاصية overflow: hidden: .js body { overflow: hidden; }وهذه بعض التنسيقات الخاصة بالروابط: a { color: #555; text-decoration: none; } a:hover { color: #000; }نريد من الحاوي الرئيسي أن يكون بعرض وارتفاع المتصفح كاملًا، وسوف نقوم بموضعة القائمة الجانبية خارج هذا الحاوي باستعمال الخاصية left وإعطائها قيمة سالبة تكون بنفس قيمة العرض الخاص بالقائمة الجانبية. والفكرة هي أنّه عند النقر على أيقونة القائمة الجانبية فإنّ الحاوي سوف يتحرك إلى اليمين مما يؤدي إلى ظهور القائمة الجانبية. دعونا إذًا نقوم بإعطاء الحاوي الرئيسي عرضًا وارتفاعًا بقيمة 100% وأن نُضيف الخاصية transition إلى الحاوي container: .container, .bb-custom-wrapper, .bb-bookblock { width: 100%; height: 100%; } .container { position: relative; left: 0px; transition: left 0.3s ease-in-out; }عند النقر على أيقونة القائمة الجانبية فإن فئة (class) أخرى سوف يتم إضافتها إلى الحاوي container والتي سوف تحتوي على الخاصية left: 240px (نفس العرض الخاص بالقائمة الجانبية) وبالتالي فإنّ الصفحة كاملة سوف تتحرك إلى اليمين بمقدار 240px وبالتالي ظهور القائمة الجانبية: .slideRight { left: 240px; }ولكن بدون الجافاسكربت لن نكون قادرين على القيام بما سبق لذلك سوف نقوم بإضافة الخاصية padding-left: 240px: .no-js .container { padding-left: 240px; }ونريد أن تكون القائمة الجانبية ثابتة في الجانب الأيسر بشكل افتراضي: .menu-panel { background: #f1103a; width: 240px; height: 100%; position: fixed; z-index: 1000; top: 0; left: 0; text-shadow: 0 1px 1px rgba(0,0,0,0.1); }وإذا كانت الجافاسكربت مفعلة فسوف نقوم بموضعة القائمة الجانبية بشكل مطلق وإلى اليسار بقيمة -240px: .js .menu-panel { position: absolute; left: -240px; }وهذه هي التنسيقات الخاصة بعناصر القائمة الجانبية: .menu-panel h3 { font-size: 1.8em; padding: 20px; font-weight: 300; color: #fff; box-shadow: inset 0 -1px 0 rgba(0,0,0,0.05); } .menu-toc { list-style: none; } .menu-toc li a { display: block; color: #fff; font-size: 1.1em; line-height: 3.5; padding: 0 20px; cursor: pointer; background: #f1103a; border-bottom: 1px solid #dd1338; } .menu-toc li a:hover, .menu-toc li.menu-toc-current a{ background: #dd1338; }وأمّا بالنسبة للقائمة الرئيسية التي سوف تحتوي على السهمين فإننا سوف نقوم بموضعتها بشكل مطلق وفوق جميع العناصر الأخرى: .bb-custom-wrapper nav { top: 20px; left: 60px; position: absolute; z-index: 1000; }كما أنّ روابط السهمين وزر القائمة الجانبية سوف يتموضعان بشكل مطلق (position: absolute) وسوف نعطيها الخاصية border-radius: 50% لنجعلها تظهر كالدائرة: .bb-custom-wrapper nav span, .menu-button { position: absolute; width: 32px; height: 32px; top: 0; left: 0; background: #f1103a; border-radius: 50%; color: #fff; line-height: 30px; text-align: center; speak: none; font-weight: bold; cursor: pointer; } .bb-custom-wrapper nav span:last-child { left: 40px; } .bb-custom-wrapper nav span:hover, .menu-button:hover { background: #000; }سوف يكون الزر الذي يفتح ويغلق القائمة الجانبية موجودًا في أعلى يسار الصفحة وسوف نقوم بإخفاء النص الموجود بداخله (نريد أن تظهر الأيقونة فقط): .menu-button { z-index: 1000; left: 20px; top: 20px; text-indent: -9000px; }لنقم الآن بإنشاء أيقونة بسيطة بدون استعمال أي صور وذلك باستعمال العنصر الزائف :after واستعمال الخاصية box-shadow والتي سوف تعمل على إنشاء الخطين العلوي والسفلي للأيقونة: .menu-button:after { position: absolute; content: ''; width: 50%; height: 2px; background: #fff; top: 50%; margin-top: -1px; left: 25%; box-shadow: 0 -4px #fff, 0 4px #fff; }وفي حالة كان الجافاسكربت معطلًا فإننا نريد أن نخفي هذه العناصر: .no-js .bb-custom-wrapper nav span, .no-js .menu-button { display: none; }لننتقل الآن إلى تنسيق الأجزاء الداخلية لكل قسم من أقسام الصفحة (bb-item). نريد أن يتم موضعة المحتوى (content) بشكل مطلق ونريد ان نستعمل الخاصية overflow: hidden، وهذا مهم لأننا نريد تطبيق شريط التمرير هنا ونريد أن نفعل ذلك فقط عند قلب/تغيير الصفحة. فإذا لم نستخدم الخاصية overflow: hidden فإنّك سوف ترى المحتوى يتداخل ببعضه. وأعيد وأكرر مرة أخرى بأنّ هذا سوف يحدث فقط إذا كان الجافاسكربت مفعلًا ولذلك سوف نستخدم الفئة "js": .js .content { position: absolute; top: 60px; left: 0; bottom: 50px; width: 100%; overflow: hidden; }العنصر <div class="scroller"> هو الذي سوف ينمو مع المحتوى لذلك سوف نعطيه الخاصية padding: .scroller { padding: 10px 5% 10px 5%; }لاحظ أننا استعملنا قيم مئوية للجوانب وذلك حتى نجعل الصفحة تتجاوب مع حجم الشاشة. دعونا نتخلص من الحواف الحادة عندما نقوم بالتمرير (scroll) وذلك باستخدام العناصر الزائفة إلى أعلى وأسفل عنصر المحتوى مع استخدام تدرج بين اللون الأبيض والشّفّاف: .js .content:before, .js .content:after { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 20px; z-index: 100; pointer-events: none; background: linear-gradient( to bottom, rgba(255,255,255,1) 0%, rgba(255,255,255,0) 100% ); } .js .content:after { top: auto; bottom: 0; background: linear-gradient( to top, rgba(255,255,255,1) 0%, rgba(255,255,255,0) 100% ); }هذا سوف يجعل النص يظهر بشكل باهت. لنقم الآن بتنسيق عناصر النصوص: .content h2 { font-weight: 300; font-size: 4em; padding: 0 0 10px; color: #333; margin: 0 1% 40px; text-align: left; box-shadow: 0 10px 0 rgba(0,0,0,0.02); text-shadow: 0 0 2px #fff; } .no-js .content h2 { padding: 40px 1% 20px; } .content p { font-size: 1.2em; line-height: 1.6; font-weight: 300; padding: 5px 8%; text-align: justify; }كل ما تبقى علينا الآن من تنسيقات CSS هو استخدام الـmedia queries. فإذا كانت الجافاسكربت معطلة فإننا لا نريد أن تظهر القائمة الجانبية إذا كان العرض أقل من 800px. كان هذا فقط مثالًا بسيطًا على كيفية التحكم بالعناصر تحت ظروف وشروط معينة. الـmedia query الأخيرة سوف تعمل على تكبير الخط قليلًا من أجل الأجهزة صغيرة الحجم كالهواتف. @media screen and (max-width: 800px){ .no-js .menu-panel { display: none; } .no-js .container { padding: 0; } } @media screen and (max-width: 400px){ .menu-panel, .content { font-size: 75%; } }كان هذا كل ما يتعلق بتنسيقات CSS ويتبقى علينا استخدام بعض الجافاسكربت. بعض الجافاسكربتسوف نبدأ اولًا بتخزين (caching) بعض العناصر حتى لا نضطر إلى استدعائها في كل مرة وسوف نقوم أيضًا بتهئية/مناداة إضافة BookBlock. نُريد أيضًا أن نقوم بضبط بعض الأمور بعد كل قلب/تغيير للصفحة وهذه الأمور هي رقم الصفحة الحالية والسلوك الخاص بإضافة jScrollPane. وهذا محدد في الاستدعاء الخلفي (callback) المسمى onEndFlip والممرر إلى إضافة BookBlock. var $container = $( '#container' ), // the element we will apply the BookBlock plugin to $bookBlock = $( '#bb-bookblock' ), // the BookBlock items (bb-item) $items = $bookBlock.children(), // index of the current item current = 0, // initialize the BookBlock bb = $( '#bb-bookblock' ).bookblock( { speed : 800, perspective : 2000, shadowSides : 0.8, shadowFlip : 0.4, // after each flip... onEndFlip : function(old, page, isLimit) { // update the current value current = page; // update the selected item of the table of contents (TOC) updateTOC(); // show and/or hide the navigation arrows updateNavigation( isLimit ); // initialize the jScrollPane on the content div for the new item setJSP( 'init' ); // destroy jScrollPane on the content div for the old item setJSP( 'destroy', old ); } } ), // the navigation arrows $navNext = $( '#bb-nav-next' ), $navPrev = $( '#bb-nav-prev' ).hide(), // the table of content items $menuItems = $container.find( 'ul.menu-toc > li' ), // button to open the TOC $tblcontents = $( '#tblcontents' ), transEndEventNames = { 'WebkitTransition': 'webkitTransitionEnd', 'MozTransition': 'transitionend', 'OTransition': 'oTransitionEnd', 'msTransition': 'MSTransitionEnd', 'transition': 'transitionend' }, // transition event name transEndEventName = transEndEventNames[Modernizr.prefixed('transition')], // check if transitions are supported supportTransitions = Modernizr.csstransitions;لنقم أولًا بربط الأحداث ببعض العناصر التي تم تهيئتها سابقًا، كما أننا نريد أن نقوم بتهيئة jScrollPane لأول عنصر (العنصر الحالي). function init() { // initialize jScrollPane on the content div of the first item setJSP( 'init' ); initEvents(); }بما أننا سوف نقوم بتهيئة وإعادة تهيئة وتدمير jScrollPane فلنقم بتعريف دالة لذلك: function setJSP( action, idx ) { var idx = idx === undefined ? current : idx, $content = $items.eq( idx ).children( 'div.content' ), apiJSP = $content.data( 'jsp' ); if( action === 'init' && apiJSP === undefined ) { $content.jScrollPane({verticalGutter : 0, hideFocus : true }); } else if( action === 'reinit' && apiJSP !== undefined ) { apiJSP.reinitialise(); } else if( action === 'destroy' && apiJSP !== undefined ) { apiJSP.destroy(); } }سوف نحتاج إلى ربط العديد من الأحداث كالتالي: سوف يتم استدعاء الدالتين ()next و()prev الخاصتين بإضافة BookBlock وذلك عند النقر على أزرار التنقل أو السحب باستخدام الفأرة.سوف يظهر جدول المحتويات أو يختفي عند النقر على زر القائمة (tblcontents$).سوف يتم استدعاء الدالة ()jump الخاصة بإضافة BookBlock وذلك عند النقر على أي عنصر من عناصر جدول المحتويات.سوف يتم تهيئة jScrollPane عند القيام بتغيير حجم النافذة (window resize).function initEvents() { // add navigation events $navNext.on( 'click', function() { bb.next(); return false; } ); $navPrev.on( 'click', function() { bb.prev(); return false; } ); // add swipe events $items.on( { 'swipeleft' : function( event ) { if( $container.data( 'opened' ) ) { return false; } bb.next(); return false; }, 'swiperight' : function( event ) { if( $container.data( 'opened' ) ) { return false; } bb.prev(); return false; } } ); // show TOC $tblcontents.on( 'click', toggleTOC ); // click a menu item $menuItems.on( 'click', function() { var $el = $( this ), idx = $el.index(), jump = function() { bb.jump( idx + 1 ); }; current !== idx ? closeTOC( jump ) : closeTOC(); return false; } ); // reinit jScrollPane on window resize $( window ).on( 'debouncedresize', function() { // reinitialise jScrollPane on the content div setJSP( 'reinit' ); } ); } ظهور أزرار التنقل من عدمه سوف يعتمد على الصفحة الحالية، فإذا كُنّا في الصفحة الأولى فإننا سوف نرى فقط زر "التالي" وإذا كُنّا في الصفحة الأخيرة فإننا سوف نرى فقط زر "السابق": function updateNavigation( isLastPage ) { if( current === 0 ) { $navNext.show(); $navPrev.hide(); } else if( isLastPage ) { $navNext.hide(); $navPrev.show(); } else { $navNext.show(); $navPrev.show(); } }عندما نفتح جدول المحتويات (القائمة الجانبية) فإننا نريد أن تختفي عناصر التنقل وأن تظهر مرة أخرى عندما نقوم بإغلاق القائمة الجانبية. سوف نقوم بتحريك القائمة الجانبية باستخدام خاصية transition، وإذا لم تكن هذه الخاصية مدعومة من المتصفح فإننا سوف نستخدم fallback بسيط: function toggleTOC() { var opened = $container.data( 'opened' ); opened ? closeTOC() : openTOC(); } function openTOC() { $navNext.hide(); $navPrev.hide(); $container.addClass( 'slideRight' ).data( 'opened', true ); } function closeTOC( callback ) { $navNext.show(); $navPrev.show(); $container.removeClass( 'slideRight' ).data( 'opened', false ); if( callback ) { if( supportTransitions ) { $container.on( transEndEventName, function() { $( this ).off( transEndEventName ); callback.call(); } ); } else { callback.call(); } } } خاتمةهذا كان كل شيء يخص هذا الدرس أتمنى أن يكون قد أعجبك وأن تكون قد وجدته مفيدًا. ترجمة -وبتصرّف- للدرس Fullscreen Pageflip Layout لصاحبته Mary Lou.1 نقطة
-
العديد من المستقلين يعانون من هذه المشكلة وأنا كنت منهم، ففي بداية عملي عانيت كثيرًا مع أهلي وأصدقائي بسبب كثرة الطلبات والأحاديث والتسلية أثناء عملي بالإضافة إلى الزيارات غير المتوقعة والمفاجئة. من جهتي كان الحلّ هو الصراحة غير المباشرة واللطيفة وذلك كي لا أُحرجهم فالاهتمام محبّة دومًا، ولذلك بدأت أشرح لهم وأعرّفهم على طريقة عملي وأُطلعهم على أسلوب العمل والوقت الذي يتطلبه أداء المشاريع والدقّة والمنافسة في هذا المجال وغيرها من الأمور التي أحببت أن أُوصلها لهم بطريقة غير مباشرة. في الحقيقة عدد منهم أُعجب في الفكرة وأراد أن يبدأ العمل الحرّ بنفسه وكنت سعيدة للغاية بهذا الموضوع. ومرّةً تلو الأخرى بدأ الأهل والأصدقاء يتفهمون طبيعة عملي ويقدّرون أن المنزل هو مكتبي في الوقت الحاليّ وبدؤوا يُظهرون احترامًا للمواعيد والوقت بشكلٍ ملفت وجميل جدًا. أتمنى أن تفلح هذه الطريقة معك صديقتي1 نقطة
-
لم توضّح مطلبك بشكل كامل في سؤالك، لكنني فهمت أنك ترغب بنشر خدمة شركتك الناشئة في مواقع مختصة بالبيع والتسويق -من أسميتهم مندوبي مبيعات-، لكنك تريد أن تعطيهم أقل مما هو متعارف عليه. أنصحك وإن كان لا بد من تسويق منتجك في هذه المواقع أن تطلع على القواعد الأساسية في نشر الإعلانات، وفي نظام التسويق بالعمولة -الافليت- والذي يعتمد على الأشخاص للترويج للمبيعات عبر الانترنت بعمولة محددة، ويتم اقتطاع هذه العمولة من سعر المنتج عند كل عملية شراء تتم عن طريق المروّج. يمكنك أيضًا نشر إعلانات لشركتك في مساحات إعلانية مخصصة في المواقع وتدفع لهم حسب معدل النقرة، لذا يجب أن تحدد نوع الإعلانات التي تريدها وتبحث عن أكثرها فاعلية عبر الانترنت. على كل حال ثمة ثمن لابد من دفعه، ويجب أن لا يكون خسارة على الشركة، لذا سيكون من المهم بداية أن تحتسب تكاليف التأسيس وتطرح سعرًا منافسًا لمنتجك، لكن يكفل لك تغطية الحملة الإعلانية والترويج له ونسبة مندوبي المبيعات.1 نقطة
-
كان سيكون من الرائع لو أن المصمّم هو من يصمّم والمطوّر هو من يطوّر/يبرمج، لكن للأسف هذا ليس الحال، بل سيتبادل المصمم والمطوّر الأدوار بين الحين والآخر، وما لفت نظري هو وجود العديد من الدروس والمقالات الّتي تشرح للمصمم كيف يطوّر ولكن القليل منها يشرح للمطوّر كيف يُصمّم، ومن هذا المنطلق فكرت في مشاركة بعض الحيل والأفكار البسيطة لكم معشر المطورين. ما يسعني قوله بدايةً، أني لن أكون قادرًا على تعليمك أساليب التصميم الأنسب في مقالة واحدة، حيث يأتي هذا الأمر مع الوقت والتدريب وربما شهادة معتمدة، وقبل أن أنسى الملكة/الموهبة، علمًا أني لن أجعل منك مصممًا محترفًا، لكنّي سأقدّم لك بعض النصائح في كيفيّة تجنّب أبرز المشاكل الّتي تواجه بعض المطوّرين بين الحين والآخر. ملاحظات عامةقبل أن أشرع في التطرّق إلى الحيل نفسها، أود فقط مشاركة بعض الملاحظات العامة والتي بَنيتها من خلال مشاهدتي لتصاميم صمّمها مطوّرون، أهدف بهذه الملاحظات تغيير نظرة المطوّر حول التصميم، فالتصميم ليس مجرّر ترتيب للبكسلات (pixels) في صفحة بيضاء. التصميم حس فني قبل كل شيءإن الشيفرة البرمجيّة التي يكتبها المطوّرون إما أن تعمل أو لا، بمعنى آخر تميل الشيفرة إلى المنطق أكثر من أي شيء آخر، فمن اليسر فهم واستوعاب العقل الإلكتروني على عكس نظيره العقل البشري، الذي يميل إلى التناقض والتباين وعدم الثبات على مبدأ واحد، وهذا بالضَّبط عالم المصممين. يحاول المصممون جاهدين الانخراط مع الناس، وذلك من محاولة التماس ما يشعرون به، واضعين أنفسهم مكان المستخدِم في سبيل فهم طريقة تفكيره وأسلوبه في معالجة الأمور. أجد الكثير من المطورين يقعون في هذا الخطأ مرارًا وتكرارًا، حيث أنهم يعاملون المستخدم كما لو أنّه يفكر بنفس طريقة تفكيرهم، هم يقومون بخلق الافتراضات حول دوافع وغايات المُستخدِم وقدراته، ودائمًا ما يفشلون في فهمه بالشكل الصحيح. أريد التأكيد على أمر في غاية الأهميّة، وهو محاولة فهم عقليّة المستخدم، أمعن في التفكير فيما يكره ويُحب المستخدم، هل هو في عجلةٍ من أمره؟ ما هو مقصده الأساسي؟ ما هو مقدار التشتت المتوقّع من المستخدم؟ حاول جاهدًا الدخول إلى ذهن المستخدِم، سيكون ذلك أمرًا مساعدًا لك في التصميم بالتأكيد. تجنب تطبيقات التصميم الاحترافيةيميل بعض المطوّرون إلى استخدام أدوات احترافيّة عندما يرغبون في تصميم الموقع بأنفسهم مثل تطبيق فوتوشوب، وذلك بحجّة أن جميع المصممين المحترفين يستخدمونه، طبعًا لا شك في أن المُصممين يستخدمون أدوات من هذا النوع لا بل قد يرسمون بأيديهم في بعض الأحيان، مع ذلك فإني لا أنصح بذلك إلا إذا كنت بالفعل تستطيع استخدام هذا النوع من التطبيقات، حيث أن استخدام هذا النوع من الأدوات من شأنه يزيد من صعوبة استكمال التصميم بدلًا من تسهيلها وذلك في حال عدم الإلمام باستخدامها بالشكل المطلوب. ألا يكفي فهم وتطبيق مبادئ التصميم نفسها؟ لماذا يجب تعلّم استخدام تطبيق جديد، أنت كمطوّر يتقن كتابة الشيفرة، يستحسن بك تصميم الموقع باستخدام CSS و HTML على اعتبار أنها الأدوات التي تتقنها بالفعل، طبعًا لن يكون التصميم ساحرًا آسرًا، ولكن هذا ليس الهدف من الأساس. لا تحاول وصول عنان السماء بالتصميم بل حاول أن تكون موضوعيالا تحاول تصميم مواقع إبداعيّة أو مبتكرة، فيصعب الأمر حتى على محترفي التصميم، حاول فعل ذلك وسينتهي بك المطاف بتصميم يحبّه الأقليّة مقابل أكثريّة تكرهه. العب على المضمون، اجعل من التصميم خفيف الظل سريع الفهم، فلنكن واقعيين التصميم المناسب أو لنقل المقبول لا يترسخ في أذهان الناس، بمعنى آخر التصميم الجيّد يُستخدم ولا يُنتقد. إن لم يتحدّث المستخدم عن التصميم فهذا يعني أن التصميم لم يسبب له أي مشاكل وهذا مؤشر جيّد، وكما أسلفت لن يكون تصميمك بذلك التصميم الجذاب الخلاب ولكنه على الأقل يلبي الغرض. النصائح العمليةسأكتفي بهذا القدر من التنظير، وسأبدأ بالتحدّث عن الأمور العمليّة، فمثلًا كيف لك أن تجعل من التصميم مناسبًا بالقدر الكافي بعيدًا عن كونه قبيحًا؟ تمام، سأقترح خمس نقاط محدّدة يجب التركيز عليها، طبعًا يمكنني الكتابة عن كل منها بالتفصيل، ولكني سأبسّط الأمور هنا واجعلها سهلة التطبيق. الخطوط Typographyإن نجاح استخدام الخطوط Typography في التصميم يأتي من خلال الثبات على مبدأ واحد في كامل التصميم، بمعنى تجنّب استخدام العديد من أنواع الخطوط typefaces، خطّ أو خطّان سيكفيان بالغرض، وتجنّب أيضًا استخدام أحجام متعدّدة وأوزان لونيّة مختلفة، بل استخدمها في التأكيد على أهميّة جزء معيّن من المحتوى، فكلما كان المحتوى هام كلما كان الخط أكبر وأعرض. حاول دائمًا الثبات على تنسيق واحد في كامل التصميم/التطبيق، فإن كان أحد العناوين بحجم ووزن معيّن في أحد الصفحات، تأكّد من أنّه على نفس السويّة في باقي الصفحات، خاصّة وأن CSS تجعل من هذه المهام سهلة التطبيق في المجمل. أخيرًا، لا تهتم بالخطّ فقط بل أيضًا في طول السطر وارتفاعه، لا تجعل من السطور طويلة، ربما 40 إلى 60 حرف كافٍ في الأغلب، كي لا تصبح هذه السطور صعبة القراءة، أضف أيضًا قليلًا من المساحة البيضاء بين السطور، سيجعل ذلك من الصّفحة فسيحة ووسيعة وسهلة القراءة. استخدم المساحات البيضاء whitespaceإن استخدام المساحات البيضاء whitespace ليس بذلك السر في التصميم، ومن خلال خبرتي فإن إضافة المزيد من المساحة دائمًا هو أمر جيّد، لأن المسافات تسهّل من عمليّة القراءة، وتعطي إحساسًا بالبساطة وتُوصِل الفكرة بيُسر ورحابة وإبداع فنّي وبأقل مجهود ممكن. نميل في معظم الأحيان إلى تصغير حجم الصّفحة قدر الإمكان للتقليل من طولها، فيدفعنا هذا الأمر إلى حشر المحتوى وتكديسه على حساب المساحات البيضاء، قاوم هذه الرغبة، وكن سخيًّا في الحشوة padding والهوامش margins والارتفاع بين السطور، ولا تخف من الأجزاء الفارغة من الصّفحة. النظام الشبكيقد يشتكي البعض بأن تصميم الموقع صَندوقيّ عند استخدام الأنظمة الشبكيّة في التصميم، ولكن في الحقيقة إن التصاميم الصندوقيّة جيّدة ومناسبة لأغلب المواقع والتصاميم، يجب على الموقع الحسن أن يتكوّن من بنية تحتيّة تتألف من أعمدة (columns) وصفوف (rows)، فهي تساعد المستخدم على فهم هرميّة الموقع وتنظم أركانه، وعلى الرغم من أن المصمّم الشاطر سيخرج عن النص في بعض الأحيان ولا يلتزم بالنظام الشبكي، ولكن سيكون دائمًا هناك بُنيّة شبكيّة خلف الستار تسهل من تطبيق تصميمه على أرض الواقع. حدّد عدد الأعمدة التي يجب على الموقع أن يمتلكها، وتأكّد من هذه الأعمدة متطابقة في جميع أرجاء الموقع، ولكن عند الضرورة لا تتردّد في التوسّع واستخدام أكثر من عمود، وتأكّد أيضًا من توزّع العناصر بشكل متناسق في النّظام الشبكي وألا تختلف من صفحة إلى أخرى، مثل القوائم العلويّة وشريط التنقل وشريط البحث. قد يبدو النظام الشبكي مقيّدًا لعمليّة التصميم ولا يحث على الإبداعيّة ولكنّه أمر أساسي لنجاح أي تصميم. الألوانيُعتبر التعامل مع الألوان أمرًا ليس بالهيّن، وطالما لديك المجال تجنّب استخدام الكثير من الألوان، لا بل من الأفضل استخدام أدوات آليّة في توليد الألوان، مثل أداة الألوان المقدّمة من شركة أدوبي Adobe Color CC، حيث تسمح لك هذه الأداة إما بالاختيار من مجموعة ألوان موجودة بالفعل أو إنشاء مجموعة لونيّة جديدة تُناسب الهويّة البصريّة/اللونيّة للموقع corporate colour. لاحظ أنها تتضمّن على خمسة ألوانٍ في اللوحة الواحدة، وهذا أمر حسن في الحقيقة، لا تُفرط في استخدام عديد الألوان، ولا تنس الاستفادة من تباين الألوان في التمييز بين المحتوى الهام والمحتوى الأهم، لأن التباين في الألوان هو الطريقة الأفضل في تمييز المحتوى وليس تعدّد الألوان. الصورتفتقر معظم تصاميم المطوّرين إلى الصور، وربما هذا ليس بالشيء السيء، فمن السهل إساءة استخدام الصور، مع ذلك فأنا أشجّع على استخدامها حتى لو كان في الأمر بعض المغامرة، لما لها دور في لفت النظر وإلقاء الضوء على المحتوى الهام في الصّفحة. يُمكن لاختيار الصور أن يكون صعبًا، ولكن إليك بعض الاقتراحات التي ستوجهك نحو الطريق الصحيح في الاختيار: تجنّب استخدام الصور المتحركة.اختر الصور ذات الأماميّة foreground (صدر الصورة) القويّةاضغط الصور (compression) ولكن لا تبالغ في الضغط.استخدم الوجوه، فهي تجذب نظر الزوّار.تجنّب استخدام القصاصات الفنيّة clipart.خاتمةقد وصلنا إلى ختام المقال، أرجو أن أكون قد وفقت في تقديم المساعدة ولو بالشيء القليل، طبعًا يوجد العديد مما قد يُضاف، ولكن لا بأس بهذه الخطوط العريضة كبداية، وفي حال أردت الانخراط في المزيد من التفاصيل بهدف تطوير مهاراتك ونقلها إلى مستوى متقدّم، عليك بتصفّح مقالات التصميم هنا في الأكاديميّة، فيوجد العديد من المقالات الدسمة. ترجمة وبتصرف للمقال: When developers design لصاحبه: Paul Boag.1 نقطة