"Nasıl Yapılır?" Bileşenleri – "nasıl yapılır" onay kutusu

Özet

<howto-checkbox>, formdaki boole seçeneğini temsil eder. En yaygın tür of onay kutusu, kullanıcının iki ekran arasında geçiş yapmasına olanak tanıyan çift türdür seçenekler -- işaretli ve işaretli değil.

Öğe, role="checkbox" ve İlk oluşturulduğunda tabindex="0". role özelliği, destekleyici olarak ekran okuyucu gibi bir teknoloji kullanıcıya bunun ne tür bir kontrol olduğunu söyler. tabindex özelliği, öğeyi sekme sırasına dahil ederek klavyeyi oluşturur ve uygulanabilir olması gerekir. Bu iki konu hakkında daha fazla bilgi edinmek için ARIA neler yapabilir? ve tabindex'i kullanma.

Onay kutusu işaretlendiğinde checked Boole özelliği eklenir ve true öğesine karşılık gelen bir checked özelliği. Buna ek olarak, öğe bir aria-checked özelliğini, değerine bağlı olarak, "true" veya "false" ile ilişkilendirin durumu. Fare veya boşluk çubuğuyla onay kutusunu tıkladığınızda bu kontrol edilmiş durumda olur.

Onay kutusu disabled durumunu da destekler. disabled özelliğinden değeri doğru değerine ayarlandığında veya disabled özelliği uygulanırsa onay kutusu aria-disabled="true", tabindex özelliğini kaldırır ve odağı döndürür activeElement öğesinin onay kutusu geçerliyse dokümana ekleyebilirsiniz.

Onay kutusu bir howto-label öğesiyle eşlenerek bir erişilebilir ad.

Referans

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 etkinliklerinin işlenmesine yardımcı olmak için tuş kodları 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'];
    }

Yeni bir örnek oluşturulduğunda öğenin kurucusu çalıştırılır. Örnekler, HTML ayrıştırılarak, document.createElement('howto-checkbox') çağrısı yapılarak veya yeni HowToCheckbox(); Oluşturucu gölge DOM'u oluşturmak için iyi bir yerdir, ancak henüz kullanıma sunulmamış olabileceğinden özelliklere veya ışık DOM alt öğelerine dokunmaktan kaçınmalısınız.

    constructor() {
      super();
      this.attachShadow({mode: 'open'});
      this.shadowRoot.appendChild(template.content.cloneNode(true));
    }

Öğe DOM'ye eklendiğinde connectedCallback() tetiklenir. Başlangıç role, tabindex, dahili durum ve yükleme etkinlik işleyicileri ayarlamak 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 öğenin bir örneğinde ö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 ayrıntı için tembel özellikler 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;
      }
    }

Öğe DOM'den kaldırıldığında disconnectedCallback() tetiklenir. Referans yayınlamak ve etkinlik işleyicileri kaldırmak gibi temizlik gerektiren işleri 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 ayrıntı için yeniden kaydolmadan 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');
    }

attributeChangedCallback(), estimatedAttributes dizisindeki özelliklerden herhangi biri değiştirildiğinde çağrılır. Bu sayfada, ARIA özelliklerini ayarlama gibi yan etkilerle başa çıkılabilir.

    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 öğeden odaklanılabilirliği tamamen kaldırma olanağı sunmuyor. tabindex=-1 içeren öğelere fare ile veya focus() çağrısı yapılarak odaklanmaya devam edebilirsiniz. Bir öğenin devre dışı bırakıldığından ve odaklanılamadığı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ğı 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ı kullanmayı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(), işaretli setter'ı çağırır ve durumunu değiştirir. _toggleChecked() yalnızca bir kullanıcı işleminden kaynaklandığı için bir değişiklik etkinliği de gönderir. Bu etkinlik, <input type=checkbox> etkinliğinin yerel davranışını taklit etmek için baloncuk oluşturur.

    _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);
})();