معايير نجاح WCAG · Level A

WCAG 2.5.2: إلغاء المؤشر

تتطلب WCAG 2.5.2 أن تكون الوظيفة التي يتم تشغيلها بواسطة مؤشر واحد (الماوس أو اللمس أو القلم) قابلة للإلغاء أو العكس، لمنع عمليات التفعيل غير المقصودة. يحمي هذا المستخدمين ذوي الإعاقات الحركية الذين قد ينقرون أو يضغطون عن غير قصد.

ماذا يعني هذا المعيار

ينطبق معيار WCAG 2.5.2 إلغاء إجراء المؤشر على كل الوظائف التي يتم تشغيلها باستخدام مؤشر واحد — وهذا يشمل نقرات الفأرة، ولمسات الشاشة، وضغطات القلم، وأي جهاز إدخال آخر يفعّل نقطة على الشاشة. وُضع هذا المعيار لضمان إمكانية التراجع عن التفعيلات العرضية الناتجة عن ضغط أو لمس غير مقصود قبل أن تُنفَّذ.

لكي يتوافق تفاعل بمؤشر واحد مع هذا المعيار، يجب أن يستوفي واحدًا على الأقل من الشروط الأربعة التالية المحددة في مواصفة WCAG:

  • عدم التفعيل عند حدث الضغط (Down-Event): لا يتم تشغيل الوظيفة عند حدث الضغط (مثل mousedown أو touchstart أو pointerdown). يحدث التفعيل فقط عند حدث الرفع (up-event) مثل mouseup أو touchend أو pointerup.
  • الإلغاء أو التراجع: يتوفر آلية لإلغاء الإجراء قبل اكتماله، أو للتراجع عن الإجراء بعد اكتماله.
  • الانعكاس عند الرفع (Up Reversal): يقوم حدث الرفع بعكس أي نتيجة تم تشغيلها عند حدث الضغط — على سبيل المثال، سحب يعود إلى موضعه إذا تم إفلات المؤشر خارج الهدف.
  • استثناء الضرورة (Essential Exception): يكون التفعيل عند حدث الضغط ضروريًا لوظيفة العنصر — مثل لوحة مفاتيح بيانو على الشاشة يجب أن يبدأ الصوت فيها لحظة الضغط على المفتاح. مع ذلك، فإن هذا الاستثناء ضيق جدًا ولا ينطبق إلا عندما يكون توقيت حدث الضغط ضروريًا بشكل جوهري.

من الناحية العملية في HTML وJavaScript، يعني هذا أن على المطورين الانتباه إلى مكان إرفاق مستمعي الأحداث. استخدام mousedown أو touchstart أو pointerdown لتنفيذ إجراء بشكل فوري ولا رجعة فيه — مثل إرسال نموذج، أو حذف سجل، أو الانتقال بعيدًا عن صفحة — دون توفير أي طريقة لإلغاء أو التراجع عن هذا الإجراء يُعد فشلًا واضحًا في هذا المعيار. سلوك المتصفح الافتراضي لعناصر <button> و<a> الأصلية يقوم بتفعيل الإجراء عند حدث الرفع بشكل افتراضي، ما يعني أن العناصر الأصلية المنفذة بشكل صحيح تجتاز هذا المعيار عادةً دون جهد إضافي.

المكوّنات التفاعلية المخصصة المبنية باستخدام JavaScript — مثل واجهات السحب والإفلات، وأشرطة التمرير القائمة على الإيماءات، وأدوات التحكم في الشرائح (carousel)، وخرائط الصور — هي أكثر مصادر الفشل شيوعًا. أي مكوّن يربط منطقًا لا رجعة فيه بمستمع لحدث الضغط دون توفير آلية للإلغاء أو الانعكاس يفشل في هذا المعيار.

لماذا يهم هذا المعيار

إلغاء إجراء المؤشر هو في الأساس معيار مصمم لحماية المستخدمين ذوي الإعاقات الحركية، لكن فوائده تمتد إلى مجموعة واسعة من المستخدمين، بما في ذلك أولئك الذين لديهم رعشات، أو تشنجات، أو محدودية في التحكم الحركي الدقيق، أو إعاقات معرفية تؤثر في الانتباه والدقة.

تأمل مستخدمًا مصابًا بمرض باركنسون يتنقل في صفحة إتمام الشراء في موقع تجارة إلكترونية على شاشة لمس. قد تتسبب رعشة يده في أن يهبط إصبعه على زر "تأكيد الشراء" دون أن يقصد ذلك. إذا تم تشغيل عملية الشراء في اللحظة التي يلمس فيها الإصبع الشاشة — عند حدث touchstart — تتم معالجة المعاملة فورًا دون أي فرصة للإلغاء. لو كان التفعيل مرتبطًا بحدث touchend، لكان بإمكان المستخدم سحب إصبعه بعيدًا عن الزر قبل رفعه، مما يلغي الإجراء. هذا الاختلاف البسيط بين الربط بحدث الرفع والربط بحدث الضغط يمكن أن يكون الفارق بين تجربة محبِطة وتجربة متاحة لملايين المستخدمين.

وفقًا لمنظمة الصحة العالمية، يعيش حوالي 1.3 مليار شخص حول العالم مع شكل من أشكال الإعاقة، وتمثل الإعاقات الحركية جزءًا كبيرًا من هذه الفئة. وبعيدًا عن الإعاقة، تُعد التفعيلات العرضية مصدر إزعاج شائع لأي مستخدم على جهاز بشاشة صغيرة تعمل باللمس، مما يجعل هذا المعيار ذا صلة بقابلية الاستخدام العامة أيضًا.

الإعاقة المعرفية اعتبار مهم آخر. قد يضغط بعض المستخدمين الذين يعالجون المعلومات ببطء على زر ثم يدركون أنهم اختاروا الخيار الخاطئ. إذا كان الإجراء لا رجعة فيه — ويتم تشغيله عند حدث الضغط — فلن يكون لديهم أي وسيلة للتصرف. توفر آلية التراجع أو التفعيل عند حدث الرفع لهؤلاء المستخدمين الوقت الذي يحتاجونه لتأكيد نيتهم.

من منظور الأعمال، يقلل تقليل عمليات إرسال النماذج، والمشتريات، والحذف العرضية من شكاوى المستخدمين، ويقلل طلبات الدعم، ويخفض معدلات التخلي عن المعاملات. كما أن نموذج التفاعل بالمؤشر المتاح يقلل أيضًا من مخاطر المسؤولية القانونية بموجب لوائح الوصول في تركيا وعلى المستوى الدولي.

قواعد axe-core ذات الصلة

يتطلب معيار WCAG 2.5.2 اختبارًا يدويًا ولا يمكن تقييمه بشكل موثوق بواسطة أدوات الفحص الآلي لإمكانية الوصول وحدها. لا توجد قاعدة آلية محددة في axe-core تطابق هذا المعيار مباشرة. إليك سبب عدم كفاية الاكتشاف الآلي:

  • لماذا تفشل الأتمتة في إلغاء إجراء المؤشر: يمكن للأدوات الآلية مثل axe-core تحليل HTML واكتشاف بعض مشكلات ARIA أو المشكلات الهيكلية، لكنها لا تستطيع تحديد النية الدلالية وقابلية التراجع لمعالِجات أحداث JavaScript بشكل موثوق. قد يكتشف أحد الأدوات وجود مستمع لحدث mousedown على عنصر ما، لكنه لا يستطيع تحديد ما إذا كان هذا المستمع يشغّل إجراءً لا رجعة فيه، أو ما إذا كانت هناك آلية تراجع موجودة في مكان آخر في التطبيق، أو ما إذا كان توقيت حدث الضغط ضروريًا بالفعل لوظيفة العنصر. إن مزيج سلوك وقت التشغيل، وحالة التطبيق، وسياق المستخدم المطلوب لتقييم هذا المعيار يتجاوز نطاق التحليل الآلي الثابت أو القائم على DOM.
  • ما الذي يجب أن يبحث عنه المختبرون يدويًا: يحتاج المختبرون إلى التفاعل مع كل عنصر تفاعلي باستخدام جهاز مؤشر وملاحظة اللحظة الدقيقة التي يتم فيها تشغيل الإجراء — عند الضغط أم عند الرفع. كما يجب عليهم التحقق مما إذا كان سحب المؤشر بعيدًا عن العنصر قبل الرفع يلغي الإجراء، وما إذا كانت أي آلية للتراجع أو الإلغاء متاحة بعد التفعيل.
  • الإشارات الجزئية من الأتمتة: قد تقوم بعض أدوات الفحص (linting) أو قواعد axe المخصصة بوضع علامة على العناصر التي تحتوي على السمات onmousedown أو ontouchstart أو onpointerdown على أنها تتطلب مراجعة، لكن هذه العلامات تحتاج إلى حكم بشري لتحديد التوافق أو عدم التوافق. تعامل مع أي علامة آلية من هذا النوع باعتبارها إشارة لبدء تحقيق يدوي، وليس تقرير فشل نهائي.

