İç düğmenin click olayını işleyin, ardından bileşen ana öğesinden adlandırılmış bir CustomEvent gönderin. Tüketen sayfa bu ana öğeyi dinler ve event.detail değerini okur. Bu kılavuz, Mac’te eksiksiz bir yerel tarayıcı demosu oluşturur ve her dinleyicinin hangi olay seçeneklerine ihtiyaç duyduğunu açıklar.

Tüketicinizin ihtiyaç duyduğu bildirimi tanımlayın

Düz JavaScript web bileşeninde tüketici, özel öğenizi kullanan sayfa veya kapsayıcı bileşendir. Buradaki somut amaç, bileşenin gölge DOM’unu sorgulamadan, biri iç düğmeyi etkinleştirdiğinde tüketicinin tepki vermesini sağlamaktır.

Örnekte Tile A etiketli yapay bir kutucuk kullanılıyor. Genel olayı tile-activate adını taşır ve bir itemId ile etkinleştirme count değeri içerir. CustomEvent, uygulama verileri için detail alanını sağlar; olay adı büyük küçük harfe duyarlıdır. Gönderme kodu ile dinleyici tamamen aynı adı kullanmalıdır. CustomEvent oluşturucu belgeleri.

Bu tercihleri küçük bir arayüz sözleşmesi olarak ele alın:

  • Ad: tile-activate.
  • Anlam: iç düğme etkinleştirildi ve sayaç güncellendi.
  • Veri yükü: detail.itemId kutucuğu tanımlar; detail.count güncellenmiş sayacı içerir.
  • Kaynak: özel öğenin ana öğesi bildirimi gönderir.
  • İletim: doğrudan tüketiciler ve üst öğe dinleyicileri, kapsayıcı gölge sınırlarını aşanlar da dahil olmak üzere, olayı alabilir.

Bunlar bu örneğe özgü tasarım tercihleridir. Yararlı bir olay, tüketicinin önem verdiği eylemi anlatır. Böylece bileşen, aynı bildirim arayüzünü korurken iç işaretlemesini daha sonra değiştirebilir.

Mac’inizde eksiksiz örneği oluşturup açın

Güncel bir masaüstü tarayıcısına ve düz metin düzenleyicisine ihtiyacınız var. Bu tek dosyalı örnek için paket kurulumu veya derleme adımı gerekmez. Örnek, HTML Standardı’nın özel öğeler bölümünde belgelenen platform örüntüsünü izleyerek HTMLElement sınıfını genişleten bağımsız bir özel öğe kullanır.

TextEdit’te File > New, ardından Format > Make Plain Text seçeneklerini belirleyin. Aşağıdaki belgenin tamamını yapıştırın. File > Save seçeneğini belirleyip dosyaya component-click.html adını verin ve sorulursa Use .html seçeneğini seçin. Apple, TextEdit’te HTML dosyası oluşturmak için bu adımları belgeliyor. Mac’te TextEdit ile HTML belgeleri üzerinde çalışma.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Component click notification</title>
</head>
<body>
  <h1>Component click notification</h1>
  <section id="demo">
    <action-tile id="tile" item-id="tile-a"></action-tile>
    <p id="direct-status">Direct listener: waiting</p>
    <p id="parent-status">Parent listener: waiting</p>
  </section>

  <script>
    class ActionTile extends HTMLElement {
      constructor() {
        super();
        this._count = 0;
        this._button = null;
        this._root = this.attachShadow({ mode: "open" });
        this._handleClick = () => {
          this._count += 1;
          this.dispatchEvent(new CustomEvent("tile-activate", {
            detail: {
              itemId: this.getAttribute("item-id"),
              count: this._count
            },
            bubbles: true,
            composed: true
          }));
        };
      }

      connectedCallback() {
        if (!this._button) {
          this._button = document.createElement("button");
          this._button.type = "button";
          this._button.textContent = "Activate Tile A";
          this._root.append(this._button);
        }
        this._button.addEventListener("click", this._handleClick);
      }

      disconnectedCallback() {
        this._button.removeEventListener("click", this._handleClick);
      }
    }

    customElements.define("action-tile", ActionTile);

    const tile = document.getElementById("tile");
    const demo = document.getElementById("demo");
    const directStatus = document.getElementById("direct-status");
    const parentStatus = document.getElementById("parent-status");

    tile.addEventListener("tile-activate", (event) => {
      const { itemId, count } = event.detail;
      directStatus.textContent =
        `Direct listener: ${itemId}, activation ${count}`;
    });

    demo.addEventListener("tile-activate", (event) => {
      const { itemId, count } = event.detail;
      parentStatus.textContent =
        `Parent listener: ${itemId}, activation ${count}`;
    });
  </script>
