ملخّص
تمثل القيمة <howto-checkbox>
خيارًا منطقيًا في نموذج. النوع الأكثر شيوعًا
من مربع الاختيار هي نوع مزدوج يتيح للمستخدم التبديل بين اثنين
الخيارات -- تم تحديدها وإلغاء تحديدها.
يحاول العنصر تطبيق السمتين role="checkbox"
بشكل ذاتي
tabindex="0"
عند إنشائه لأول مرة. تساعد السمة role
تقنية مثل قارئ الشاشة تخبر المستخدم عن نوع التحكم هذا.
تعمل السمة tabindex
على تفعيل العنصر في ترتيب التنقل بـ Tab، مما يجعله لوحة المفاتيح
وقابلة للتركيز والتشغيل. لمعرفة المزيد حول هذين الموضوعين، اطلع على
ما الذي يمكن أن يفعله ARIA؟ واستخدام tabindex
عند وضع علامة في مربّع الاختيار، تضيف السمة المنطقية checked
وتضبط
قيمة السمة checked
المقابلة لـ true
. بالإضافة إلى ذلك، يعين العنصر
سمة aria-checked
إما إلى "true"
أو "false"
، بناءً على
الولاية. يؤدي النقر على مربع الاختيار بالماوس أو شريط المسافة إلى تبديل هذه
الحالات المحددة.
يتيح مربّع الاختيار أيضًا استخدام حالة disabled
. إذا كانت السمة disabled
على "صحيح" أو عند تطبيق السمة disabled
، فستُضبط مربّعات الاختيار
aria-disabled="true"
، وتتم إزالة السمة tabindex
وإعادة التركيز
بالمستند إذا كان مربّع الاختيار هو activeElement
الحالي.
يتم إقران مربّع الاختيار بعنصر howto-label
للتأكّد من أنّه يتضمّن
اسم ظاهر.
مَراجع
- طريقة التنفيذ: المكوّنات على GitHub
- نمط مربّع الاختيار في الإصدار 1.1 من ممارسات التأليف في ARIA
- ما الذي يمكن أن يفعله ARIA؟
- استخدام Tabindex
عرض توضيحي
مشاهدة عرض توضيحي مباشر على GitHub
مثال على الاستخدام
<style>
howto-checkbox {
vertical-align: middle;
}
howto-label {
vertical-align: middle;
display: inline-block;
font-weight: bold;
font-family: sans-serif;
font-size: 20px;
margin-left: 8px;
}
</style>
<howto-checkbox id="join-checkbox"></howto-checkbox>
<howto-label for="join-checkbox">Join Newsletter</howto-label>
الرمز
(function() {
يمكنك تحديد رموز رئيسية للمساعدة في التعامل مع أحداث لوحة المفاتيح.
const KEYCODE = {
SPACE: 32,
};
يُعدّ استنساخ المحتوى من عنصر <template>
أفضل من استخدام HTML الداخلي لأنّه يتجنّب التكاليف الإضافية لتحليل HTML.
const template = document.createElement('template');
template.innerHTML = `
<style>
:host {
display: inline-block;
background: url('../images/unchecked-checkbox.svg') no-repeat;
background-size: contain;
width: 24px;
height: 24px;
}
:host([hidden]) {
display: none;
}
:host([checked]) {
background: url('../images/checked-checkbox.svg') no-repeat;
background-size: contain;
}
:host([disabled]) {
background:
url('../images/unchecked-checkbox-disabled.svg') no-repeat;
background-size: contain;
}
:host([checked][disabled]) {
background:
url('../images/checked-checkbox-disabled.svg') no-repeat;
background-size: contain;
}
</style>
`;
class HowToCheckbox extends HTMLElement {
static get observedAttributes() {
return ['checked', 'disabled'];
}
يتم تشغيل الدالة الإنشائية للعنصر في أي وقت يتم فيه إنشاء مثيل جديد. يتم إنشاء المثيلات إما عن طريق تحليل HTML أو استدعاء document.createElement('howto-checkbox') أو استدعاء HowToCheckbox(); تعتبر الدالة الإنشائية مكانًا جيدًا لإنشاء shadow DOM، على الرغم من أنّه يجب تجنُّب لمس أي سمات أو عناصر light DOM الثانوية لأنّها قد لا تكون متاحة بعد.
constructor() {
super();
this.attachShadow({mode: 'open'});
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
يتم تنشيط connectedCallback()
عند إدراج العنصر في DOM. وهو مكان مناسب لضبط أدوات معالجة الأحداث المبدئية في role
وtabindex
والحالة الداخلية وعمليات التثبيت.
connectedCallback() {
if (!this.hasAttribute('role'))
this.setAttribute('role', 'checkbox');
if (!this.hasAttribute('tabindex'))
this.setAttribute('tabindex', 0);
يمكن للمستخدم تعيين خاصية على مثيل عنصر قبل ربط النموذج الأولي بهذه الفئة. ستتحقّق الطريقة _upgradeProperty()
من توفُّر أي خصائص مثيل وستشغّلها من خلال أدوات تحديد الفئة المناسبة. راجِع قسم الخصائص الكسولة للحصول على مزيد من التفاصيل.
this._upgradeProperty('checked');
this._upgradeProperty('disabled');
this.addEventListener('keyup', this._onKeyUp);
this.addEventListener('click', this._onClick);
}
_upgradeProperty(prop) {
if (this.hasOwnProperty(prop)) {
let value = this[prop];
delete this[prop];
this[prop] = value;
}
}
يتم تنشيط disconnectedCallback()
عند إزالة العنصر من DOM. إنه مكان جيد لإنجاز الأعمال مثل إصدار المراجع وإزالة المستمعين للأحداث.
disconnectedCallback() {
this.removeEventListener('keyup', this._onKeyUp);
this.removeEventListener('click', this._onClick);
}
يجب أن تتطابق المواقع والسمات المرتبطة بها مع بعضها. تتعامل دالة setter مع قيم الحقيقة/الخيالية التي تم تحديدها مع تلك التي تشير إلى حالة السمة. راجع قسم تجنُّب إعادة الدخول للحصول على مزيد من التفاصيل.
set checked(value) {
const isChecked = Boolean(value);
if (isChecked)
this.setAttribute('checked', '');
else
this.removeAttribute('checked');
}
get checked() {
return this.hasAttribute('checked');
}
set disabled(value) {
const isDisabled = Boolean(value);
if (isDisabled)
this.setAttribute('disabled', '');
else
this.removeAttribute('disabled');
}
get disabled() {
return this.hasAttribute('disabled');
}
يتم استدعاء attributeChangedCallback()
عند تغيير أي من السمات في صفيف noticeAttributes. وهو مكان جيد للتعامل مع الآثار الجانبية، مثل ضبط سمات ARIA.
attributeChangedCallback(name, oldValue, newValue) {
const hasValue = newValue !== null;
switch (name) {
case 'checked':
this.setAttribute('aria-checked', hasValue);
break;
case 'disabled':
this.setAttribute('aria-disabled', hasValue);
لا توفّر السمة tabindex
طريقة لإلغاء إمكانية التركيز بالكامل من العنصر. سيظلّ بإمكانك التركيز على العناصر التي تتضمّن tabindex=-1
باستخدام الماوس أو من خلال طلب القيمة focus()
. للتأكّد من إيقاف عنصر ومن عدم إمكانية التركيز عليه، أزِل السمة tabindex
.
if (hasValue) {
this.removeAttribute('tabindex');
إذا كان التركيز حاليًا على هذا العنصر، عليك إلغاء التركيز من خلال استدعاء طريقة HTMLElement.blur()
.
this.blur();
} else {
this.setAttribute('tabindex', '0');
}
break;
}
}
_onKeyUp(event) {
لا تتعامل مع اختصارات المعدِّل التي تستخدمها عادةً التكنولوجيا المساعِدة.
if (event.altKey)
return;
switch (event.keyCode) {
case KEYCODE.SPACE:
event.preventDefault();
this._toggleChecked();
break;
ويتم تجاهل أي ضغطة مفتاحية أخرى وإعادتها إلى المتصفِّح.
default:
return;
}
}
_onClick(event) {
this._toggleChecked();
}
يستدعي _toggleChecked()
الإعداد المحدّد ويقلب حالته. بما أنّ _toggleChecked()
ناتج عن إجراء من جانب المستخدم فقط، سيتم أيضًا إرسال حدث تغيير. يظهر هذا الحدث كفقاعات لمحاكاة سلوك <input type=checkbox>
الأصلي.
_toggleChecked() {
if (this.disabled)
return;
this.checked = !this.checked;
this.dispatchEvent(new CustomEvent('change', {
detail: {
checked: this.checked,
},
bubbles: true,
}));
}
}
customElements.define('howto-checkbox', HowToCheckbox);
})();