ゼファーネットのロゴ

コンテキストアウェアWebコンポーネントはあなたが思っているよりも簡単です

日付:

まだ説明していないWebコンポーネントのもうXNUMXつの側面は、Webコンポーネントがページに追加またはページから削除されるたびにJavaScript関数が呼び出されることです。 これらのライフサイクルコールバックは、要素にそのコンテキストを認識させるなど、さまざまな目的に使用できます。

記事シリーズ

WebコンポーネントのXNUMXつのライフサイクルコールバック

XNUMXつのライフサイクルコールバック Webコンポーネントで使用できるもの:

  • connectedCallback:このコールバックは、カスタム要素が 添付された 要素に。
  • disconnectedCallback:このコールバックは、要素が次の場合に発生します 削除 ドキュメントから。
  • adoptedCallback:このコールバックは、要素が次の場合に発生します 追加されました 新しいドキュメントに。
  • attributeChangedCallback:このコールバックは、 属性を使用する。 その属性が監視されている限り、変更、追加、または削除されます。

これらの実際の動作を見てみましょう。

私たちのポスト黙示録的な人のコンポーネント

WebコンポーネントのXNUMXつのレンダリングを並べて表示します。左側は人間、右側はゾンビです。

まず、というWebコンポーネントを作成します。 <postapocalyptic-person>。 黙示録の後のすべての人は人間かゾンビのどちらかであり、クラスに基づいてどちらかがわかります—どちらか .human or .zombie —これはの親要素に適用されます <postapocalyptic-person> 成分。 (まだ)特別なことは何もしませんが、追加します shadowRoot その分類に基づいて、対応する画像を添付するために使用できます。