</body>
</html>

Kaydedilen dosyayı tarayıcınızda açın ve Activate Tile A düğmesine tıklayın. Beklenen ilk sonuç Direct listener: tile-a, activation 1 ve Parent listener: tile-a, activation 1 olur. Sonraki her etkinleştirme, görüntülenen iki sayacı da bir artırır. Bunlar örnekten beklenen sonuçlardır; tarayıcıda test edildiği bildirilmiş sonuçlar değildir.

Kodda önemli sıralama açıkça görülür: bileşen durumunu güncelleyin, bildirimi oluşturun, this üzerinden gönderin ve tüketicinin kendi arayüzünü güncellemesine izin verin. dispatchEvent(), geçerli dinleyicileri dönmeden önce eşzamanlı olarak çağırır; bu nedenle tüketiciler, işleyicileri sırasında güncellenmiş sayacı görür. dispatchEvent belgeleri.

Kabarcıklanma ve gölge sınırı seçeneklerini doğru belirleyin

Hangi seçeneklerin önemli olduğunu gönderim hedefi ve dinleyicinin konumu belirler. Ana öğeye doğrudan eklenmiş bir dinleyici, bubbles false olsa bile bu ana öğeye gönderilen olayı alır. Sıradan bir üst öğe dinleyicisinin olayı alması için kabarcıklanma gerekir. Bir gölge sınırını aşmak için composed de gerekir. bubbles, composed ve cancelable seçeneklerinin varsayılan değerleri false’tur. DOM Standardı: Event arayüzü.

Aşağıdaki karar tablosu bu yayılma kurallarından çıkarılmıştır. Olağan biçimde capture kullanmadan kaydedilmiş dinleyicileri ve yayılmayı durduran bir işleyici olmadığını varsayar.

Özel olayın başladığı yer Tüketicinin dinlediği yer Bu rota için yapılandırma
Bileşen ana öğesi Aynı ana öğe İki bayrağın da true olması gerekmez
Bileşen ana öğesi Aynı ağaçtaki sıradan bir üst öğe bubbles: true
İç gölge düğmesi Bu gölge kökünün dışındaki sıradan bir üst öğe bubbles: true, composed: true
Başka bir gölge ağacının içindeki bileşen ana öğesi Kapsayıcı gölge kökünün dışındaki sıradan bir üst öğe bubbles: true, composed: true

Demoda this.dispatchEvent(...) bildirimi ana öğede başlatır. Bu nedenle bileşenin kendi gölge kökünden çıkması gerekmez. composed: true, bu kutucuk daha sonra iç içe yerleştirilirse bildirimin kapsayıcı bileşenin gölge sınırını aşmasını sağlar. Bu daha geniş erişim, genel arayüzün bilinçli bir parçası olmalıdır. Event composed belgeleri.

Odaklı bir deneme için yalnızca bubbles: true değerini bubbles: false olarak değiştirin, kaydedin ve sayfayı yeniden yükleyin. Etkinleştirmede doğrudan durum güncellenmeli, üst öğe durumu ise Parent listener: waiting olarak kalmalıdır. Ardından kabarcıklanmayı yeniden etkinleştirin. Yalnızca composed değerini false yapmak, bu belgede hiçbir rota gölge sınırını aşmadığından iki dinleyicinin de çalışmasını sağlamalıdır.

Başlatma ve yeniden bağlanma davranışını koruyun

Olay iletimi başlangıçta doğru görünebilir, ancak bileşen taşındıktan veya yeniden bağlandıktan sonra yinelenen bildirimler üretebilir. Oluşturma, bağlanma ve temizleme sorumluluklarını açıkça belirleyin.

Oluşturucu önce super() çağrısını yapar, durumu başlatır ve bir gölge kökü ekler. İşleme connectedCallback() içinde yapılır ve mevcut düğme başvurusu sayesinde yalnızca bir kez çalışır. Bu tercihler, HTML Standardı’nın oluşturucu gerekliliklerini ve bağlantı geri çağrıları yeniden çalıştığında tekrarlanmaması gereken başlatma işlemlerini korumaya yönelik kılavuzunu izler. Özel öğe oluşturucuları ve tepkileri için gereklilikler.

