در این آموزش، ما یک جزء بلوک آکاردئونی قابل دسترس با استفاده از جاوا اسکریپت وانیلی ایجاد می کنیم که به کاربر اجازه می دهد محتوای تاشو را تغییر دهد.
1. ایجاد طرح بندی (HTML)
از آنجایی که ما در حال ساخت یک جزء سفارشی هستیم، تمرکز ما بر این است که آن را در دسترس قرار دهیم تا بتوان آن را توسط همه کاربران اداره کرد.
این HTML برای طرح آکاردئون ما است:
1 |
<section id="accordion" class="accordion"> |
2 |
<div class="accordion-container"> |
3 |
<div class="accordion-item"> |
4 |
<button class="accordion-trigger" id="accordion-trigger-1" aria-expanded="false" aria-controls="accordion-content-1"> |
5 |
<span class="accordion-title"> |
6 |
</span>
|
7 |
<span class="accordion-icon"> |
8 |
+
|
9 |
</span>
|
10 |
</button>
|
11 |
<div class="accordion-content" id="accordion-content-1" role="region" aria-labelledby="accordion-trigger-1"> |
12 |
<p></p>
|
13 |
</div>
|
14 |
</div>
|
15 |
|
16 |
... |
17 |
</div>
|
18 |
</section>
|
در دسترس ساختن چیزها
بیایید به ویژگی هایی که برای کمک به دسترسی استفاده می کنیم نگاهی بیندازیم:
-
aria-expanded
: این ویژگی روی عناصر جمع شونده استفاده می شود تا نشان دهد که آیا عنصر گسترش یافته است یا خیر. -
aria-controls
: این ویژگی روی عنصری استفاده می شود که وظیفه نمایش محتویات یک عنصر دیگر را بر عهده دارد. راaria-controls
مقدار، شناسه عنصری است که کنترل می شود. -
aria-labelledby
: این یک نام قابل دسترسی برای یک عنصر فراهم می کند. -
role
: این ویژگی برای اختصاص معنای معنایی به یک عنصر استفاده می شود. برای این آموزش، ما به محتوای آکاردئونی خود نقش اختصاص می دهیم منطقه.
2. سبک دادن به محتوا (CSS)
ما از CSS برای مدیریت زمانبندی انتقال عناصری که میخواهیم متحرک کنیم استفاده میکنیم. در این مورد، آن است accordion-content
و accordion-icon
. ما همچنین یک ظاهر طراحی را برای زمانی تنظیم می کنیم accordion-item
فعال است و محتوای آکاردئون را به طور پیش فرض مخفی می کند.
1 |
.accordion-icon { |
2 |
transition: transform 0.5s; |
3 |
}
|
4 |
|
5 |
.accordion-item.is-active .accordion-icon { |
6 |
transform: rotate(45deg); |
7 |
}
|
8 |
|
9 |
.accordion-content { |
10 |
height: 0; |
11 |
overflow: hidden; |
12 |
transition: 0.5s; |
13 |
}
|
این بقیه استایل برای چیدمان است:
1 |
.accordion-container { |
2 |
width: 90%; |
3 |
max-width: 1240px; |
4 |
margin: 0 auto; |
5 |
border: 3px solid #e0e0e0; |
6 |
border-radius: 24px; |
7 |
overflow: hidden; |
8 |
}
|
9 |
|
10 |
.accordion-item { |
11 |
width: 100%; |
12 |
}
|
13 |
|
14 |
.accordion-trigger { |
15 |
width: 100%; |
16 |
display: block; |
17 |
background-color: rgb(250, 250, 250); |
18 |
color: rgb(0, 0, 0); |
19 |
padding: 24px; |
20 |
font-size: 20px; |
21 |
font-weight: 500; |
22 |
font-family: 'Inter', sans-serif; |
23 |
text-align: left; |
24 |
border: none; |
25 |
display: flex; |
26 |
gap: 16px; |
27 |
justify-content: space-between; |
28 |
cursor: pointer; |
29 |
}
|
30 |
|
31 |
.accordion-item:not(:first-of-type) .accordion-trigger { |
32 |
border-top: 3px solid #eaeaea; |
33 |
}
|
34 |
|
35 |
.accordion-content { |
36 |
height: 0; |
37 |
overflow: hidden; |
38 |
transition: 0.5s; |
39 |
}
|
40 |
|
41 |
.accordion-content p { |
42 |
margin: 24px; |
43 |
}
|
نکته ای که باید به آن توجه داشت این است که ما از هیچ بالشتک یا حاشیه ای در عنصر محتوای آکاردئونی خود استفاده نمی کنیم و در عوض فقط یک حاشیه برای عنصر فرزند اعمال می کنیم. این بخاطر این است که height:0
بر حاشیهها یا بالشتکهای یک عنصر تأثیر نمیگذارد، بنابراین اگر فضایی را تنظیم کنیم، همچنان فضای قابل مشاهده خواهیم داشت.
3. مدیریت عملکرد آکاردئون (جاوا اسکریپت)
ابتدا باید همه اقلام آکاردئونی را تهیه کنیم:
1 |
const accordionItems = document.querySelectorAll(".accordion-item"); |
روی رویداد شنونده کلیک کنید
در مرحله بعد، عملکردی را در بارگذاری صفحه تعریف می کنیم تا شنونده رویداد کلیکی را به همه دکمه های ماشه آکاردئون اضافه کنیم.
1 |
window.addEventListener("load", () => { |
2 |
accordionItems.forEach((accordion, index) => { |
3 |
const accordionTrigger = accordion.querySelector(".accordion-trigger"); |
4 |
accordionTrigger.addEventListener("click", () => toggleAccordion(index)); |
5 |
});
|
6 |
});
|
از زمانی که ما .querySelectorAll()
روش a را برمی گرداند NodeList، می توانیم استفاده کنیم .forEach()
روش حلقه زدن از طریق هر عنصر آیتم آکاردئونی.
سپس میتوانیم هر دکمه ماشه را در داخل یک آیتم آکاردئونی خاص با استفاده از هدف قرار دهیم accordion.querySelector()
. ساخت کامپوننت به این شکل آن را مقیاسپذیرتر میکند، زیرا هدف قرار دادن عنصر محرک یا محتوا به شناسه یا نام کلاس خاصی وابسته نیست و در عوض بر اساس ظرف آکاردئونی موردی است که در آن وجود دارد.
عملکرد تعویض ما
اکنون ما شنونده رویداد خود را تنظیم کرده ایم، می توانیم خود را تعریف کنیم toggleAccordion()
عملکرد.
ابتدا می خواهیم آیتم فعلی آکاردئون را مورد هدف قرار دهیم. انجام این کار با استفاده امکان پذیر است e.target.parentNode
اما برای این نسخه ی نمایشی، به جای آن از ایندکس استفاده می کنیم، که toggleFunction آن را به عنوان یک پارامتر می پذیرد.
1 |
const toggleAccordion = (index) => { |
2 |
const currentAccordion = accordionItems[index]; |
3 |
currentAccordion.classList.toggle("is-active"); |
4 |
};
|
هنگامی که ماشه آکاردئون کلیک می شود، کلاس is-active را روی آیتم آکاردئونی مربوطه تغییر می دهیم.
این تابع همچنین بهروزرسانی ارتفاع محتوای آکاردئونی ما و تنظیم مقدار افزایش یافته با آریا ماشه آکاردئون را روی false انجام میدهد.
ما ارتفاع را در جاوا اسکریپت تنظیم می کنیم تا یک اثر گذار بر روی محتوای آکاردئون ایجاد کنیم زیرا هیچ راهی برای دانستن ارتفاع دقیق محتوای آکاردئون در CSS وجود ندارد.
این چیزی است که ما به روز کردیم toggleAccordion()
تابع به نظر می رسد:
1 |
const toggleAccordion = (index) => { |
2 |
resetAccordions(index); |
3 |
|
4 |
const currentAccordion = accordionItems[index]; |
5 |
currentAccordion.classList.toggle("is-active"); |
6 |
|
7 |
const accordionContent = currentAccordion.querySelector(".accordion-content"); |
8 |
const accordionTrigger = currentAccordion.querySelector(".accordion-trigger"); |
9 |
|
10 |
if (currentAccordion.classList.contains("is-active")) { |
11 |
accordionContent.style.height = `${accordionContent.scrollHeight}px`; |
12 |
accordionTrigger.setAttribute("aria-expanded", "true"); |
13 |
} else { |
14 |
accordionContent.style.height = 0; |
15 |
accordionTrigger.setAttribute("aria-expanded", "false"); |
16 |
}
|
17 |
};
|
هنگامی که کلاس is-active را در accordion فعلی تغییر دادیم، از وجود کلاس is-active برای تعیین ویژگیهای آریا و استایل محرک و محتوای آکاردئون استفاده میکنیم.
از جمله یک تابع تنظیم مجدد
ما میتوانیم با اضافه کردن یک تابع بازنشانی، این ساخت را بیشتر گسترش دهیم تا مطمئن شویم فقط یک آکاردئون در یک زمان باز است. تابع بازنشانی ما از طریق حلقه حلقه خواهد شد accordionItems
NodeList را فهرست کنید و وضعیت فعال را در هر آیتم آکاردئونی به جز حالت فعلی بر اساس شاخص آن حذف کنید.
بیایید تعریف کنیم resetAccordions()
عملکرد:
1 |
const resetAccordions = (targetIndex) => { |
2 |
accordionItems.forEach((accordion, index) => { |
3 |
const accordionContent = accordion.querySelector(".accordion-content"); |
4 |
const accordionTrigger = accordion.querySelector(".accordion-trigger"); |
5 |
|
6 |
if (targetIndex != index) { |
7 |
accordion.classList.remove("is-active"); |
8 |
accordionContent.style.height = 0; |
9 |
accordionTrigger.setAttribute("aria-expanded", "false"); |
10 |
}
|
11 |
});
|
12 |
};
|
ما حلقه را از طریق accordionItem
و تمام عناصری را که شاخص آیتم برابر نیست هدف قرار دهید targetIndex
در حال منتقل شدن به resetAccordions()
عملکرد.
در نهایت، ما می توانیم خود را به روز کنیم toggleAccordion()
عملکردی که شامل تنظیم مجدد بلوک آکاردئون در هنگام کلیک روی یک آیتم آکاردئونی است:
1 |
const toggleAccordion = (index) => { |
2 |
resetAccordions(index); |
3 |
|
4 |
const currentAccordion = accordionItems[index]; |
5 |
currentAccordion.classList.toggle("is-active"); |
6 |
|
7 |
const accordionContent = currentAccordion.querySelector(".accordion-content"); |
8 |
const accordionTrigger = currentAccordion.querySelector(".accordion-trigger"); |
9 |
|
10 |
if (currentAccordion.classList.contains("is-active")) { |
11 |
accordionContent.style.height = `${accordionContent.scrollHeight}px`; |
12 |
accordionTrigger.setAttribute("aria-expanded", "true"); |
13 |
} else { |
14 |
accordionContent.style.height = 0; |
15 |
accordionTrigger.setAttribute("aria-expanded", "false"); |
16 |
}
|
17 |
};
|
نتیجه
و با آن، ما به طور کامل یک جزء آکاردئونی جاوا اسکریپت ساخته ایم! آفرین. بیایید محصول نهایی را به خود یادآوری کنیم: