رابطهای کشیدن و رها کردن به بخشی جداییناپذیر از برنامههای وب مدرن تبدیل شدهاند و راهی شهودی برای مرتبسازی لیستها، جابجایی فایلها یا مدیریت جریانهای کاری ارائه میدهند. با این حال، یک دام رایج در توسعه فرانتاند، ترجیح دادن تعاملات ماوس بر دسترسیپذیری صفحهکلید است. برای کاربرانی که از خوانندههای صفحه یا پیمایش صرفاً با صفحهکلید استفاده میکنند، یک پیادهسازی استاندارد کشیدن و رها کردن اغلب مانعی برای ورود محسوب میشود. این پست بررسی میکند که چگونه میتوان با استفاده تنها از جاوااسکریپت خالص و استانداردهای WAI-ARIA، عملکرد کشیدن و رها کردن قوی و در دسترس را پیادهسازی کرد تا اطمینان حاصل شود برنامه شما برای همه قابل استفاده است.
چرا دسترسیپذیری صفحهکلید در کشیدن و رها کردن اهمیت دارد
کشیدن و رها کردن سنتی به شدت به API رویدادهای ماوس (mousedown، mousemove، mouseup) متکی است. اگرچه این روش برای کاربران ماوس خوب کار میکند، اما کاربران صفحهکلید را به طور کامل حذف میکند. طبق دستورالعملهای WCAG 2.1، تمام عملکردهایی که از طریق رابط ماوس در دسترس هستند باید از طریق صفحهکلید نیز قابل دسترسی باشند. این بدان معناست که ما به یک رویکرد دوگانه نیاز داریم: پشتیبانی از کشیدن بومی تا حد امکان، اما مهمتر از آن، ارائه یک «حالت صفحهکلید» جایگزین که به کاربران اجازه دهد آیتمها را با استفاده از کلیدهای جهتنما و Enter/Space جابجا کنند.
نقشها و حالتهای اصلی WAI-ARIA
برای ارتباط وضعیت عناصر تعاملی ما با فناوریهای کمکی، باید از نقشهای خاص WAI-ARIA استفاده کنیم. رایجترین الگو شامل استفاده از role="listbox" برای ظرف و role="option" برای آیتمهای قابل کشیدن است. ما همچنین باید وضعیت را به صورت پویا با استفاده از ویژگیهایی مانند مدیریت کنیم:
aria-grabbed: نشان میدهد که آیا یک آیتم قابل کشیدن است (true) یا خیر (false).aria-dropeffect: نشان میدهد چه عملیاتی هنگام رها کردن آیتم رخ میدهد (به عنوان مثال، "move"، "copy").aria-activedescendant: به گزینهای که در حال حاضر متمرکز یا «فعال» است در داخل لیستباکس اشاره میکند و به خوانندههای صفحه کمک میکند موقعیت را ردیابی کنند.
پیادهسازی منطق کشیدن و رها کردن در دسترس
در زیر یک پیادهسازی سادهشده از مکانیسم مرتبسازی لیست آورده شده است. این مثال بر منطق تعامل صفحهکلید تمرکز دارد که اغلب در دسترسپذیری نادیده گرفته میشود.
const listContainer = document.getElementById('item-list');
const items = Array.from(listContainer.querySelectorAll('[role="option"]'));
// کمکی مدیریت تمرکز
let currentIndex = 0;
function moveItem(direction) {
const current = items[currentIndex];
// تعیین ایندکس هدف بر اساس جهت ('up' یا 'down')
const newIndex = direction === 'up'
? currentIndex - 1
: currentIndex + 1;
// بررسی مرزها
if (newIndex < 0 || newIndex >= items.length) return;
const target = items[newIndex];
// جابجایی عناصر در DOM
if (direction === 'up') {
listContainer.insertBefore(current, target);
} else {
listContainer.insertBefore(target, current);
}
// بهروزرسانی ترتیب آرایه برای بازتاب تغییرات DOM
const tempItems = Array.from(listContainer.querySelectorAll('[role="option"]'));
const oldIndex = items.indexOf(current);
items.splice(oldIndex, 1);
items.splice(newIndex, 0, current);
// انتقال تمرکز به آیتم با موقعیت جدید
target.focus();
listContainer.setAttribute('aria-activedescendant', target.id);
// اعلام تغییر به خواننده صفحه
current.setAttribute('aria-label', `Moved ${direction}`);
}
// شنونده رویداد برای پیمایش صفحهکلید
listContainer.addEventListener('keydown', (e) => {
if (e.key === 'ArrowUp') {
e.preventDefault();
moveItem('up');
} else if (e.key === 'ArrowDown') {
e.preventDefault();
moveItem('down');
}
});
بهبود تجربه ماوس
در حالی که کد بالا پیمایش صفحهکلید را مدیریت میکند، یک راهحل کامل باید کشیدن ماوس را نیز پشتیبانی کند. برای این کار میتوانید از HTML5 Drag and Drop API یا کتابخانهای مانند SortableJS (پیکربندی شده برای دسترسیپذیری) استفاده کنید. نکته کلیدی این است که اطمینان حاصل کنید وقتی یک آیتم با ماوس برداشته میشود، حالت aria-grabbed آن به true بهروزرسانی شود و پس از رها کردن، به false بازگردد.
// نمونهای از بهروزرسانی وضعیت ARIA در طول کشیدن ماوس
function onDragStart(event) {
event.target.setAttribute('aria-grabbed', 'true');
event.dataTransfer.effectAllowed = 'move';
}
function onDragEnd(event) {
event.target.setAttribute('aria-grabbed', 'false');
}
تست و اعتبارسنجی
پس از پیادهسازی، تست دقیق ضروری است. از ابزارهایی مانند Web Accessibility Evaluation Tools (WAVE) برای بررسی اعتبار ویژگیهای ARIA استفاده کنید. مهمتر از آن، رابط کاربری خود را با یک خواننده صفحه (مانند NVDA یا VoiceOver) تست کنید و صرفاً با استفاده از صفحهکلید پیمایش کنید. اطمینان حاصل کنید که کاربر بازخورد شنیداری واضحی هنگام جابجایی آیتمها دریافت میکند و ترتیب تمرکز منطقی باقی میماند.
نتیجهگیری
پیادهسازی رابطهای کشیدن و رها کردن در دسترس تنها درباره انطباق نیست؛ بلکه درباره همدلی و فراگیری است. با ترکیب ویژگیهای WAI-ARIA با منطق جاوااسکریپت خالص، میتوانیم تجربیات غنی و تعاملی ایجاد کنیم که به طور بینقص برای همه کاربران، صرفنظر از روش ورودی آنها، کار میکند. به عنوان توسعهدهندگان فرانتاند، مسئولیت ما فراتر از زیباییشناسی بصری است و شامل اطمینان از باز و قابل استفاده بودن برنامههای ما برای همه میشود.