Bileşen, iç tıklama dinleyicisini bağlandığında kaydeder ve bağlantısı kesildiğinde kaldırır. Yeniden bağlandığında mevcut düğmeyi yeniden kullanır ve _count değerini korur. Bağlanma ve bağlantıyı kesme geri çağrıları, öğeler belgeye girip çıkarken çağrılan yaşam döngüsü kancalarıdır. Özel öğeleri kullanma.

Saklanan _handleClick işlevi önemlidir: kaldırma işlemi, kayıt sırasında kullanılan aynı işlevi ve aynı capture ayarını tanımlamalıdır. Kaldırma çağrısında yeni bir ok işlevi oluşturmak, kayıtlı dinleyiciyi tanımlamaz. removeEventListener belgeleri.

Daha büyük bir bileşende window, document veya başka bir harici hedefe dinleyiciler eklerseniz, bu dinleyicilerin temizliğini de aynı açıklıkta yapın. Yaşam döngüsü değişikliklerini bildirimin anlamından ayrı tutun; böylece öğenin yeniden bağlanması yanlışlıkla bir kullanıcı eylemini duyurmaz.

Eksik veya yinelenen bildirimleri teşhis edin

Olay bayraklarını değiştirmeden önce arızayı bulmak için görünen iki durum satırını kullanın. Bu satırlar, bileşenin bildirimindeki bir sorunu üst öğeye iletimdeki bir sorundan ayırt eder.

  1. İki durum da değişmiyor: gönderimdeki ve kayıttaki olay adlarını karşılaştırın, ardından özel öğe tanımının ve düğme işleyicisinin çalıştığını kontrol edin. Bu belgede tüketici dinleyicileri, kullanıcı etkinleştirmesinden önce kaydedilir.
  2. Yalnızca doğrudan durum değişiyor: bubbles değerini kontrol edin. Ayrıca yayılmayı durduran ara işleyicileri inceleyin.
  3. Yalnızca başka bir bileşenin içine yerleştirildiğinde iletim başarısız oluyor: bu rotadaki gölge sınırını belirleyin ve composed değerini kontrol edin.
  4. Yeniden bağlanmadan sonra sayaçlar sıçrıyor: dinleyicilerin tekrar tekrar kaydedilip kaydedilmediğini, özellikle öğe her bağlandığında yeni anonim işlevler oluşturulup oluşturulmadığını inceleyin.

Yinelenen anonim işlevler, kaynak metinleri aynı olsa bile ayrı dinleyici nesneleridir. Kararlı bir işlev başvurusu kullanmak, kaydetme ve temizleme işlemlerini anlamayı kolaylaştırır. addEventListener(), dinleyicinin ne zaman çalışacağını etkileyen capture seçeneğini de ayırt eder. addEventListener belgeleri.

Yerel bir click olayı, tarayıcının gönderdiği tıklamalar composed olduğundan bir gölge ağacının dışına zaten ulaşabilir. Tüketicinin adlandırılmış bir bileşen eylemine ve tanımlanmış bir veri yüküne ihtiyacı olduğunda ayrı bir özel olay kullanışlıdır. Bu yinelenme kasıtlı değilse, iki bildirimi de aynı uygulama eylemi olarak işlemeyin. Event composed belgeleri.

Son olarak, bildirim ile devam etme iznini olay tasarımınızda ayrı tutun. Bu örnek, göndermeden önce sayacı artırır ve olayı iptal edilemez bırakır. Tüketicinin preventDefault() çağrısı bu güncellemeyi geri alamaz. İptal edilebilir bir istek için, istenen eylemi gerçekleştirmeden önce dispatchEvent() dönüş değerini kontrol eden açık bir uygulama gerekir. dispatchEvent dönüş değeri.

Bu görev için sözleşmenin tamamı basittir: bir iç düğme işleyicisi durumu günceller, adlandırılmış bir özel olay ana öğeden çıkar ve tüketiciler belgelenmiş veri yükünü okur. Önce doğrudan dinleyicinin çalıştığından emin olun, ardından kapsayıcı arayüzünüzün gerçekten ihtiyaç duyduğu yayılma rotalarını etkinleştirin.

Kaynaklar