customElements.define( "postapocalyptic-person", class extends HTMLElement { constructor() { super(); const shadowRoot = this.attachShadow({ mode: "open" }); }
}

HTMLは次のようになります。

<div class="humans"> <postapocalyptic-person></postapocalyptic-person>
</div>
<div class="zombies"> <postapocalyptic-person></postapocalyptic-person>
</div>

で人を挿入する connectedCallback

<postapocalyptic-person> ページに読み込まれ、 connectedCallback() 関数が呼び出されます。

connectedCallback() { let image = document.createElement("img"); if (this.parentNode.classList.contains("humans")) { image.src = "https://assets.codepen.io/1804713/lady.png"; this.shadowRoot.appendChild(image); } else if (this.parentNode.classList.contains("zombies")) { image.src = "https://assets.codepen.io/1804713/ladyz.png"; this.shadowRoot.appendChild(image); }
}

これにより、人間の画像が出力されるようになります。 <postapocalyptic-person> は人間であり、コンポーネントがゾンビの場合はゾンビの画像です。

での作業には注意してください connectedCallback。 それはあなたが思っているよりも頻繁に実行され、要素が動かされたときはいつでも発火し、(不可解に)実行することさえできます After ノードは接続されなくなります—これは高額なパフォーマンスコストになる可能性があります。 使用できます this.isConnected 要素が接続されているかどうかを知るため。

で人を数える connectedCallback() それらが追加されたとき

ミックスにいくつかのボタンを追加して、もう少し複雑にしましょう。 XNUMXつ追加します <postapocalyptic-person>、「コイントス」アプローチを使用して、それが人間かゾンビかを判断します。 もう一方のボタンは反対のことを行い、 <postapocalyptic-person> 無作為に。 そこにいる間、何人の人間とゾンビが見えているかを追跡します。

<div class="btns"> <button id="addbtn">Add Person</button> <button id="rmvbtn">Remove Person</button> <span class="counts"> Humans: <span id="human-count">0</span> Zombies: <span id="zombie-count">0</span> </span>
</div>

ボタンの機能は次のとおりです。

let zombienest = document.querySelector(".zombies"), humancamp = document.querySelector(".humans"); document.getElementById("addbtn").addEventListener("click", function () { // Flips a "coin" and adds either a zombie or a human if (Math.random() > 0.5) { zombienest.appendChild(document.createElement("postapocalyptic-person")); } else { humancamp.appendChild(document.createElement("postapocalyptic-person")); }
});
document.getElementById("rmvbtn").addEventListener("click", function () { // Flips a "coin" and removes either a zombie or a human // A console message is logged if no more are available to remove. if (Math.random() > 0.5) { if (zombienest.lastElementChild) { zombienest.lastElementChild.remove(); } else { console.log("No more zombies to remove"); } } else { if (humancamp.lastElementChild) { humancamp.lastElementChild.remove(); } else { console.log("No more humans to remove"); } }
});

これがのコードです connectedCallback() これは、追加された人間とゾンビをカウントします。

connectedCallback() { let image = document.createElement("img"); if (this.parentNode.classList.contains("humans")) { image.src = "https://assets.codepen.io/1804713/lady.png"; this.shadowRoot.appendChild(image); // Get the existing human count. let humancount = document.getElementById("human-count"); // Increment it humancount.innerHTML = parseInt(humancount.textContent) + 1; } else if (this.parentNode.classList.contains("zombies")) { image.src = "https://assets.codepen.io/1804713/ladyz.png"; this.shadowRoot.appendChild(image); // Get the existing zombie count. let zombiecount = document.getElementById("zombie-count"); // Increment it zombiecount.innerHTML = parseInt(zombiecount.textContent) + 1; }
}

でカウントを更新する disconnectedCallback

次に、 disconnectedCallback() 人間とゾンビが削除されると、数を減らします。 ただし、対応するクラスの親要素がすでになくなっているため、親要素のクラスを確認できません。 disconnectedCallback と呼ばれます。 要素に属性を設定したり、オブジェクトにプロパティを追加したりすることもできますが、 src 属性はその親要素によってすでに決定されているので、削除されるWebコンポーネントが人間であるかゾンビであるかを知るためのプロキシとして使用できます。

disconnectedCallback() { let image = this.shadowRoot.querySelector('img'); // Test for the human image if (image.src == "https://assets.codepen.io/1804713/lady.png") { let humancount = document.getElementById("human-count"); humancount.innerHTML = parseInt(humancount.textContent) - 1; // Decrement count // Test for the zombie image } else if (image.src == "https://assets.codepen.io/1804713/ladyz.png") { let zombiecount = document.getElementById("zombie-count"); zombiecount.innerHTML = parseInt(zombiecount.textContent) - 1; // Decrement count }
}

ピエロに注意してください!

今(そしてもちろん、ここでの経験から話しています)、ゾンビの大群があなたの位置を支えているよりも恐ろしいのはピエロだけです—必要なのはXNUMXつだけです! ですから、私たちはすでに恐ろしい終末後のゾンビを扱っていますが、さらに恐ろしいためにピエロがシーンに入る可能性を追加しましょう。 実際、画面上の人間やゾンビが密かに変装したピエロになる可能性があるように行います!

前に言ったことを取り戻します。XNUMXつのゾンビピエロは、「通常の」ピエロのグループよりも怖いです。 人間であれゾンビであれ、何らかの種類のピエロが見つかった場合、それらをまったく異なるドキュメントに送信することで、人間とゾンビの集団から分離するとします。 <iframe> 刑務所、あなたがそうするなら。 (「ピエロ」はゾンビの伝染よりも伝染性が高いと聞いています。)

そして、疑わしいピエロを現在の文書から <iframe>、元のノードを破棄して再作成することはありません。 むしろそれは、最初に呼び出して、前記ノードを採用して接続します adoptedCallback その後 connectedCallback.

には何も必要ありません <iframe> 本文を除く文書 .clowns クラス。 このドキュメントがメインドキュメントのiframe内にある限り(個別に表示されない限り)、 <postapocalyptic-person> インスタンス化コード。 人間用のスペースとゾンビ用のスペースをXNUMXつずつ含めます。そうです、ピエロの刑務所…えーと… <iframe> の…楽しい。

<div class="btns"> <button id="addbtn">Add Person</button> <button id="jailbtn">Jail Potential Clown</button>
</div>
<div class="humans"> <postapocalyptic-person></postapocalyptic-person>
</div>
<div class="zombies"> <postapocalyptic-person></postapocalyptic-person>
</div>
<iframe class="clowniframeoffun” src="adoptedCallback-iframe.html">
</iframe>

「人を追加」ボタンは、前の例と同じように機能します。デジタルコインを裏返して、人間またはゾンビをランダムに挿入します。 「JailPotentialClown」ボタンを押すと、別のコインが裏返され、ゾンビか人間のどちらかを連れて行きます。 <iframe> 刑務所。

document.getElementById("jailbtn").addEventListener("click", function () { if (Math.random() > 0.5) { let human = humancamp.querySelector('postapocalyptic-person'); if (human) { clowncollege.contentDocument.querySelector('body').appendChild(document.adoptNode(human)); } else { console.log("No more potential clowns at the human camp"); } } else { let zombie = zombienest.querySelector('postapocalyptic-person'); if (zombie) { clowncollege.contentDocument.querySelector('body').appendChild(document.adoptNode(zombie)); } else { console.log("No more potential clowns at the zombie nest"); } }
});

ピエロを明らかにする adoptedCallback

adoptedCallback 対応する画像に基づいて、ピエロがゾンビの人間の種類であるかどうかを判断し、それに応じて画像を変更します。 connectedCallback その後呼び出されますが、必要なことは何もありません。また、それが行うことによって変更が妨げられることはありません。 そのままにしておくことができます。

adoptedCallback() { let image = this.shadowRoot.querySelector("img"); if (this.parentNode.dataset.type == "clowns") { if (image.src.indexOf("lady.png") != -1) { // Sometimes, the full URL path including the domain is saved in `image.src`. // Using `indexOf` allows us to skip the unnecessary bits. image.src = "ladyc.png"; this.shadowRoot.appendChild(image); } else if (image.src.indexOf("ladyz.png") != -1) { image.src = "ladyzc.png"; this.shadowRoot.appendChild(image); } }
}

で隠されたピエロを検出する attributeChangedCallback

最後に、 attributeChangedCallback。 他のXNUMXつのライフサイクルコールバックとは異なり、コールバックを起動するには、Webコンポーネントの属性を監視する必要があります。 これを行うには、 observedAttributes() 関数をカスタム要素のクラスに追加し、その関数に属性名の配列を返すようにします。

static get observedAttributes() { return [“attribute-name”];
}

次に、その属性が変更された場合(追加または削除を含む)、 attributeChangedCallback 火災。

さて、ピエロについて心配しなければならないのは、あなたが知っていて愛している人間(またはゾンビになる前にあなたが知っていて愛していた人間)の一部が密かに変装したピエロになる可能性があるということです。 人間とゾンビのグループを監視するピエロ検出器を設定しました。[ピエロを表示]ボタンをクリックすると、検出器は(完全に科学的で完全に信頼できる手段で インデックスを選択する乱数に基づく)適用 data-clown="true" コンポーネントに。 そして、この属性が適用されると、 attributeChangedCallback コンポーネントの画像を起動して更新し、色が濃い色を明らかにします。

また、 attributeChangedCallback XNUMXつのパラメータを取ります:

  • 属性の名前
  • 属性の以前の値
  • 属性の新しい値

さらに、コールバックを使用すると、属性がどれだけ変更されたか、またはXNUMXつの状態間の遷移に基づいて変更を加えることができます。

これが私たちの attributeChangedCallback コー​​ド:

attributeChangedCallback(name, oldValue, newValue) { let image = this.shadowRoot.querySelector("img"); // Ensures that `data-clown` was the attribute that changed, // that its value is true, and that it had an image in its `shadowRoot` if (name="data-clown" && this.dataset.clown && image) { // Setting and updating the counts of humans, zombies, // and clowns on the page let clowncount = document.getElementById("clown-count"), humancount = document.getElementById("human-count"), zombiecount = document.getElementById("zombie-count"); if (image.src.indexOf("lady.png") != -1) { image.src = "https://assets.codepen.io/1804713/ladyc.png"; this.shadowRoot.appendChild(image); // Update counts clowncount.innerHTML = parseInt(clowncount.textContent) + 1; humancount.innerHTML = parseInt(humancount.textContent) - 1; } else if (image.src.indexOf("ladyz.png") != -1) { image.src = "https://assets.codepen.io/1804713/ladyzc.png"; this.shadowRoot.appendChild(image); // Update counts clowncount.innerHTML = parseInt(clowncount.textContent) + 1; zombiecount.innerHTML = parseInt(zombiecount.textContent) - 1; } }
}

そして、あなたはそれを持っています! Webコンポーネントのコールバックとコンテキスト認識カスタム要素の作成が思ったよりも簡単であるだけでなく、恐ろしいものの、黙示録的なピエロの検出も思ったより簡単であることがわかりました。 これらのWebコンポーネントのコールバック関数を使用して、どのような種類の悪意のある、終末論的なピエロを検出できますか?

ソース:https://css-tricks.com/context-aware-web-components/

スポット画像

最新のインテリジェンス

スポット画像

私たちとチャット

やあ! どんな御用でしょうか?