آخر الأخبار

استكشف في مدونة أوعي وشك عالم الابتكار

اكتشف الحلول المتطورة في تطبيقات الأجهزة المحمولة والتكنولوجيا والتعليم وموضوعات بلوجر. كن على اطلاع دائم بمقالات الخبراء والموارد الإبداعية والأدوات القوية لتعزيز مشاريعك الرقمية.

تبسيط تجربة المستخدم تبويبات ذكية مع Stepper UI

إذا لم تكن على دراية بمكونات المتدرج (stepper)، فإن هدفها الرئيسي هو تحسين تجربة المستخدم من خلال تنظيم كتل المحتوى المنطقية الكبيرة إلى ......

في هذا البرنامج التعليمي، سنقوم ببناء مكون تبويب بسيط باستخدام JavaScript حيث ستظهر علامات التبويب القابلة للنقر كمكون متدرج (stepper).

في السابق، عرضت لك كيفية إنشاء واجهات تبويب مختلفة. اليوم، سنقوم ببناء مكون تبويب آخر باستخدام JavaScript حيث ستظهر علامات التبويب كمكون متدرج.

إذا لم تكن على دراية بمكونات المتدرج (stepper)، فإن هدفها الرئيسي هو تحسين تجربة المستخدم من خلال تنظيم كتل المحتوى المنطقية الكبيرة إلى خطوات متسلسلة أصغر. أحد حالات الاستخدام الشائعة لهذا المكون هو إنشاء عملية دفع متعددة الخطوات في مواقع التجارة الإلكترونية.

مكون التبويب الخاص بنا

إليك ما سنقوم بإنشائه — قم بتغيير حجم المتصفح لترى كيف يتغير تخطيط التبويب:

لن نركز كثيرًا على إمكانية الوصول في هذا البرنامج التعليمي، لذا فإن استكشاف كيفية جعل هذا المكون أكثر سهولة في الوصول سيكون خطوة تالية صحيحة.

ابدأ بعلامات الصفحة

داخل حاوية، سنضع قائمتين تحتويان على علامات التبويب والمحتوى المرتبط بها (الألواح).

بشكل افتراضي، سيتم تفعيل علامة التبويب الأولى.

إليك العلامات المطلوبة:


