كيفية إنشاء شريط تقدم سريع الاستجابة وديناميكي باستخدام HTML و CSS و JavaScript
قبل عامين ، كتبت مقالًا قصيرًا حول بناء شريط تقدم سريع الاستجابة. لقد تطورت تقنياتي منذ ذلك الحين ، ولذا فإن التحديث مطلوب.
التغيير الأكبر هو أن العناصر الزائفة (قبل ، وبعد) لم تعد مطلوبة. الآن أصبح CSS أكثر وضوحًا ، وأصبح DOM أسهل في القراءة ، وهو أكثر ديناميكية.
لذلك دعونا نجرب هذا مرة أخرى.
هدفنا هو بناء شريط تقدم سريع الاستجابة بسيط وفعال يقوم بما يلي:
- أربع خطوات لإكمالها.
- كل خطوة لديها
default
،active
وcomplete
الدولة. - يمكن أن يتقدم من خطوة إلى أخرى حتى الانتهاء.
تحقق من CodePen هنا للحصول على مثال حي.
HTML
لتقليل التكرار وزيادة قابلية إعادة الاستخدام ، نتتبع جميع الحالات في مكون Vue. في DOM ، يولد هذا بشكل ديناميكي أي عدد من الخطوات المطلوبة.
ملاحظة : يمكن لـ JavaScript الأصلي (ECMAScript) أو أي إطار عمل آخر تحقيق ذلك. استخدام Vue لأغراض توضيحية.
يستخدم شريط التقدم الترميز الأساسي. هناك:
- حاوية بها فئات محسوبة بناءً على الخطوة الحالية:
progressClasses
- مسار خلفية ثابت:
progress__bg
- حلقة تتكرر خلال كل خطوة وتطبق
stepClasses
بناءً على الخطوة الحالية.
كل خطوة لها:
- a
progress__indicator
الذي يحتوي على رمز تحقق يكون مرئيًا في حالة اكتمال الخطوة. - و
progress__label
الذي يحتوي على نص التسمية لهذه الخطوة.
{{step.label}} Back Next Step: {{currentStep ? currentStep.label : "Start"}}
من أجل التبسيط ، يتم دمج العناصر progress__actions
التي تتحكم في اتجاه الحركة داخل شريط التقدم نفسه.
CSS (SCSS)
هذا هو المكان الذي نقوم فيه برفع الأحمال الثقيلة. سيتم تطبيق الفئات المحددة هنا ديناميكيًا بواسطة JS بناءً على الخطوة الحالية.
أولاً ، دعنا نختار بعض الألوان للعمل بها:
$gray: #E5E5E5; $gray2: #808080; $blue: #2183DD; $green: #009900; $white: #FFFFFF;
حدد الآن .progress
الفئة: الحاوية التي تجمع محتويات شريط التقدم معًا.
.progress { position: absolute; top: 15vh; width: 0%; height: 10px; background-color: $blue; transition: width .2s; }
يحتاج شريط التقدم لدينا إلى .progress__bg
أن خطوات التقدم سوف تعمل مثل المسار. سيكون هذا باللون الرمادي ، مغطى بالشريط الملون أثناء انتقاله إلى الخطوة التالية.
.progress__bg { position: absolute; width: 100vw; height: 10px; background-color: $gray; z-index: -1; }
.progress__step
يحتوي كل منها على الخطوة المستديرة التي ستبرز وتملأ مع تقدم شريط التقدم.
.progress__step { position: absolute; top: -8px; left: 0; display: flex; flex-direction: column; align-items: center; text-align: center; @for $i from 1 through 5 { &.progress__step--#{$i} { left: calc(#{$i * 20}vw - 9px); } } }
يحتوي أيضًا على نص الجولة .progress__indicator
والتسمية .progress__label
. يتم تحديد أنماطها الافتراضية خارج نطاق .progress__step
.
.progress__indicator { width: 25px; height: 25px; border: 2px solid $gray2; border-radius: 50%; background-color: $white; margin-bottom: 10px; .fa { display: none; font-size: 16px; color: $white; } } .progress__label { position: absolute; top: 40px; }
دعنا الآن نستمر في التداخل .progress__step
مرة أخرى وتحديد الخطوة في حالتها النشطة .
&.progress__step--active { color: $blue; font-weight: 600; }
بعد ذلك ، حدد الخطوة في حالتها الكاملة . ملاحظة : الأنماط الافتراضية ل .progress__indicator
و .progress__label
يتم الكتابة عندما تكون في دولة كاملة.
&.progress__step--complete { .progress__indicator { background-color: $green; border-color: $blue; color: $white; display: flex; align-items: center; justify-content: center; } .progress__indicator .fa { display: block; } .progress__label { font-weight: 600; color: $green; } }
جافا سكريبت
كما ذكرنا سابقًا ، سيختلف هذا بناءً على كيفية تنفيذك لمنطق الخطوة ، والسياق الأكبر الذي تم تنفيذه فيه ، والأطر والأنماط التي تستخدمها ، وما إلى ذلك.
يستخدم هذا المثال مكون Vue لشرح:
- حساب الفئات لشريط التقدم بناءً على الحالة الحالية.
- حساب الفئات لكل خطوة على أساس الوضع الحالي.
var app = new Vue({ el: '#app', data: { currentStep: null, steps: [ {"label": "one"}, {"label": "two"}, {"label": "three"}, {"label": "complete"} ] }, methods: { nextStep(next=true) { const steps = this.steps const currentStep = this.currentStep const currentIndex = steps.indexOf(currentStep) // handle back if (!next) { if (currentStep && currentStep.label === 'complete') { return this.currentStep = steps[steps.length - 1] } if (steps[currentIndex - 1]) { return this.currentStep = steps[currentIndex - 1] } return this.currentStep = { "label": "start" } } // handle next if (this.currentStep && this.currentStep.label === 'complete') { return this.currentStep = { "label": "start" } } if (steps[currentIndex + 1]) { return this.currentStep = steps[currentIndex + 1] } this.currentStep = { "label": "complete" } }, stepClasses(index) { let result = `progress__step progress__step--${index + 1} ` if (this.currentStep && this.currentStep.label === 'complete' || index < this.steps.indexOf(this.currentStep)) { return result += 'progress__step--complete' } if (index === this.steps.indexOf(this.currentStep)) { return result += 'progress__step--active' } return result } }, computed: { progressClasses() { let result = 'progress ' if (this.currentStep && this.currentStep.label === 'complete') { return result += 'progress--complete' } return result += `progress--${this.steps.indexOf(this.currentStep) + 1}` } } })
استنتاج
في نهاية كل شيء لديك هذا:

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