كيفية الاختبار

  1. فحص آلي (مسح أولي): شغّل axe DevTools أو Lighthouse على الصفحة لتحديد العناصر التفاعلية وأي ربط مخصص للأحداث تم وضع علامة عليه للمراجعة اليدوية. في Chrome DevTools، استخدم لوحة Elements لفحص مستمعي الأحداث المرفقين بالأزرار والروابط وعناصر التحكم المخصصة — وابحث عن معالِجات mousedown أو touchstart أو pointerdown على العناصر التي تشغّل إجراءات لا رجعة فيها.
  2. اختبار مؤشر الفأرة — الإلغاء بالسحب أثناء الضغط: لكل زر تفاعلي، ورابط، وعنصر تحكم مخصص في الصفحة، اضغط مع الاستمرار على زر الفأرة فوق العنصر، ثم اسحب المؤشر خارج حدود العنصر قبل الإفلات. إذا تم تشغيل الإجراء أثناء الضغط على الزر (قبل الإفلات)، فهذا فشل. إذا منع السحب بعيدًا تشغيل الإجراء عند الإفلات، فهذا نجاح وفقًا لشرط الانعكاس عند الرفع أو عدم التفعيل عند حدث الضغط.
  3. اختبار جهاز اللمس: على جهاز بشاشة لمس أو محاكي متصفح (وضع الأجهزة في Chrome DevTools)، المس كل عنصر تفاعلي مع الاستمرار، ثم اسحب إصبعك بعيدًا قبل رفعه. إذا تم تشغيل الإجراء فورًا عند اللمس (قبل رفع الإصبع)، فهذا فشل ما لم يكن توقيت حدث الضغط ضروريًا. تحقق من أن رفع إصبعك خارج العنصر لا يشغّل الإجراء.
  4. فحص التحكم عبر لوحة المفاتيح: رغم أن هذا المعيار يتعلق تحديدًا بتفاعلات المؤشر، تحقق من أن جميع العناصر التفاعلية قابلة للتشغيل أيضًا عبر لوحة المفاتيح. اضغط على Tab للتركيز على كل عنصر، ثم Enter أو Space لتفعيله، مع التأكد من أن العنصر يمكن الوصول إليه وتشغيله دون استخدام المؤشر — فهذا يدعم الصورة الأوسع لإمكانية الوصول.
  5. التحقق من آليات التراجع/الإلغاء: بالنسبة للإجراءات المرتبطة بأحداث الضغط (حيث قد ينطبق استثناء الضرورة)، تأكد من وجود آلية واضحة للتراجع أو الإلغاء وأنها متاحة لجميع المستخدمين، بما في ذلك مستخدمي تقنيات المساعدة. على سبيل المثال، بعد إجراء سحب وإفلات، هل يوجد زر "تراجع" يمكن الوصول إليه عبر لوحة المفاتيح وقارئ الشاشة؟
  6. اختبار الجمع بين قارئ الشاشة والمؤشر (NVDA + Firefox، JAWS + Chrome، VoiceOver + Safari): فعّل العناصر التفاعلية باستخدام كل من المؤشر ومؤشر قارئ الشاشة الافتراضي. تأكد من أن الإجراءات التي يشغّلها المؤشر متسقة مع تلك التي يشغّلها قارئ الشاشة، وأنه لا يتم تشغيل إجراءات فورية لا رجعة فيها بشكل غير متوقع.
  7. مراجعة الشيفرة: ابحث في قاعدة الشيفرة عن ربط مستمعي الأحداث: addEventListener('mousedown' وaddEventListener('touchstart' وaddEventListener('pointerdown'، وكذلك السمات المضمّنة onmousedown وontouchstart. لكل حالة، قيّم ما إذا كان المعالِج يشغّل إجراءً لا رجعة فيه وما إذا كان أي من الشروط الأربعة لـ WCAG مستوفيًا.

كيفية الإصلاح

إجراء لا رجعة فيه على mousedown — غير صحيح

<!-- FAIL: Delete fires immediately on mousedown, no cancellation possible -->
<button onmousedown='deleteRecord(recordId)'>Delete Record</button>

<script>
function deleteRecord(id) {
  // Record is deleted immediately on button press, before the user releases
  fetch('/api/records/' + id, { method: 'DELETE' });
}
</script>

إجراء لا رجعة فيه على mousedown — صحيح

<!-- PASS: Delete fires on click (up-event), native button behavior -->
<button onclick='deleteRecord(recordId)'>Delete Record</button>

<!-- Even better: provide confirmation dialog as an additional abort mechanism -->
<button onclick='confirmDelete(recordId)'>Delete Record</button>

<script>
function confirmDelete(id) {
  // User can cancel via the dialog — satisfies the Abort or Undo condition
  if (confirm('Are you sure you want to delete this record? This cannot be undone.')) {
    fetch('/api/records/' + id, { method: 'DELETE' });
  }
}
</script>

إيماءة لمس تُشغَّل عند touchstart — غير صحيح

<!-- FAIL: Action fires immediately on touchstart, no opportunity to abort -->
<div id='buy-btn'>Buy Now</div>

<script>
document.getElementById('buy-btn').addEventListener('touchstart', function() {
  // Purchase initiated immediately when finger touches the element
  initiatePurchase();
});
</script>

إيماءة لمس تُشغَّل عند touchstart — صحيح

<!-- PASS: Use a native button and bind to click, which fires on touchend -->
<button id='buy-btn'>Buy Now</button>

<script>
// The 'click' event on a native button fires on the up-event (touchend/mouseup)
// giving users the ability to cancel by sliding their finger away before releasing
document.getElementById('buy-btn').addEventListener('click', function() {
  initiatePurchase();
});
</script>

سحب وإفلات مخصص بدون انعكاس عند الرفع — غير صحيح

<!-- FAIL: Item is moved to new position on pointerdown, not on pointerup -->
<div class='draggable' onpointerdown='moveItemToTarget(this)'>
  Drag me
</div>

سحب وإفلات مخصص مع انعكاس عند الرفع — صحيح

<!-- PASS: Item moves to target only when pointer is released over the drop zone -->
<!-- If user drags away before releasing, item returns to original position -->
<div
  class='draggable'
  draggable='true'
  ondragstart='handleDragStart(event)'
>
  Drag me
</div>
<div
  class='drop-zone'
  ondragover='event.preventDefault()'
  ondrop='handleDrop(event)'
  aria-label='Drop zone'
>
  Drop here
</div>

<script>
function handleDragStart(event) {
  // Only records intent; does not move the item yet
  event.dataTransfer.setData('text/plain', event.target.id);
}
function handleDrop(event) {
  event.preventDefault();
  // Item is moved only on drop (up-event equivalent)
  // If user releases outside drop zone, item returns to origin — up-reversal satisfied
  const id = event.dataTransfer.getData('text/plain');
  event.currentTarget.appendChild(document.getElementById(id));
}
</script>

الأخطاء الشائعة

  • ربط إجراءات لا رجعة فيها مثل إرسال النماذج، أو حذف السجلات، أو التنقل إلى صفحات أخرى بأحداث mousedown أو pointerdown بدلًا من click، الذي يتم تشغيله عند حدث الرفع ويسمح بالإلغاء عن طريق السحب بعيدًا بشكل افتراضي.
  • استخدام touchstart لتشغيل المشتريات، أو التأكيدات، أو تغييرات البيانات في واجهات التجارة الإلكترونية أو الخدمات المصرفية، حيث لا ينبغي اعتبار ملامسة الإصبع للحظات نية مؤكدة من المستخدم.
  • الافتراض بأنه لمجرد أن الزر يستخدم عنصر <button> أصليًا، فإن كل JavaScript المرتبط به متوافق تلقائيًا — فمستمع mousedown المضاف عبر addEventListener لا يزال ينتهك هذا المعيار إذا كان يشغّل إجراءً لا رجعة فيه.
  • استدعاء مربعات حوارية (modals)، أو تراكبات (overlays)، أو تغييرات تنقل على مستوى الصفحة بالكامل عند حدث الضغط للمؤشر، مما يربك المستخدمين الذين لم يقصدوا تفعيل عنصر التحكم ولا يملكون طريقة للعودة.
  • تنفيذ عناصر تحكم مخصصة للمنزلقات أو النطاقات تقوم بتثبيت قيمة على الخادم عند pointerdown بدلًا من الانتظار حتى pointerup أو إجراء تأكيد منفصل.
  • الاعتماد على مربع حوار confirm() الافتراضي في المتصفح كآلية التراجع الوحيدة لإجراء مرتبط بحدث الضغط دون اختبار ما إذا كانت تقنيات المساعدة يمكنها الوصول إلى مربع الحوار وتشغيله بشكل موثوق قبل اكتمال الإجراء التدميري.
  • عدم توفير أي تغذية راجعة مرئية أو برمجية تفيد بأن إجراء حدث الضغط قيد الانتظار، مما يجعل من المستحيل على المستخدمين فهم أنهم يمكنهم الإلغاء عن طريق تحريك المؤشر بعيدًا قبل الرفع.
  • التعامل مع استثناء الضرورة بشكل واسع جدًا — على سبيل المثال، الادعاء بأن زر "شراء سريع" يحتاج إلى التشغيل عند mousedown من أجل السرعة، بينما لا يوجد أي قيد حقيقي على التوقيت، ويكون الادعاء مجرد تفضيل منتج وليس ضرورة وظيفية.
  • عدم الاختبار على كل من أجهزة الفأرة وأجهزة اللمس — فقد يستخدم أحد الواجهات أحداث الرفع بشكل صحيح لتفاعلات الفأرة لكنه لا يزال يربط إجراءات لا رجعة فيها بـ touchstart في مسار شيفرة منفصل خاص بالهواتف المحمولة.
  • تنفيذ وظيفة التراجع بحيث تكون متاحة فقط عبر اختصار لوحة المفاتيح (مثل Ctrl+Z) دون توفير عنصر تحكم مكافئ على الشاشة، مما يترك المستخدمين الذين يعتمدون على المؤشر فقط دون آلية إلغاء بعد تفعيل حدث الضغط.

العلاقة بلوائح إمكانية الوصول في تركيا

تُقرّر المذكرة الرئاسية التركية 2025/10، المنشورة في الجريدة الرسمية رقم 32933 بتاريخ 21 يونيو 2025، متطلبات إلزامية لإمكانية الوصول على الويب متوافقة مع معايير WCAG 2.2. بموجب هذه المذكرة، يُعد الالتزام بمعايير المستوى A — بما في ذلك WCAG 2.5.2 إلغاء إجراء المؤشر — مطلبًا قانونيًا لمجموعة واسعة من الكيانات العامة والخاصة التي تدير خدمات رقمية في تركيا.

تشمل المذكرة طيفًا واسعًا من المنظمات. يجب على المؤسسات العامة والهيئات الحكومية تحقيق التوافق الكامل مع المستوى A خلال عام واحد من تاريخ نشر المذكرة. أما الكيانات في القطاع الخاص المشمولة باللائحة — بما في ذلك منصات التجارة الإلكترونية، والبنوك والمؤسسات المالية، والمستشفيات ومقدمي الرعاية الصحية، وشركات الاتصالات التي لديها 200,000 مشترك أو أكثر، ووكالات السفر، وشركات النقل الخاصة، والمدارس الخاصة المرخصة من وزارة التربية الوطنية (MoNE) — فيُمنح لها إطار زمني مدته عامان للامتثال.

بالنسبة لهذه الكيانات المشمولة، فإن الفشل في تنفيذ إلغاء إجراء المؤشر بشكل صحيح ينطوي على مخاطر تنظيمية حقيقية. تأمل منصة تجارة إلكترونية تركية تقوم صفحة إتمام الشراء على الهاتف المحمول فيها بتشغيل تأكيد الدفع عند touchstart — مثل هذا التنفيذ سيشكل انتهاكًا مباشرًا لـ WCAG 2.5.2، وبالتالي للمذكرة الرئاسية. سيكون لدى المستخدمين الذين يبدؤون عملية شراء عن طريق الخطأ على تلك المنصة بسبب رعشة، أو إعاقة حركية، أو مجرد لمس خاطئ، أساس قانوني للادعاء بأن المنصة لم تفِ بالتزاماتها المتعلقة بإمكانية الوصول.

وبعيدًا عن الامتثال التنظيمي، ينبغي على المنظمات التركية أن تدرك أن إلغاء إجراء المؤشر ليس مجرد خانة فنية للتأشير، بل هو مبدأ تصميم أساسي يحمي قدرة المستخدمين على التفاعل بأمان وبشكل مقصود مع الخدمات الرقمية. إن تنفيذ التفعيل عند حدث الرفع وآليات التراجع عبر المكوّنات التفاعلية — من عربات التسوق وأنظمة حجز المواعيد إلى أدوات إدارة المستندات — يُظهر التزامًا بالتصميم الشامل الذي يفيد جميع المستخدمين، وليس فقط ذوي الإعاقة.

يجب على المنظمات الخاضعة للمذكرة إجراء عمليات تدقيق منهجية لأنماط التعامل مع أحداث JavaScript لديها، خصوصًا في الصفحات المحسّنة للهواتف المحمولة والمكوّنات التفاعلية المخصصة، لتحديد أي تفعيلات عند حدث الضغط تفتقر إلى آليات الإلغاء أو الانعكاس ومعالجتها. سيساعد توثيق جهود المعالجة هذه أيضًا في دعم التزامات تقارير التوافق التي قد تُطلب بموجب أحكام إنفاذ المذكرة.