Özet
<howto-checkbox>
, formdaki 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 alarak klavyede odaklanılabilir ve çalışabilir 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 checked
boole özelliği eklenir ve true
öğesine karşılık gelen checked
özelliği ayarlanır. Buna ek olarak, öğe, bir aria-checked
özelliğini durumuna bağlı olarak "true"
veya "false"
değerine ayarlar. Onay kutusunu fareyle veya boşluk tuşuyla tıkladığınızda bu işaretli 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 kutusunun erişilebilir bir ada sahip olması için howto-label
öğesiyle eşleştirilmesi gerekir.
Referans
- HowTo: GitHub'da Bileşenler
- ARIA Yazma Uygulamalarında Onay Kutusu Kalıbı 1.1
- ARIA neler yapabilir?
- Tabindex'i kullanma
Demo
GitHub'da canlı demoyu görüntüle
Ö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,
};
Bir <template>
öğesinden içerik klonlamak, ek HTML ayrıştırma maliyetlerini önlemesi nedeniyle innerHTML kullanmaktan daha etkilidir.
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, örnek özelliklerini kontrol eder ve bunları uygun sınıf belirleyiciler aracılığıyla ç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);
}
Özellikler ve karşılık gelen özellikler birbirini yansıtmalıdır. İşaretlenmiş için özellik belirleyici, 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 tuşlara basmalar yoksayılır ve tarayıcıya geri döner.
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);
})();