Zusammenfassung
Ein <howto-checkbox>
steht für eine boolesche Option in einem Formular. Der häufigste Typ
Das Kontrollkästchen ist ein Dual-Typ, bei dem der Nutzer
Auswahl - aktiviert und deaktiviert.
Das Element versucht, die Attribute role="checkbox"
und
tabindex="0"
fest. Das Attribut role
hilft bei der
wie Screenreader, um Nutzenden mitzuteilen, welche Art von Steuerung das ist.
Mit dem Attribut „tabindex
“ wird das Element in die TAB-Reihenfolge verschoben, also per Tastatureingabe
fokussierbar und bedienbar. Weitere Informationen zu diesen beiden Themen findest du in
Was kann ARIA tun? und Tabindex verwenden.
Wenn das Kästchen angeklickt ist, wird das boolesche Attribut checked
hinzugefügt und
entsprechende checked
-Property für true
. Außerdem legt das Element ein
aria-checked
-Attribut entweder auf "true"
oder "false"
Bundesstaat. Durch Klicken auf das Kontrollkästchen mit der Maus oder Leertaste können Sie diese
geprüften Status.
Das Kästchen unterstützt auch den Status disabled
. Wenn entweder das Attribut disabled
auf „true“ gesetzt ist oder das Attribut disabled
angewendet wird, legt das Kästchen fest
aria-disabled="true"
, entfernt das Attribut tabindex
und kehrt den Fokus zurück
zum Dokument hinzufügen, wenn das Kästchen die aktuelle activeElement
ist.
Das Kästchen ist mit einem howto-label
-Element gekoppelt, damit es ein
barrierefreier Name.
Referenz
- Anleitung: Komponenten auf GitHub
- Kästchenmuster in ARIA Authoring Practices 1.1
- Was kann ARIA tun?
- Tabindex verwenden
Demo
Nutzungsbeispiel
<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>
Code
(function() {
Definieren Sie Schlüsselcodes, um die Verarbeitung von Tastaturereignissen zu erleichtern.
const KEYCODE = {
SPACE: 32,
};
Das Klonen von Inhalten aus einem <template>
-Element ist leistungsfähiger als das Verwenden von innerHTML, da zusätzliche Kosten für die HTML-Analyse vermieden werden.
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'];
}
Der Konstruktor des Elements wird jedes Mal ausgeführt, wenn eine neue Instanz erstellt wird. Instanzen werden entweder durch Parsen von HTML, durch Aufrufen von document.createElement('howto-checkbox') oder durch Aufrufen von new HowToCheckbox() erstellt. Der Konstruktor eignet sich gut zum Erstellen eines Shadow DOM. Sie sollten jedoch keine Attribute oder Light-DOM-Unterelemente berühren, da diese möglicherweise noch nicht verfügbar sind.
constructor() {
super();
this.attachShadow({mode: 'open'});
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
connectedCallback()
wird ausgelöst, wenn das Element in das DOM eingefügt wird. Hier können Sie die anfänglichen role
-, tabindex
- und internen Status-Listener sowie Installationsereignis-Listener festlegen.
connectedCallback() {
if (!this.hasAttribute('role'))
this.setAttribute('role', 'checkbox');
if (!this.hasAttribute('tabindex'))
this.setAttribute('tabindex', 0);
Ein Nutzer kann eine Eigenschaft für eine Instanz eines Elements festlegen, bevor sein Prototyp mit dieser Klasse verbunden wurde. Die Methode _upgradeProperty()
sucht nach Instanzattributen und führt sie durch die richtigen Klassen-Setter. Weitere Informationen finden Sie im Abschnitt Verzögerte Eigenschaften.
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()
wird ausgelöst, wenn das Element aus dem DOM entfernt wird. Hier können Sie Bereinigungsarbeiten ausführen, z. B. Referenzen veröffentlichen und Ereignis-Listener entfernen.
disconnectedCallback() {
this.removeEventListener('keyup', this._onKeyUp);
this.removeEventListener('click', this._onClick);
}
Eigenschaften und ihre entsprechenden Attribute sollten sich widerspiegeln. Der Property-Setter für aktivierte Werte verarbeitet wahrheitsgemäße/falsche Werte und spiegelt sie im Status des Attributs wider. Weitere Informationen finden Sie im Abschnitt Widerruf vermeiden.
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()
wird aufgerufen, wenn sich eines der Attribute im Array „Beobachtende Attribute“ ändert. Hier können Sie sich gut mit Nebenwirkungen wie dem Festlegen von ARIA-Attributen befassen.
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);
Das Attribut tabindex
bietet keine Möglichkeit, die Fokussierbarkeit eines Elements vollständig zu entfernen. Elemente mit tabindex=-1
können weiterhin mit einer Maus oder durch Aufrufen von focus()
fokussiert werden. Entfernen Sie das Attribut tabindex
, damit ein Element deaktiviert und nicht fokussierbar ist.
if (hasValue) {
this.removeAttribute('tabindex');
Wenn der Fokus derzeit auf diesem Element liegt, heben Sie den Fokus auf, indem Sie die Methode HTMLElement.blur()
aufrufen
this.blur();
} else {
this.setAttribute('tabindex', '0');
}
break;
}
}
_onKeyUp(event) {
Verwenden Sie keine Modifikatortasten, die normalerweise von Hilfstechnologien verwendet werden.
if (event.altKey)
return;
switch (event.keyCode) {
case KEYCODE.SPACE:
event.preventDefault();
this._toggleChecked();
break;
Jeder andere Tastendruck wird ignoriert und an den Browser zurückgegeben.
default:
return;
}
}
_onClick(event) {
this._toggleChecked();
}
_toggleChecked()
ruft den aktivierten Setter auf und dreht seinen Status. Da _toggleChecked()
nur durch eine Nutzeraktion verursacht wird, wird auch ein Änderungsereignis ausgelöst. Dieses Ereignis wird erstellt, um das native Verhalten von <input type=checkbox>
nachzuahmen.
_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);
})();