Özet
<howto-checkbox>
, formdaki bir boole seçeneğini temsil eder. En yaygın onay kutusu türü, kullanıcının iki seçenek arasında geçiş yapmasına olanak tanıyan ikili türdür: işaretli ve işaretsiz.
Öğe, ilk oluşturulduğunda role="checkbox"
ve tabindex="0"
özelliklerini kendi kendine uygulamaya çalışır. role
özelliği, ekran okuyucu gibi yardımcı teknolojilerin kullanıcıya bunun ne tür bir kontrol olduğunu söylemesine yardımcı olur. tabindex
özelliği, öğeyi sekme sırasına ekleyerek klavyeyle odaklanabilir ve kullanılabilir hale getirir. Bu iki konu hakkında daha fazla bilgi edinmek için ARIA ne yapabilir? ve tabindex kullanma başlıklı makaleleri inceleyin.
Onay kutusu işaretlendiğinde bir checked
boole özelliği eklenir ve ilgili checked
özelliği true
olarak ayarlanır. Ayrıca öğe, durumuna bağlı olarak aria-checked
özelliğini "true"
veya "false"
olarak ayarlar. Onay kutusunu fareyle veya boşluk tuşuyla tıkladığınızda bu onaylanmış durumlar açılıp kapanır.
Onay kutusu, disabled
durumunu da destekler. disabled
mülkü true olarak ayarlanırsa veya disabled
özelliği uygulanırsa onay kutusu aria-disabled="true"
değerini ayarlar, tabindex
özelliğini kaldırır ve onay kutusu geçerli activeElement
ise odak dokümana geri döner.
Onay kutusu, erişilebilir bir ada sahip olması için bir howto-label
öğesiyle eşleştirilir.
Referans
- HowTo: GitHub'da Bileşenler
- ARIA Yazma Uygulamaları 1.1'de onay kutusu kalıbı
- ARIA neler yapabilir?
- tabindex özelliğini kullanma
Demo
Canlı demoyu GitHub'da görüntüleme
Örnek kullanım
<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>
Kod
(function() {
Klavye etkinliklerini işlemeye yardımcı olması için tuş kodlarını tanımlayın.
const KEYCODE = {
SPACE: 32,
};
<template>
öğesindeki içeriklerin klonlanması, ek HTML ayrıştırma maliyetlerini önlediği için innerHTML kullanmaktan daha yüksek performanslıdır.
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'];
}
Öğenin kurucusu, yeni bir örnek oluşturulduğunda her zaman çalıştırılır. Örnekler, HTML ayrıştırılarak, document.createElement("howto-checkbox") çağrılarak veya new HowToCheckbox(); çağrılarak oluşturulur. Oluşturucu, gölge DOM oluşturmak için iyi bir yerdir ancak henüz kullanılamayabilecek özellikler veya hafif DOM alt öğelerine dokunmaktan kaçınmanız gerekir.
constructor() {
super();
this.attachShadow({mode: 'open'});
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
connectedCallback()
, öğe DOM'ye eklendiğinde tetiklenir. İlk role
, tabindex
, dahili durumu ayarlamak ve etkinlik dinleyicileri yüklemek için iyi bir yerdir.
connectedCallback() {
if (!this.hasAttribute('role'))
this.setAttribute('role', 'checkbox');
if (!this.hasAttribute('tabindex'))
this.setAttribute('tabindex', 0);
Kullanıcı, prototipi bu sınıfa bağlanmadan önce bir öğenin örneğinde bir özellik ayarlayabilir. _upgradeProperty()
yöntemi, tüm örnek özelliklerini kontrol eder ve bunları uygun sınıf ayarlayıcıları üzerinden çalıştırır. Daha fazla bilgi için tembel mülkler bölümüne bakın.
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()
, öğe DOM'dan kaldırıldığında tetiklenir. Referansları serbest bırakma ve etkinlik dinleyicilerini kaldırma gibi temizleme işlemlerini yapmak için iyi bir yerdir.
disconnectedCallback() {
this.removeEventListener('keyup', this._onKeyUp);
this.removeEventListener('click', this._onClick);
}
Tesisler ve ilgili özellikleri birbirini yansıtmalıdır. checked özelliğinin ayarlayıcısı, doğru/yanlış değerleri işler ve bunları özelliğin durumuna yansıtır. Daha fazla bilgi için yeniden girişten kaçınma bölümüne bakın.
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');
}
observedAttributes dizisindeki özelliklerden herhangi biri değiştiğinde attributeChangedCallback()
çağrılır. ARIA özelliklerini ayarlama gibi yan etkileri ele almak için iyi bir yerdir.
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
özelliği, bir öğenin odaklanılabilirliğini tamamen kaldırmanın bir yolunu sağlamaz. tabindex=-1
içeren öğeler, fareyle veya focus()
çağrılarak odaklanmaya devam edebilir. Bir öğenin devre dışı olduğundan ve odaklanılabilir olmadığından emin olmak için tabindex
özelliğini kaldırın.
if (hasValue) {
this.removeAttribute('tabindex');
Odak şu anda bu öğedeyse HTMLElement.blur()
yöntemini çağırarak odağını kaldırın.
this.blur();
} else {
this.setAttribute('tabindex', '0');
}
break;
}
}
_onKeyUp(event) {
Genellikle yardımcı teknolojiler tarafından kullanılan değiştirici kısayolları işleme alınmayın.
if (event.altKey)
return;
switch (event.keyCode) {
case KEYCODE.SPACE:
event.preventDefault();
this._toggleChecked();
break;
Diğer tüm tuş basımları yoksayılır ve tarayıcıya geri iletilir.
default:
return;
}
}
_onClick(event) {
this._toggleChecked();
}
_toggleChecked()
, checked ayarlayıcısını çağırır ve durumunu değiştirir. _toggleChecked()
yalnızca bir kullanıcı işlemi nedeniyle gerçekleştiğinden bir değişiklik etkinliği de gönderilir. Bu etkinlik, <input type=checkbox>
'ün doğal davranışını taklit etmek için oluşturulur.
_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);
})();