<div class="grid">
  <ul class="tab-list">
    <li class="active">
      <a href="">
        <span class="dot"></span>
        <span>Bald Eagle</span>
      </a>
    </li>
    <li>
      <a href="">
        <span class="dot"></span>
        <span>Golden Eagle</span>
      </a>
    </li>
    <li>
      <a href="">
        <span class="dot"></span>
        <span>Common Tern</span>
      </a>
    </li>
    <li>
      <a href="">
        <span class="dot"></span>
        <span>Great Blue Heron</span>
      </a>
    </li>
    <li>
      <a href="">
        <span class="dot"></span>
        <span>Hawk</span>
      </a>
    </li>
  </ul>
  <ul class="tab-panels">
    <li class="active">
      <h2>Bald Eagle</h2>
      <p>The bald eagle (Haliaeetus leucocephalus) is a bird of prey found in North America. A sea eagle, it has two known subspecies and forms a species pair with the white-tailed eagle (Haliaeetus albicilla), which occupies the same niche as the bald eagle in the Palearctic. Its range includes most of Canada and Alaska, all of the contiguous United States, and northern Mexico. It is found near large bodies of open water with an abundant food supply and old-growth trees for nesting.</p>
      <p>
        <a href="https://en.wikipedia.org/wiki/Bald_eagle" target="_blank">Read More</a>
      </p>
    </li>
    <li>
      <h2>Golden Eagle</h2>
      <p>The golden eagle (Aquila chrysaetos) is a bird of prey living in the Northern Hemisphere. It is the most widely distributed species of eagle. Like all eagles, it belongs to the family Accipitridae. They are one of the best-known birds of prey in the Northern Hemisphere. These birds are dark brown, with lighter golden-brown plumage on their napes. Immature eagles of this species typically have white on the tail and often have white markings on the wings. Golden eagles use their agility and speed combined with powerful feet and large, sharp talons to hunt a variety of prey, mainly hares, rabbits, and marmots and other ground squirrels.</p>
      <p>
        <a href="https://en.wikipedia.org/wiki/Golden_eagle" target="_blank">Read More</a>
      </p>
    </li>
    <li>
      <h2>Common Tern</h2>
      <p>The common tern (Sterna hirundo) is a seabird in the family Laridae. This bird has a circumpolar distribution, its four subspecies breeding in temperate and subarctic regions of Europe, Asia and North America. It is strongly migratory, wintering in coastal tropical and subtropical regions. Breeding adults have light grey upperparts, white to very light grey underparts, a black cap, orange-red legs, and a narrow pointed bill. Depending on the subspecies, the bill may be mostly red with a black tip or all black. There are several similar species, including the partly sympatric Arctic tern, which can be separated on plumage details, leg and bill colour, or vocalisations.</p>
      <p>
        <a href="https://en.wikipedia.org/wiki/Common_tern" target="_blank">Read More</a>
      </p>
    </li>
    <li>
      <h2>Great Blue Heron</h2>
      <p>The great blue heron (Ardea herodias) is a large wading bird in the heron family Ardeidae, common near the shores of open water and in wetlands over most of North and Central America, as well as far northwestern South America, the Caribbean and the Galápagos Islands. It is occasionally found in the Azores and is a rare vagrant to Europe. An all-white population found in south Florida and the Florida Keys is known as the great white heron. Debate exists about whether these white birds are a color morph of the great blue heron, a subspecies of it, or an entirely separate species.</p>
      <p>
        <a href="https://en.wikipedia.org/wiki/Great_blue_heron" target="_blank">Read More</a>
      </p>
    </li>
    <li>
      <h2>Hawk</h2>
      <p>Hawks are birds of prey of the family Accipitridae. They are very widely distributed and are found on all continents except Antarctica.</p>
      <ul>
        <li>
          The subfamily Accipitrinae includes goshawks, sparrowhawks, sharp-shinned hawks, and others. This subfamily are mainly woodland birds with short broad wings, long tails, and high visual acuity. They hunt by dashing suddenly from a concealed perch.
        </li>
        <li>
          In America, members of the Buteo group are also called hawks; this group is called buzzards in other parts of the world. Generally, buteos have broad wings and sturdy builds. They are relatively larger-winged and shorter-tailed than accipiters, and fly further distances in open areas. Buteos descend or pounce on their prey rather than hunting in a fast horizontal pursuit.
        </li>
      </ul>
      <p>
        <a href="https://en.wikipedia.org/wiki/Great_blue_heron" target="_blank">Read More</a>
      </p>
    </li>
  </ul>
</div>

<footer class="page-footer">
  <span>صنع بواسطة </span>
  <a href="https://georgemartsoukos.com/" target="_blank">
    <img width="24" height="24" src="https://blogger.googleusercontent.com/img/a/AVvXsEh8omGGY9jA5vvoO8Z0qEeRGHvSWLTwtza8n3HrOLnhsPkWPgt0lY3xJaMAzZ8u2_wWsmHiruGXriQz7AHh8hD2kAiXOGvILBON6HCT7fYPs4otW3wlDsgo43qDgJYe23bIX3irX-SkqDrqcfsahO9tY_qS1aQyKzhMguOdOjpKRxsGHIktwI_nEz1uwC43=w150-h150-p-k-no-nu-rw-e90" alt="George Martsoukos logo">
  </a>
</footer>
    
أضف CSS

لنركز على الأنماط الرئيسية — يمكنك رؤية جميع الأنماط من خلال النقر على علامة CSS في مشروع العرض التوضيحي.

على الشاشات الكبيرة (>700px)، سيبدو مكون التبويب كما يلي:

إنشاء مكون تبويب باستخدام JavaScript

على الشاشات الصغيرة، سيبدو كما يلي:

إنشاء مكون تبويب باستخدام JavaScript

لاحظ كيف يتحول المتدرج بين الاتجاه الأفقي والرأسي اعتمادًا على حجم الشاشة.

أيضًا، ضع في اعتبارك أن جميع ألواح التبويب سيتم تكديسها وتحريكها 100% إلى اليسار؛ في أي وقت، سيظهر فقط اللوحة التي تحتوي على الفئة active وتجلس في موقعها الأولي.

إليك جزء من الأنماط المطلوبة:


/* RESET STYLES
–––––––––––––––––––––––––––––––––––––––––––––––––– */
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap");

:root {
  --stepper-outline-color: #386641;
  --stepper-active-color: #4f772d;
  --stepper-connector-color: #90a955;
}

* {
  box-sizing: border-box;
}

a {
  color: inherit;
}

body {
  font-family: "Poppins", sans-serif;
  margin: 50px 0;
}

