Skip to content

JavaScript Tabbed Component

المعرفة:: JavaScript
الحالة:: ملاحظة_مؤرشفة
المراجع:: The Complete JavaScript Course 2022 From Zero to Expert


  • Use Event Delegation while attaching an event listener instead of a attaching it to every button element.
  • Use guard clause to handle clicks on empty spaces between child elements.
  • Control visibility by adding/removing classes.
  • Remove active classes before adding to the clicked element.

HTML

  <div class="operations">  
    <div class="operations__tab-container">  
      <button  
        class="btn operations__tab operations__tab--1 operations__tab--active"  
        data-tab="1">  
        <span>01</span>Section  
      </button>  
      <button class="btn operations__tab operations__tab--2" data-tab="2">  
        <span>02</span>Section  
      </button>  
      <button class="btn operations__tab operations__tab--3" data-tab="3">  
        <span>03</span>Section  
      </button>  
    </div>  
    <div  
      class="operations__content operations__content--1 operations__content--active"  
>  
      <div class="operations__icon operations__icon--1">  
        <svg>  
          <use xlink:href="img/icons.svg#icon-upload"><_use>  
        </svg>  
      </div>  
      <h5 class="operations__header">  
        Header.  
      </h5>  
      <p>  
        Content.  
      </p>  
    </div>  

    <div class="operations__content operations__content--2">  
      <div class="operations__icon operations__icon--2">  
        <svg>  
          <use xlink:href="img/icons.svg#icon-home"><_use>  
        </svg>  
      </div>  
      <h5 class="operations__header">  
        Header.  
      </h5>  
      <p>  
        Content.  
      </p>  
    </div>  
    <div class="operations__content operations__content--3">  
      <div class="operations__icon operations__icon--3">  
        <svg>  
          <use xlink:href="img/icons.svg#icon-user-x"><_use>  
        </svg>  
      </div>  
      <h5 class="operations__header">  
        Header.  
      </h5>  
      <p>  
        Content.  
      </p>  
    </div>  
  </div>  

CSS

/* OPERATIONS */  
.operations {  
  max-width: 100rem;  
  margin: 12rem auto 0 auto;  
  background-color: **fff**{: #fff .hash};  
}  

.operations__tab-container {  
  display: flex;  
  justify-content: center;  
}  

.operations__tab {  
  margin-right: 2.5rem;  
  transform: translateY(-50%);  
}  

.operations__tab span {  
  margin-right: 1rem;  
  font-weight: 600;  
  display: inline-block;  
}  

.operations__tab--1 {  
  background-color: var(--color-secondary);  
}  

.operations__tab--1:hover {  
  background-color: var(--color-secondary-darker);  
}  

.operations__tab--3 {  
  background-color: var(--color-tertiary);  
  margin: 0;  
}  

.operations__tab--3:hover {  
  background-color: var(--color-tertiary-darker);  
}  

.operations__tab--active {  
  transform: translateY(-66%);  
}  

.operations__content {  
  display: none;  
  /* JUST PRESENTATIONAL */  
  font-size: 1.7rem;  
  padding: 2.5rem 7rem 6.5rem 7rem;  
}  

.operations__content--active {  
  display: grid;  
  grid-template-columns: 7rem 1fr;  
  column-gap: 3rem;  
  row-gap: 0.5rem;  
}  

.operations__header {  
  font-size: 2.25rem;  
  font-weight: 500;  
  align-self: center;  
}  

.operations__icon {  
  display: flex;  
  align-items: center;  
  justify-content: center;  
  height: 7rem;  
  width: 7rem;  
  border-radius: 50%;  
}  

.operations__icon svg {  
  height: 2.75rem;  
  width: 2.75rem;  
}  

.operations__content p {  
  grid-column: 2;  
}  

.operations__icon--1 {  
  background-color: var(--color-secondary-opacity);  
}  
.operations__icon--2 {  
  background-color: var(--color-primary-opacity);  
}  
.operations__icon--3 {  
  background-color: var(--color-tertiary-opacity);  
}  
.operations__icon--1 svg {  
  fill: var(--color-secondary-darker);  
}  
.operations__icon--2 svg {  
  fill: var(--color-primary);  
}  
.operations__icon--3 svg {  
  fill: var(--color-tertiary);  
}  

JavaScript

tabsContainer.addEventListener('click', function (e) {  
  const clicked = e.target.closest('.operations__tab');  

  // Guard clause  
  if (!clicked) return;  

  // Remove active classes  
  tabs.forEach(t => t.classList.remove('operations__tab--active'));  
  tabsContent.forEach(c => c.classList.remove('operations__content--active'));  

  // Activate tab  
  clicked.classList.add('operations__tab--active');  

  // Activate content area  
  document  
    .querySelector(`.operations__content--${clicked.dataset.tab}`)  
    .classList.add('operations__content--active');  
});  

Last update : August 14, 2023
Created : August 23, 2022

Comments

Comments