Skip to content

Instantly share code, notes, and snippets.

@denvernine
Last active December 23, 2021 11:27
Show Gist options
  • Save denvernine/74d9de970c3402bb1618b9d47ff0f4a3 to your computer and use it in GitHub Desktop.
Save denvernine/74d9de970c3402bb1618b9d47ff0f4a3 to your computer and use it in GitHub Desktop.
Web Components を使ったwebページの作成

Web Componentsを使ったwebページの作成

静的サイトジェネレータやアプリケーションフレームワークでは、webページを作成する際にテンプレートと内容を分けることができることがほとんどです。Web Componentsという技術を使うことで、アプリケーションフレームワークなどを使用せずに、同様のことが可能です。

Live Sample

カスタム要素を定義する

<template> を使用してカスタム要素の内容を定義します。これを行うことで要素の再利用が可能になります。 <slot> を使用して外部から値を与えることもできます。

<template id="custom-element-template">
  <p><slot name="custom-element-text">default text</slot></p>
  <button>this is button</button>
</template>

カスタム要素を登録する

WebAPIを使用してカスタム要素を登録します。

customElements.define('custom-element', class extends HTMLElement {
  constructor() {
    super();

    const customElement = document.querySelector('#custom-element-template').content;

    if (this.hasAttribute('text')) {
      customElement.textContent = this.getAttribute('text');
    }

    const shadowRoot = this.attachShadow({mode: 'open'}).appendChild(customElement.cloneNode(true));
  };
});

カスタム要素を表示する

カスタム要素を表示します。入れ子にする場合、 <slot> を使用しない要素は表示されません。

<custom-element>
  <span slot="custom-element-text">this is custom element</span>
  <span>this is not display</span>
</custom-element>
<!doctype html>
<html lang="ja" dir="ltr">
<head>
<meta charset="UTF-8">
<title>web component test</title>
</head>
<body>
<custom-element>
<span slot="custom-element-text">this is custom element</span>
<span>this is not display</span>
</custom-element>
<div>
<a id="showA">show A</a> | <a id="showB">show B</a>
</div>
<custom-element id="A" text="this is A" style="display: none;"></custom-element>
<custom-element id="B" text="this is B" style="display: none;"></custom-element>
<template id="custom-element-template">
<p><slot name="custom-element-text">default text</slot></p>
<button>this is button</button>
</template>
<script>
(function() {
customElements.define('custom-element', class extends HTMLElement {
constructor() {
super();
const customElement = document.querySelector('#custom-element-template').content;
if (this.hasAttribute('text')) {
customElement.textContent = this.getAttribute('text');
}
const shadowRoot = this.attachShadow({mode: 'open'}).appendChild(customElement.cloneNode(true));
};
});
})();
const hidden = function(element) {
document.querySelectorAll(element).forEach(function(element) {
element.style.display = 'none';
});
};
const show = function(element) {
document.querySelector(element).style.display = 'block';
};
document.querySelector('#showA').onclick = function() {
hidden('custom-element[id]');
show('#A');
};
document.querySelector('#showB').onclick = function() {
hidden('custom-element[id]');
show('#B');
};
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment