בפוסט זה נראה כיצד להחליף CSS Classes של אלמנטים באמצעות JavaScript ו-data attributes. גישה זו שומרת על JavaScript גנרי וניתן לשימוש חוזר – במקום לכתוב handler נפרד לכל toggle, מגדירים את היעד ושם ה-class ישירות ב-HTML.
שימוש ב-data attributes כ-hooks ל-JavaScript הוא best practice להפרדת אחריות. מחלקות CSS נשארות לעיצוב, ותכונות
data-*מניעות התנהגות. כך ניתן לשנות עיצוב מבלי לשבור פונקציונליות, ולהיפך.
הגדרת HTML בסיסית
נסתכל ראשית על מבנה HTML בסיסי. נשתמש בכפתור כדי להחליף (toggle) מחלקה (class) של אלמנט היעד. ה-JavaScript משתמש ב-querySelectorAll כדי למצוא את כל טריגרי ה-toggle.
<button data-toggle-target="#content" data-toggle-class="highlight">Toggle Highlight</button>
<div id="content">This is the content to be toggled.</div>
קוד ה- JavaScript להחלפת ה- Class
נוסיף לאחר מכן JavaScript שיטפל באירוע הלחיצה על הכפתור ויחליף את class שהוגדר באלמנט היעד.
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('[data-toggle-target]').forEach(button => {
button.addEventListener('click', () => {
const targetSelector = button.getAttribute('data-toggle-target');
const className = button.getAttribute('data-toggle-class');
document.querySelectorAll(targetSelector).forEach(target => {
target.classList.toggle(className);
});
});
});
});
הפרמטר force
המתודה classList.toggle() מקבלת פרמטר שני אופציונלי בשם force. כאשר force הוא true, ה-class רק מתווסף (לעולם לא מוסר). כאשר false, הוא רק מוסר (לעולם לא מתווסף). זה שימושי להגדרת מצב על פי תנאי:
// Only add the class when a condition is true
element.classList.toggle('active', isExpanded);
// Equivalent to:
if (isExpanded) {
element.classList.add('active');
} else {
element.classList.remove('active');
}
שימוש במאפיין dataset
הקוד למעלה משתמש ב-getAttribute() לקריאת data attributes. חלופה היא המאפיין dataset, שממיר שמות תכונות data-* ל-camelCase:
const targetSelector = button.dataset.toggleTarget; // reads data-toggle-target
const className = button.dataset.toggleClass; // reads data-toggle-class
שתי הגישות עובדות באופן זהה. dataset קצר יותר, בעוד ש-getAttribute() מפורש יותר ועובד עם שמות תכונות שלא עוקבים אחרי מוסכמת data-.
עיצוב עם CSS
נוסיף לדוגמה זו מעט CSS כדי לראות את ההשפעה של החלפת ה- class:
.highlight {
background-color: darkolivegreen;
}
הנה דוגמה חיה:
מספר יעדים
ניתן גם להחליף מחלקות (classes) על מספר אלמנטים במקביל. עדכנו את ה-HTML כדי לראות זאת בפעולה:
<button data-toggle-target=".content" data-toggle-class="highlight">Toggle Highlight on All</button>
<div class="content">Content 1</div>
<div class="content">Content 2</div>
ה-HTML כולל כפתורים עם תכונות data-toggle-target ו-data-toggle-class. אותו JavaScript בוחר את כל האלמנטים עם data-toggle-target ומוסיף Event Listener ללחיצה על הכפתור. כאשר לוחצים על כפתור, הוא מחליף את ה-class באלמנטים.
עבור כפתורי toggle שמציגים/מסתירים תוכן, הוסיפו aria-expanded="false" לכפתור ועדכנו אותו עם JavaScript בעת ההחלפה. כך קוראי מסך יודיעו למשתמשים על המצב הנוכחי.
הנה דוגמה חיה:
שאלות נפוצות
שאלות נפוצות על החלפת classes באמצעות JavaScript ו-data attributes:
classList.toggle() מוסיף את ה-class אם הוא חסר ומסיר אותו אם קיים - מתודה אחת שמטפלת בשני הכיוונים. classList.add() ו-classList.remove() עובדים רק בכיוון אחד. השתמשו ב-toggle() כשרוצים אפקט מתג, וב-add()/remove() כשצריך שליטה מפורשת על המצב הסופי..js-toggle כ-hook ל-JavaScript, שינוי שם או הסרה שלה במהלך רפקטורינג של CSS עלולים לשבור את הסקריפטים. תכונות data כמו data-toggle-target מיועדות בבירור ל-JavaScript, כך שמעצבים ומפתחים יכולים לעבוד בנפרד ללא התנגשויות.classList.toggle(className, force) שולט בכיוון. כאשר force הוא true, ה-class רק מתווסף. כאשר false, ה-class רק מוסר. זה שימושי לסנכרון ה-class עם תנאי בוליאני, כמו element.classList.toggle('open', isMenuOpen).classList.toggle() מקבל רק class אחד בכל פעם. כדי להחליף מספר classes, קראו למתודה פעם לכל אחד: element.classList.toggle('a'); element.classList.toggle('b');. לחלופין, ניתן להרחיב את גישת ה-data attributes כך שתקבל רשימת classes מופרדת ברווחים ולפצל אותם ב-JavaScript.getAttribute('data-toggle-target') משתמש בשם התכונה המלא והוא יותר מפורש. dataset.toggleTarget משתמש ב-camelCase והוא יותר תמציתי. הביצועים זהים בדפדפנים מודרניים. בחרו סגנון אחד ושמרו על עקביות בבסיס הקוד.סיכום
תכונות data מספקות דרך נקייה לחבר התנהגות toggle ישירות ב-HTML ללא כתיבת JavaScript ייעודי לכל אלמנט. אותו סקריפט גנרי מטפל בכל מספר של כפתורים, יעדים ושמות classes.
השתמשו בפרמטר force של classList.toggle() כשצריך לסנכרן class עם תנאי בוליאני במקום להחליף אותו הלוך ושוב.
לנגישות, הוסיפו aria-expanded לכפתורי toggle שמציגים או מסתירים תוכן, כך שקוראי מסך יוכלו להודיע על המצב הנוכחי.

