در این آموزش، با استفاده از وانیلی جاوا اسکریپت، یک جزء کشویی سفارشی و قابل استفاده مجدد ایجاد می کنیم.

چی؟ یک استراتژی برای کاهش یک منو یا ردپای ناوبری، قرار دادن پیوندهای اضافی در داخل یک مؤلفه کشویی است. ایده این است که کاربران برای نمایش گزینه‌های بیشتر کلیک کنند، بنابراین راه‌های بیشتری برای پیمایش صفحات وب در اختیار آنها قرار می‌گیرد و در عین حال رابط کاربری را تمیز نگه می‌دارند.

برای این آموزش، فرض می‌کنم که در حال ساختن یک جزء برای وب‌سایت آژانس بازاریابی هستیم.

چگونه یک کامپوننت کشویی با جاوا اسکریپت بسازیم

خوب، بیایید در گیر کنیم! طبق معمول، ما با نشانه گذاری HTML برای ساختار خود شروع می کنیم، سپس چند سبک را با CSS اضافه می کنیم، و در نهایت رفتار را با جاوا اسکریپت وانیلی اضافه می کنیم.

ساختار HTML

اول، ساختار HTML. ما از یک لیست نامرتب با موارد و پیوندهای لیست استفاده خواهیم کرد.

1
<nav role="primary navigation">
2
  <a href="#">Home</a>
3
  <div class="dropdown">
4
    <a href="#" class="dropdown-action">
5
        Services
6
        <svg class="dropdown-icon" xmlns=" width="24" height="24" viewBox="0 0 24 24"><title>chevron-down</title><g fill="none"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M15.25 10.75L12 14.25l-3.25-3.5"></path></g></svg>
7
    </a>
8
    <ul class="dropdown-menu">
9
      <li><a href="#">SEO</a></li>
10
      <li><a href="#">Content Strategy</a></li>
11
      <li><a href="#">Copywriting</a></li>
12
      <li><a href="#">Storytelling</a></li>
13
    </ul>
14
  </div>
15
  <a href="#">About</a>
16
  <a href="#">Contact</a>
17
  <div class="dropdown">
18
    <a href="#" class="dropdown-action">
19
        Account
20
        <svg class="dropdown-icon" xmlns=" width="24" height="24" viewBox="0 0 24 24"><title>chevron-down</title><g fill="none"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M15.25 10.75L12 14.25l-3.25-3.5"></path></g></svg>
21
    </a>
22
    <ul class="dropdown-menu">
23
      <li><a href="#">Login</a></li>
24
      <li><a href="#">Sign up</a></li>
25
    </ul>
26
  </div>
27
</nav>

به نام کلاس ها در پیوند لنگر والد توجه کنید .dropdown-action و لیست نامرتب .dropdown-menu. این قراردادهای نامگذاری کلاس عمومی تر هستند، بنابراین ما می توانیم هر چند وقت یکبار که بخواهیم در وب سایت از CSS و جاوا اسکریپت استفاده کنیم.

اضافه کردن چند سبک با CSS

بیایید به لیست کشویی چند درمان زیبایی با CSS ارائه دهیم.

به یاد داشته باشید که پایه اصلی یک کشویی به درستی پنهان می شود و لیست را در صورت تقاضا نشان می دهد. من لیست کشویی را با در نظر گرفتن آن طراحی می کنم.

1
nav {
2
  width: 1020px;
3
  display: flex;
4
  align-items: center;
5
  margin: 20px auto;
6
  padding-bottom: 10px;
7
  border-bottom: 1px solid #ddd;
8
}
9
10
nav a {
11
  padding: 10px 16px;
12
  border-radius: 4px;
13
  display: inline-block;
14
  color: #334155;
15
  text-decoration: none;
16
}
17
18
nav a:hover {
19
  color: #0ea5e9;
20
  background-color: #f0f9ff;
21
}
22
23
.dropdown {
24
  position: relative;
25
}
26
27
.dropdown-action {
28
  display: flex;
29
  align-items: center;
30
  padding-right: 10px;
31
}
32
33
.dropdown-icon {
34
  stroke: currentColor;
35
}
36
37
.dropdown-menu {
38
  display: none;
39
  list-style: none;
40
  margin: 0;
41
  padding: 10px 0;
42
  border: 1px solid #cbd5e1;
43
  border-radius: 6px;
44
  box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
45
  position: absolute;
46
  top: 40px;
47
  left: 5px;
48
  min-width: 180px;
49
  background: white;
50
}
51
52
.dropdown-menu.active {
53
  display: block;
54
}
55
56
.dropdown-menu a {
57
  display: block;
58
}

افزودن تعامل با جاوا اسکریپت

برای اطمینان از اینکه می‌توانیم بارها و بارها از مؤلفه کشویی استفاده مجدد کنیم، جاوا اسکریپت را به گونه‌ای می‌نویسم که هر مؤلفه کشویی در یک صفحه مشخص را حساب کند. این بدان معناست که تنها کاری که ما باید انجام دهیم این است که اسکریپت را برای کار در بسیاری از مؤلفه‌های کشویی با فرض مطابقت HTML و CSS با کار قبلی ما وارد کنیم.

1
class Dropdown {
2
3
  constructor() {
4
    this.dropdowns = document.querySelectorAll('.dropdown .dropdown-menu')
5
    if (this. dropdowns.length) {
6
      this.initialize();
7
    }
8
  }
9
10
11
 initialize() {
12
    document.addEventListener('click', (e) => {
13
      if (e.target.classList.contains('dropdown-action')) {
14
        this.hideOtherDropdowns(e.target);
15
        this.handleClick(e.target);
16
      } else {
17
        this.hideOtherDropdowns(null);
18
      }
19
    });
20
  }
21
22
  handleClick(dropdownAction) {
23
    this. dropdowns.forEach(dropdown => {
24
      if (dropdown.parentElement.contains(dropdownAction)) {
25
        dropdown.classList.add('active');
26
      } else {
27
        dropdown.classList.remove('active');
28
      }
29
    })
30
  }
31
32
  hideOtherDropdowns(dropdownAction) {
33
34
    this.dropdowns.forEach((dropdown) => {
35
      if (!dropdown.parentElement.contains(dropdownAction)) {
36
        dropdown.classList.remove('active');
37
      }
38
    });
39
  }
40
41
}
42
43
document.addEventListener('DOMContentLoaded', () => new Dropdown);

با استفاده از سینتکس مدرن ES6، یک جدید ایجاد کردم Dropdown کلاس برای پیچیدن منطق برای استفاده مجدد در یک صفحه مشخص. ما آن را در همان لحظه با استفاده از خط زیر مقداردهی اولیه می کنیم.

1
document.addEventListener('DOMContentLoaded', () => new Dropdown);

تا زمانی که اسکریپت در یک صفحه مشخص گنجانده شده است، این کد تنها چیزی است که برای زنده کردن کامپوننت نیاز دارید. ما می توانیم منتظر بمانیم محتوای DOM بارگیری می شود قبل از مقداردهی اولیه Dropdown کلاس برای نتایج بهتر

توابع ما (در جزئیات بیشتر)

بیایید هر عملکرد را از هم جدا کنیم و عمیق‌تر به آنچه در حال وقوع است بپردازیم.

روش سازنده

1
constructor() {
2
  this.dropdowns = document.querySelectorAll('.dropdown .dropdown-menu')
3
  if (this. dropdowns.length) {
4
    this.initialize();
5
  }
6
}

این constructor متد برای مقداردهی اولیه شی یا کلاس استفاده می شود. سازنده به شما امکان می دهد تا قبل از فراخوانی روش های دیگر، هر مقدار اولیه سفارشی را ارائه دهید.

در اینجا من یک را اضافه کردم querySelectorAll روشی که برای همه منوهای کشویی در یک صفحه معین پرس و جو می کند. ما در توابع آینده از طریق آنها حلقه خواهیم کرد.

بعلاوه، من مقداری منطق شرطی اضافه کردم تا بررسی کنم قبل از فراخوانی، فهرست‌های کشویی در یک صفحه وجود دارند initialize() تابعی که بخشی از کلاس است.

تابع ()initialize

1
initialize() {
2
  document.addEventListener('click', (e) => {
3
    if (e.target.classList.contains('dropdown-action')) {
4
      this.hideOtherDropdowns(e.target);
5
      this.handleClick(e.target);
6
    } else {
7
      this.hideOtherDropdowns(null);
8
    }
9
  });
10
}

این initialize() تابع دیگر توابع داخل کلاس را فراخوانی می کند. در اینجا یک شنونده رویداد به کل سند HTML اضافه کردم. ما باید این کار را انجام دهیم تا زمانی که کاربر در خارج از یک منوی کشویی کلیک می کند، به عملکرد کاربر پاسخ دهیم. یک تجربه خوب، بسته شدن خودکار منو هنگام کلیک کردن در خارج از آن است، بنابراین این منطق به این دلیل است.

ما می‌توانیم با استفاده از رویدادی که برگردانده می‌شود، روی «کلیک» ضربه بزنیم و برای استفاده در آینده روی آن ضربه بزنید. ایده این است که از آیتمی که کاربر روی آن کلیک کرده است استفاده کنید تا راه را برای نمایش و پنهان کردن منوهای صحیح در صفحه هموار کنید. اگر چندین منو وجود دارد، می‌خواهیم منوهایی را که به طور فعال استفاده نمی‌شوند به‌طور خودکار ببندیم.

اگر پیوند منوی پیمایش شامل dropdown-action کلاس، دو تابع دیگر را فراخوانی می کنیم و همان مقدار هدف را به آن ها ارسال می کنیم. در غیر این صورت، همه کشویی های دیگر را با استفاده از hideOtherDropdowns() تابع.

تابع handleClick().

1
  handleClick(dropdownAction) {
2
    this. dropdowns.forEach(dropdown => {
3
      if (dropdown.parentElement.contains(dropdownAction)) {
4
        dropdown.classList.add('active');
5
      } else {
6
        dropdown.classList.remove('active');
7
      }
8
    })
9
  }

این handleClick() تابع را می پذیرد event.target ویژگی. ملک را از داخل رد می کنیم initialize() تابع. ما از قبل مقداردهی شده خود استفاده خواهیم کرد this.dropdowns آرایه ای برای حلقه زدن از طریق تمام کرکره های موجود. اگر یک کشویی شامل event.target (یا dropdownAction) کلاس را اضافه می کنیم .active به منوی کشویی بروید و آن را نشان دهید. اگر اینطور نیست کلاس را حذف می کنیم .active.

پارامتر dropdownAction

1
hideOtherDropdowns(dropdownAction) {
2
  this. dropdowns.forEach((dropdown) => {
3
    if (!dropdown.parentElement.contains(dropdownAction)) {
4
      dropdown.classList.remove('active');
5
    }
6
  });
7
}

باز کردن کرکره های کمتر به یکباره تجربه بهتری را در دراز مدت ایجاد می کند. ما باید هر کدام را که به طور فعال در حال استفاده نیستند ببندیم. ما می توانیم بفهمیم که کدام یک نسبت به استفاده می شود event.target در حال عبور از initialize() تابع. در اینجا از پارامتری به نام استفاده می کنیم dropdownAction برای زیرمجموعه کردن event.target ویژگی.

یک بار دیگر همه فهرست‌های کشویی را مرور می‌کنیم. در داخل forEach حلقه، می‌توانیم یک دستور شرطی انجام دهیم که بررسی می‌کند آیا فهرست کشویی حاوی عبارت است یا خیر dropdownAction یا نه. ما استفاده خواهیم کرد ! نشان می دهد که ما معکوس منطق را بررسی می کنیم. بنابراین به زبان ساده، من بررسی می‌کنم که آیا فهرست کرکره‌ای حاوی پیوندی برای باز کردن آن نیست. اگر نه، کلاس فعال آن را حذف می کنیم و آن را پنهان می کنیم.

نتیجه

با هر شانسی، اکنون می توانید هر دو منوی کشویی را که در HTML اضافه کرده ایم باز و بسته کنید، و آنها باید هر طور که دوست داریم پاسخ دهند. وقتی یکی باز می شود، دیگری بسته می شود. همچنین توجه داشته باشید که وقتی خارج از یک کشویی کلیک می کنید، منوی کشویی اصلی نیز بسته می شود.

امیدوارم از دنبال کردن این آموزش جاوا اسکریپت لذت برده باشید و چیزی یاد گرفته باشید که بتوانید از آن استفاده کنید. با تشکر برای خواندن!