بعد أن تعرفنا في المقال السابق على إطار العمل Alpine.js وأنشأنا نموذج مُصغر للإطار من الصفر بهدف التعلم وفهم آلية عمل هذا الإطار، سنقوم في هذا المقال بإنشاء بعض الأمثلة البسيطة باستخدام Alpine.js وسنُغطي مجموعة من المواضيع المهمة في الإطار كإنشاء المكونات، التعامل مع الأحداث، عرض البيانات وإنشاء رسومات متحركة.
إنشاء نافذة منبثقة Modal
هذا المثال لإنشاء نافذة منبثقة عبر Alpine.js، نقوم أولًا بإنشاء هيكلية HTML:
<!doctype html> <html lang="ar" dir="rtl"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>مثال لنافذة منبثقة</title> </head> <body> <div class="modal-wrapper"> <div class="modal"> محتوى النافذة المنبثقة </div> </div> </body> </html>
سنضيف بعض تنسيقات CSS لتظهر النافذة بشكل جيد، في عنصر head
نضيف وسم style
ونضع به التنسيقات التالية:
<style> body { margin: 0; } .modal-wrapper { position: absolute; width: 100%; height: 100%; background-color: rgba(0, 0, 0, .5); display: flex; align-items: center; justify-content: center; } .modal { background-color: #fff; width: 30%; padding: 20px; box-shadow: 5px 5px 5px #333; border-radius: 5px; } </style>
وسيكون مظهر النافذة بعد فتح صفحة HTML بالشكل التالي:
نريد التحكم الآن في إخفاء هذه النافذة، بحيث عند الضغط بزر الفأرة خارج حاوية النافذة البيضاء أو عند الضغط على زر الهروب escape تختفي النافذة، نقوم أولاً بتضمين إطار العمل Alpine.js عبر شبكة CDN بالشكل التالي:
<script src="https://unpkg.com/alpinejs" defer></script>
وكما تعلمنا سابقاً نستعمل أولاً الموجه x-data
لنستطيع استعمال كافة ما تتيحه Alpine داخل المكون، بما أننا نريد التحكم في إظهار أو إخفاء النافذة، سنعرف خاصية بالاسم open
، بحيث إذا كانت true
فذلك يعني أن النافذة مفتوحة وإذا كانت false
فإن النافذة مُغلقة، ونتحكم في ذلك عبر المُوجه x-show
ونمرر له اسم الخاصية open
:
<div class="modal-wrapper" x-data="{ open: true }" x-show="open" > <div class="modal"> محتوى النافذة المنبثقة </div> </div>
سترى أن النافذة مفتوحة افتراضيًا عند فتح الصفحة، يُمكنك تجربة تغيير القيمة الابتدائية من true
إلى false
وسترى أنها تستجيب لذلك.
بما أننا نرغب عند النقر خارج الحاوية البيضاء بإخفاء النافذة فإننا سنستخدم المُوجه x-on
للاستماع الى حدث النقر، لكني افضل استخدام الطريقة المختصرة @ ثم اسم الحدث أي click@
يُمكنك استخدام أي طريقة تريد سواء المختصرة click@
أو x-on:click
ونحدد المُعدل outside
للدلالة على أن الإستماع سيكون عند النقر خارج العُنصر المحدد:
<div class="modal-wrapper" x-data="{ open: true }" x-show="open" > <div class="modal" @click.outside="open = false"> محتوى النافذة المنبثقة </div> </div>
الآن عند فتح الصفحة ستظهر النافذة وعند النقر خارج الحاوية البيضاء ستختفي النافذة المنبثقة، وهذا لأننا حددنا أنه عندما يتم النقر قم بتغيير قيمة open
إلى false
وبالتالي يتم تحديث شجرة DOM وتختفي النافذة المنبثقة.
بخصوص الضغط على زر الهروب escape لإخفاء النافذة المنبثقة سنستخدم حدث keyup
للإستماع إلى حدث الضغط على الزر المطلوب ثم نمرر المعدل window
لتحديد أن الإستماع سيحدث على مستوى الصفحة بشكل كامل:
<div class="modal-wrapper" x-data="{ open: true }" x-show="open" @keyup.escape.window="open = false" > <div class="modal" @click.outside="open = false"> محتوى النافذة المنبثقة </div> </div>
لحد الآن لا توجد طريقة لإظهار النافذة المنبثقة سوى بتحديث الصفحة، سنتيح ذلك الآن، نقوم بتغيير قيمة open
الافتراضية إلى false
:
x-data="{ open: false }"
ثم نضيف خارج المكون زر لفتح النافذة المنبثقة:
<button>فتح النافذة المنبثقة</button>
بما أن الزر موجود خارج المكون فهو لا يعلم أي شيء عن بيانات ذلك المكون ولا يستطيع الوصول لها وبالتالي لا يستطيع التحكم فيها، سنُعرف بداخله الخاصية x-data
حتى نتمكن من استعمال Alpine بداخله، ثم نستخدم الخاصية dispatch$
التي تُتيحها Alpine لإطلاق حدث خاص:
<button x-data @click="$dispatch('open-modal')">فتح النافذة المنبثقة</button>
يمكن تسمية الحدث بأي اسم لقد أسميته open-modal
، ثم في المكون الأساسي يمكن الاستماع إلى الحدث الخاص الذي تم إطلاقه بنفس الطريقة التي نستخدمها في الإستماع إلى الأحداث العادية:
@open-modal.window="open = true"
بحيث تُصبح هيكلية HTML بالشكل التالي:
<div class="modal-wrapper" x-data="{ open: false }" x-show="open" @keyup.esc.window="open = false" @open-modal.window="open = true" > <div class="modal" @click.outside="open = false"> محتوى النافذة المنبثقة </div> </div> <button x-data @click="$dispatch('open-modal')">فتح النافذة المنبثقة</button>
بهذا الشكل نكون قد أنشأنا مثال بسيط عن مكون نافذة منبثقة، وتحكمنا في إظهاره وإخفائه.
إنشاء مفسر لصيغة ماركداون Markdown Parser
إن لم تكن لديك معرفة مسبقة بصيغة ماركداون فأدعوك للإطلاع على المقالتين: ماركداون للمبرمجين و كيف تكتب بصيغة ماركداون ببساطة، لن نقوم بإنشاء مفسر من الصفر وإنما سنستخدم مكتبة marked وسيكون مثالنا في إنشاء حقل إدخال نكتب من خلاله بصيغة ماركداون ثم نضغط على زر ليقوم بتفسير تلك الصيغة ويعرض لنا ما يوافقها:
نبدأ بإنشاء هيكلية HTML:
<!DOCTYPE html> <html lang="ar" dir="rtl"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>مفسر صيغة ماركداون</title> <script src="https://unpkg.com/alpinejs" defer></script> <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> </head> <body> <div x-data="{ body: '', markdown: '' }"> <div> <div> <textarea cols="50" rows="10"></textarea> </div> <button>عرض</button> </div> <div> المحتوى </div> </div> </body> </html>
المحتوى بسيط فقط قمنا بتضمين إطار Alpine.js ثم حزمة marked التي ستساعدنا في عملية التفسير، عرفنا مكون يحتوي على خاصيتين body هو المحتوى الذي سيتم كتابته عبر حقل الإدخال، و markdown هو نتيجة التفسير والذي سيكون عبارة عن html.
نقوم بربط الخاصية body مع حقل الإدخال باستخدام المُوجه x-model
بحيث عند الكتابة في حقل الإدخال تتغير القيمة:
<textarea cols="50" rows="10" x-model="body"></textarea>
نستمع الى حدث النقر ونقوم بتفسير القيمة المدخلة في حقل الإدخال ونسندها إلى الخاصية markdown
:
<button @click="markdown = marked.parse(body)">عرض</button>
نقوم بعرض المحتوى باستخدام المُوجه x-html
:
<div x-html="markdown"></div>
الآن إذا أدخلت محتوى بصيغة ماركداون في حقل الإدخال وضغطت على عرض سيتم عرضه بشكل مُفسر
جرب إدخال التالي في حقل الإدخال:
# عنوان أول ## عنوان ثاني ### عنوان ثالث #### عنوان رابع **نص ثخين** *نص مائل* ~~نص مشطوب~~ > هذا مثال على اقتباس مثال عن رابط: [أكاديمية حسوب](https://academy.hsoub.com/) قائمة عناصر: * عنصر * عنصر آخر * عنصر آخر قائمة مرتبة: 1. عنصر أول 2. عنصر ثانٍ 3. عنصر ثالث.
بعد الضغط على زر عرض ستحصل على النتيجة التالية:
يُمكن في الكائن x-data
إنشاء توابع وغير ذلك مما يمكن استعماله في كائنات جافاسكربت، سنقوم بإنشاء تابع يقوم بعملية التفسير ونستدعيه عند الاستماع إلى حدث الضغط حيث يصبح المكون بالشكل التالي:
<div x-data="{ body: '', markdown: '', parseMarkdown() { this.markdown = marked.parse(this.body) } }"> <div> <div> <textarea cols="50" rows="10" x-model="body"></textarea> </div> <button @click="parseMarkdown">عرض</button> </div> <div x-html="markdown"></div> </div>
إنشاء شريط تقدم دائري متحرك circular progress bar
سنقوم أولا بإنشاء هيكلية عناصر HTML واستخدام CSS لتنسيق شريط التقدم:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Animated circular progress bar</title> <script src="https://unpkg.com/alpinejs" defer></script> <style> body { margin: 0; } .box { position: absolute; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; width: 100%; } .progress { position: relative; height: 250px; width: 250px; border-radius: 50%; background: conic-gradient(slategray 306deg, #ddd 0deg); display: flex; align-items: center; justify-content: center; } .progress::before{ content: ""; position: absolute; height: 210px; width: 210px; border-radius: 50%; background-color: #fff; } .progress-inner{ position: relative; font-size: 40px; font-weight: 600; color: slategray; } .text{ font-size: 30px; font-weight: 500; color: #606060; margin-top: 10px; } </style> </head> <body> <div class="box"> <div class="progress"> <div class="progress-inner">85%</div> </div> <span class="text">Alpine Js</span> </div> </body> </html>
سيكون المظهر بالشكل التالي:
يُمكنك استخدام أي تنسيقات ترغب بها، ما يهم أننا سنستهدف الخاصية:
background: conic-gradient(slategray 306deg, #ddd 0deg);
القيمة 306deg بالضبط، حيث أننا سنحصل عليها من ضرب نسبة التقدم في 3.6، أي لما تكون النسبة 100% فإن القيمة تكون 360 درجة فهي عبارة عن قيس زاوية. وعندما تكون نسبة التقدم 50% تكون قيمة الزاوية 180 درجة وهي حاصل ضرب 50 في 3.6 لأننا سنبدأ التحريك من 0 إلى غاية القيمة النهائية.
لذلك سنجعل القيمة الابتدائية 0 بالشكل التالي:
background: conic-gradient(slategray 0deg, #ddd 0deg);
ثم نأتي لنبني المكون عبر Alpine.js ونبدأ بتعريف x-data
في العُنصر progress، بحيث نحدد الخصائص التالية: currentValue وسنعتمد عليها في زيادة قيمة التقدم وتكون مُهيأة بالقيمة 0، endValue وهي القيمة الأعظمية للتقدم، speed خاصية زمنية سنعتمد عليها في تسريع التحريك.
<div class="box"> <div class="progress" x-data="{ currentValue: 0, endValue: 85, speed: 20, // ms }" > <div class="progress-inner" x-text="currentValue + '%'"></div> </div> <span class="text">Alpine Js</span> </div>
ستلاحظ أننا حددنا x-text
للعنصر progress-inner حتى تكون القيمة ديناميكية وتتحدث كلما تغيرت قيمة currentValue.
الآن سنقوم بتعريف تابع بالاسم init داخل x-data
هذا التابع سيتم تنفيذه مباشرةً بعد تهيئة المكون يمكنك تجربة التالي:
<div class="progress" x-data="{ currentValue: 0, endValue: 85, speed: 20, // ms init() { console.log('Initialized') } }" >
ستجد أنه يتم طباعة العبارة Initialized في الطرفية console عند تحديث الصفحة، نحن لم نستدعي التابع، هذا لأن Alpine.js تقوم بذلك تلقائيًا، يُمكن أيضًا استخدام الموجه x-init
لنفس الغرض.
سنقوم بداخل التابع init
استخدام setInterval
لتنفيذ دالة بعد كل زمن معين (هنا سنستخدم speed
حيث أن الدالة سيتم تنفيذها بعد كل 20ms) بداخل الدالة سنقوم بزيادة قيمة currentValue بـ 1 ونتحقق إذا وصلنا للقيمة الأعظمية للتقدم حيث نقوم بإيقاف تنفيذ الدالة:
<div class="progress" x-data="{ currentValue: 0, endValue: 85, speed: 20, // ms init() { let progress = setInterval(() => { this.currentValue++ if (this.currentValue === this.endValue) { clearInterval(progress) } }, this.speed) } }" >
الآن إذا تصفحت ستجد أن القيمة تتغير من 0 إلى 85 كما هو مطلوب وعندما نصل إلى القيمة النهائية يتوقف التنفيذ. متبقي الآن ربط التنسيق الذي ذكرته في الأعلى بالقيمة الحالية، ولعمل هذا الشيء نحتاج إلى استخدام الموجه x-bind
فهو يتيح ربط تعبير برمجي بخاصية من الخصائص في html، والخاصية التي سنتعامل معها هي style، هناك كتابة مختصرة لـ x-bind
وهي رمز النقطتين :
مثلما هو الحال مع x-on
في الأحداث لذلك فبدل كتابة:
x-bind:style=""
يمكن كتابة:
:style=""
وبالتالي، لربط قيمة currentValue
بخاصية style
سنكتب:
:style="`background: conic-gradient(slategray ${currentValue * 3.6}deg, #ddd 0deg)`"
ليُصبح المكون بالشكل التالي:
<div class="box"> <div class="progress" x-data="{ currentValue: 0, endValue: 85, speed: 20, // ms init() { let progress = setInterval(() => { this.currentValue++ if (this.currentValue === this.endValue) { clearInterval(progress) } }, this.speed) } }" :style="`background: conic-gradient(slategray ${currentValue * 3.6}deg, #ddd 0deg)`" > <div class="progress-inner" x-text="currentValue + '%'"></div> </div> <span class="text">Alpine Js</span> </div>
بهذا الشكل سيُصبح كل من الشريط والنص المكتوب في الوسط يتحرك من القيمة 0 إلى القيمة النهائية 85، يمكنك تعديل القيمة النهائية 85 وقيمة السرعة speed
لمعاينة النتائج:
خاتمة
في ختام هذا المقال، نستنتج أن إطار العمل Alpine.js يعد أداة قوية وبسيطة في تطوير تجارب المستخدم الديناميكية على الويب. قدمت الأمثلة التي استعرضناها في هذا السياق نظرة عامة على قوة وسهولة استخدام Alpine.js في تحقيق العديد من الوظائف الديناميكية دون الحاجة إلى اللجوء إلى أطر عمل JavaScript الكبيرة والمعقدة.
تعتبر قدرة Alpine.js على توفير عمليات DOM الديناميكية والربط الفعّال بين العناصر والبيانات من خلال السماح بالتفاعل المباشر والتحكم السهل، مميزة بشكل خاص. التعابير البرمجية القصيرة والبنية البسيطة تجعل من السهل إدماجه في مشاريع الويب المختلفة دون تعقيدات زائدة.
من خلال الأمثلة البسيطة التي قمنا بإنشائها، يمكن للمطورين الآن البدء بفهم كيفية استخدام Alpine.js في مشاريعهم الشخصية أو العملية. عليهم استكشاف الميزات الإضافية واستخدام الإمكانيات الكاملة لهذا الإطار لتحسين تفاعل المستخدم وتبسيط التجارب على الويب.
اقرأ أيضًا
- دليل تعلم لغة جافاسكربت
- متى نستعمل إطار عمل للتطوير باستخدام JavaScript
- تعلم لغة جافا سكريبت من الصفر حتى الاحتراف
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.