会議に行ってWebコンポーネントのトピックに関するプレゼンテーションを見たとき、私はいつもそれがエレガントであるだけでなく、非常に難しいと思っていました。わずか4行のHTMLを格納するための数千行のJavaScript。話者は必然的に単純なものの背後に大量のJSコードを隠したり、複雑な詳細に飛び込んだりして、退屈で目を閉じ始め、毎日の手当がおやつの費用をカバーしているかどうかを考え始めました。
しかし、HTMLを簡単に学習するために作成された最近のプロジェクト(もちろん、ゾンビやばかげたジョークを追加することによって)で、仕様内のすべてのHTML要素を記述する必要があると判断しました。その会議とは別に、私は最初に紹介<slot>
と<template>
要素から始めました、そして私がプロジェクトでそれらについて何か面白いことを書きたいと思ったとき、私は主題を掘り下げなければなりませんでした。
そして、深く掘り下げていくと、Webコンポーネントが思ったよりも簡単であることに気づきました。
私が会議で間食することを夢見て以来、Webコンポーネントは長い道のりを歩んできました。あるいは、最初の恐怖が実際にそれらを知る妨げになるか、あるいはその両方です。
私はあなたを伝えるためにここにいるはい、あなたは、Webコンポーネントを作成することができます。恐れやおやつさえもドアの外に置いて、すべてをまとめましょう。
<テンプレート>から始めましょう
<template>
テンプレート(WebコンポーネントのHTML構造)を作成できるようにするHTML要素です。
コード
<template>
<p>The Zombies are coming!</p>
</template>
この要素<template>
は、すべてをまとめることができるため、非常に重要です。それはあなたの家の拠点のようなものであり、私たちが完成した建物と呼ぶすべてのものがそこから構築され始める拠点です。<apocalyptic-warning>
ゾンビの黙示録が来ることを通知するコンポーネントに、この小さなコードスニペットを使用しましょう。
次に、<slot>コンポーネントがあります
<slot>
と同じように、単なるHTML要素<template>
です。ただし、この場合、ページ<slot>
に<template>
表示する内容を構成します。
コード
<template>
<p>The <slot>Zombies</slot> are coming!</p>
</template>
"Zombies" ( ?) <template>
. , . "Zombies".
<slot>
placeholder
. placeholder
, , - placeholder
. - name
.
<template>
<p>The <slot name="whats-coming">Zombies</slot> are coming!</p>
</template>
name
- , <template>
. "whats-coming" . , -, <slot>
, - , , .
-
, , ( : JS , ).
<apocalyptic-warning>
<span slot="whats-coming">Halitosis Laden Undead Minions</span>
</apocalyptic-warning>
<template>
<p>The <slot name="whats-coming">Zombies</slot> are coming!</p>
</template>
, ? <apocalyptic-warning>
, HTML . <span>
"whats-coming". <span>
"Zombies", .
, - , HTML , . , , -.
? , ? , . , <slot>
, JavaScript.
, JavaScript , , , , . , , .
-, -. : , .
, .
// -
customElements.define("apocalyptic-warning", class extends HTMLElement {
// , HTML
// ,
constructor() {
// , . HTMLElement. HTML .
super();
// <template> `warinng`
let warning = document.getElementById("warningtemplate");
// `mywarning`
let mywarning = warning.content;
const shadowRoot = this.attachShadow({mode: "open"}).appendChild(mywarning.cloneNode(true));
}
});
, .
const shadowRoot = this.attachShadow({mode: "open"}).appendChild(mywarning.cloneNode(true));
. -, - (this) , Shadow DOM.{ mode: open }
, JavaScript :root
Shadow DOM , - . Shadow DOM ( : HTML Node). , . , Shadow DOM , <slot>
slot , .
. -, , .
JS:
customElements.define('apocalyptic-warning',
class extends HTMLElement {
constructor() {
super();
let warning = document.getElementById('warningtemplate');
let mywarning = warning.content;
const shadowRoot = this.attachShadow({mode: 'open'}).appendChild(mywarning.cloneNode(true));
}
});
HTML:
<p>The Apocalypse will never happen!</p>
<apocalyptic-warning>
<span slot="whats-coming">Undead</span>
</apocalyptic-warning>
<apocalyptic-warning>
<span slot="whats-coming">Halitosis Laden Zombie Minions</span>
</apocalyptic-warning>
<template id="warningtemplate">
<style>
p {
background-color: pink;
padding: 0.5em;
border: 1px solid red;
}
</style>
<p>The <slot name="whats-coming">Zombies</slot> are coming!</p>
</template>
: Codepen
, . , CSS. , <style>
<template>
.
<template id="warningtemplate">
<style>
p {
background-color: pink;
padding: 0.5em;
border: 1px solid red;
}
</style>
<p>The <slot name="whats-coming">Zombies</slot> are coming!</p>
</template>
, , Shadow DOM.
, , , , , Shadow DOM. , Shadow DOM DOM , . - , DOM .
, , <style>,
<slot>
. , . - , CSS , , . , -, CSS.
apocalyptic-warning span {
color: blue;
}
, CSS <template>
.
JavaScript , , , , <zombie-profile>.
customElements.define("zombie-profile",
class extends HTMLElement {
constructor() {
super();
let profile = document.getElementById("zprofiletemplate");
let myprofile = profile.content;
const shadowRoot = this.attachShadow({mode: "open"}).appendChild(myprofile.cloneNode(true));
}
}
);
HTML CSS.
<template id="zprofiletemplate">
<style>
img {
width: 100%;
max-width: 300px;
height: auto;
margin: 0 1em 0 0;
}
h2 {
font-size: 3em;
margin: 0 0 0.25em 0;
line-height: 0.8;
}
h3 {
margin: 0.5em 0 0 0;
font-weight: normal;
}
.age, .infection-date {
display: block;
}
span {
line-height: 1.4;
}
.label {
color: #555;
}
li, ul {
display: inline;
padding: 0;
}
li::after {
content: ', ';
}
li:last-child::after {
content: '';
}
li:last-child::before {
content: ' and ';
}
</style>
<div class="profilepic">
<slot name="profile-image"><img src="https://assets.codepen.io/1804713/default.png" alt=""></slot>
</div>
<div class="info">
<h2><slot name="zombie-name" part="zname">Zombie Bob</slot></h2>
<span class="age"><span class="label">Age:</span> <slot name="z-age">37</slot></span>
<span class="infection-date"><span class="label">Infection Date:</span> <slot name="idate">September 12, 2025</slot></span>
<div class="interests">
<span class="label">Interests: </span>
<slot name="z-interests">
<ul>
<li>Long Walks on Beach</li>
<li>brains</li>
<li>defeating humanity</li>
</ul>
</slot>
</div>
<span class="z-statement"><span class="label">Apocalyptic Statement: </span> <slot name="statement">Moooooooan!</slot></span>
</div>
</template>
CSS <zombie-profile>
CSS. , , , <template>
.
zombie-profile {
width: calc(50% - 1em);
border: 1px solid red;
padding: 1em;
margin-bottom: 2em;
display: grid;
grid-template-columns: 2fr 4fr;
column-gap: 20px;
}
zombie-profile img {
width: 100%;
max-width: 300px;
height: auto;
margin: 0 1em 0 0;
}
zombie-profile li, zombie-profile ul {
display: inline;
padding: 0;
}
zombie-profile li::after {
content: ', ';
}
zombie-profile li:last-child::after {
content: '';
}
zombie-profile li:last-child::before {
content: ' and ';
}
:
: Codepen
, , , -, . , , - , , .
それで全部です。あなたは今、何をもっと恐れていますか:ウェブコンポーネントまたはゾンビの黙示録?それほど遠くない過去には、Webコンポーネントと言っていたかもしれませんが、今ではゾンビだけが私を心配しています(まあ、そして私の日当は軽食の費用をカバーします)。