/* MAIN STYLES
–––––––––––––––––––––––––––––––––––––––––––––––––– */
.grid {
  display: grid;
  grid-template-columns: auto auto;
  gap: 70px;
  max-width: 1000px;
  padding: 0 20px;
  margin: 0 auto;
}

.grid > ul {
  list-style: none;
  padding: 0;
  margin: 0;
}

.tab-list {
  padding: 0 10px;
  margin: 0 auto;
}

.tab-list li {
  display: flex;
}

.tab-list li:not(:last-child) {
  margin-bottom: 40px;
}

.tab-list a {
  display: inline-flex;
  align-items: center;
  gap: 24px;
  text-decoration: none;
}

.tab-list a .dot {
  position: relative;
  display: inline-block;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 1px solid var(--stepper-outline-color);
}

.tab-list li a .dot::before,
.tab-list li:not(:last-child) a .dot::after {
  content: "";
  position: absolute;
  left: 50%;
}

.tab-list li a .dot::before {
  top: 50%;
  transform: translate(-50%, -50%) scale(0);
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--stepper-active-color);
  transition: transform 0.3s;
}

.tab-list li:not(:last-child) a .dot::after {
  top: calc(100% + 1px);
  transform: translateX(-50%);
  height: 40px;
  border-left: 2px dashed var(--stepper-connector-color);
}

.tab-list li.active a {
  font-weight: bold;
}

.tab-list li.active a .dot::before {
  transform: translate(-50%, -50%) scale(1);
}

.tab-panels {
  display: grid;
  overflow: hidden;
}

.tab-panels > li {
  grid-area: 1/1;
  opacity: 0;
  transform: translateX(-100%);
  transition: opacity 0.35s ease-in-out, transform 0.7s ease-in-out;
}

.tab-panels > li.active {
  opacity: 1;
  transform: none;
}

.tab-panels h2 {
  padding-bottom: 5px;
  border-bottom: 1px solid #ededed;
  margin: 0 0 20px;
}

@media (max-width: 700px) {
  .grid {
    grid-template-columns: 1fr;
    gap: 30px;
  }

  .tab-list {
    display: flex;
    justify-content: center;
  }

  .tab-list li:not(:last-child) {
    margin: 0 40px 0 0;
  }

  .tab-list li a span:last-child {
    display: none;
  }

  .tab-list a {
    gap: 0;
  }

  .tab-list li:not(:last-child) a .dot::after {
    top: 50%;
    left: calc(100% + 1px);
    transform: translateY(-50%);
    width: 40px;
    height: auto;
    border-bottom: 2px dashed var(--stepper-connector-color);
    border-left: 0;
  }
}

/* FOOTER STYLES
–––––––––––––––––––––––––––––––––––––––––––––––––– */
.page-footer {
  position: fixed;
  right: 0;
  bottom: 50px;
  display: flex;
  align-items: center;
  padding: 5px;
  font-size: 0.9em;
  background: white;
}

.page-footer a {
  display: flex;
  margin-left: 4px;
}
    
أضف JavaScript

في كل مرة ننقر فيها على رابط تبويب، سنقوم بإزالة الفئة active من علامة التبويب واللوحة النشطة حاليًا. ثم سنضع هذه الفئة في علامة التبويب واللوحة المرتبطة بهذا الرابط.

إليك JavaScript المطلوب:


const tabList = document.querySelector(".tab-list");
const tabItems = tabList.querySelectorAll("li");
const tabLinks = tabList.querySelectorAll("a");
const tabPanelsList = document.querySelector(".tab-panels");
const tabPanels = tabPanelsList.querySelectorAll("li");
const ACTIVE_CLASS = "active";
for (const tabLink of tabLinks) {
  tabLink.addEventListener("click", function (e) {
    e.preventDefault();
    tabList.querySelector(`li.${ACTIVE_CLASS}`).classList.remove(ACTIVE_CLASS);
    tabPanelsList
      .querySelector(`li.${ACTIVE_CLASS}`)
      .classList.remove(ACTIVE_CLASS);
    const parent = tabLink.parentElement;
    let parentIndex = Array.from(tabItems).indexOf(parent);
    parent.classList.add(ACTIVE_CLASS);
    tabPanelsList
      .querySelector(`li:nth-child(${++parentIndex})`)
      .classList.add(ACTIVE_CLASS);
  });
}
    

إضافة دعم لوحة المفاتيح

على الرغم من أن مكوننا ليس مُحسّنًا لإمكانية الوصول، دعنا نضيف دعمًا للتنقل باستخدام لوحة المفاتيح.

