كيفية إنشاء شريط تقدم سريع الاستجابة وديناميكي باستخدام 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 الخاص بي :)

أو إذا كنت ترغب فقط في شراء القهوة لي (أحب القهوة):