على الشاشات الصغيرة، في كل مرة يتم الضغط على مفتاح السهم الأيسر (←) أو الأيمن (→)، سنقوم بالحصول على علامة التبويب النشطة حاليًا. من هناك، سنتحقق من السهم الذي تم النقر عليه. إذا كان السهمعلى الشاشات الصغيرة، في كل مرة يتم الضغط على مفتاح السهم الأيسر أو الأيمن ، سنقوم بالحصول على علامة التبويب النشطة حاليًا. من هناك، سنتحقق من السهم الذي تم النقر عليه. إذا كان السهم الأيمن، فسنقوم بتعيين علامة التبويب التالية على أنها التي تلي علامة التبويب النشطة حاليًا. إذا لم تكن هناك علامة تبويب تالية، تصبح علامة التبويب الأولى هي التالية. وبالمثل، إذا تم النقر على السهم الأيسر، فسنقوم بتعيين علامة التبويب التالية على أنها التي تسبق علامة التبويب النشطة حاليًا. إذا لم تكن هناك علامة تبويب سابقة، تصبح علامة التبويب الأخيرة هي التالية.

سنتبع نفس العملية مع مفاتيح السهم لأعلى (↑) ولأسفل (↓) على الشاشات الكبيرة.

إليك كود JavaScript ذو الصلة:


tabList.addEventListener("keyup", function (e) {
  const activeTabListItem = tabList.querySelector(`li.${ACTIVE_CLASS}`);
  if (
    e.key === "ArrowUp" ||
    e.key === "ArrowDown" ||
    e.key === "ArrowLeft" ||
    e.key === "ArrowRight"
  ) {
    if (
      (mqSm.matches && (e.key === "ArrowUp" || e.key === "ArrowDown")) ||
      (mqLg.matches && (e.key === "ArrowLeft" || e.key === "ArrowRight"))
    ) {
      return;
    }
    if (e.key === "ArrowUp" || e.key === "ArrowLeft") {
      const prevActiveTabListItem = activeTabListItem.previousElementSibling
        ? activeTabListItem.previousElementSibling
        : lastTabListItem;
      prevActiveTabListItem.querySelector("a").click();
    } else {
      const nextActiveTabListItem = activeTabListItem.nextElementSibling
        ? activeTabListItem.nextElementSibling
        : firstTabListItem;
      nextActiveTabListItem.querySelector("a").click();
    }
  }
});
    
الخلاصـــة

تهانينا! لقد قمنا ببناء هذا المكون الجميل والفريد للتبويب باستخدام JavaScript دون كتابة الكثير من الأكواد. من هناك، يمكنك استخدامه كما هو وجعله أكثر سهولة في الوصول من خلال التحقق من كود مكون مشابه مثل تبويبات Bootstrap.

بدلاً من ذلك، يمكنك عزل تخطيط قائمة التبويب الذي يبدو كمكون متدرج واستخدامه كما تريد عن طريق إضافة وظائف لأسهم التنقل، إلخ.

قبل الإغلاق، دعونا نتذكر ما أنشأناه اليوم:

كما هو الحال دائمًا، شكرًا جزيلاً على القراءة!

🌟 انتبه عزيزي أعضاء المجتمع! 🌟
نحن متحمسون لمشاركتك في مناقشاتنا الديناميكية. لضمان بيئة محترمة وشاملة للجميع، نطلب تعاونكم مع الإرشادات التالية:
1. احترام الخصوصية: يرجى عدم مشاركة معلومات حساسة أو شخصية في تعليقاتك.
2. انشر الإيجابية: نحن نتمسك بسياسة عدم التسامح مطلقًا مع خطاب الكراهية أو اللغة المسيئة. دعونا نحافظ على محادثاتنا محترمة وودية.
3. اللغة المفضلة: لا تتردد في التعبير عن نفسك باللغة الإنجليزية أو العربية. ستساعدنا هاتان اللغتان في الحفاظ على مناقشة واضحة ومتماسكة.
4. احترام التنوع: لتعزيز جو شامل، نطلب منك بكل احترام تجنب مناقشة المسائل الدينية في تعليقاتك.
تذكر أن مساهماتك قيمة، ونحن نقدر التزامك بجعل مجتمعنا مكانًا ترحيبيًا للجميع. دعونا نواصل التعلم والنمو معًا من خلال المناقشات البناءة والاحترام المتبادل.
شكرًا لكونك جزءًا من مجتمعنا اوعي وشك! 🌟

إرسال تعليق