はじめに
私は研究や仕事でWeb Componentsに関する技術を使っているわけではなく、プロではないのですが「とりあえず使ってみたい!」と思って使ってみました。
本記事は「技術的なことは追々わかるとして、とりあえず動くものを作りたい!」という人向けです。
日本語で結構、技術的なことを分かりやすくまとめてくださっている記事は 初心者向けWebComponentsまとめ にあります。「初心者向けWebComponentsまとめ」ではライフサイクルなどにも触れていますが、 本記事はHTML5のタグをペタペタ貼って、一つのElementを作ってみよう! というものです。
Qiitaに、この先書き続けるか分からないので、自分のウェブサイト にも同じ内容を書いています。こちらは、これからWebcomponentsについての知識が増えれば、随時更新しまとめていきますので、よければ参照してください。逆に言えば、この記事は誤植や誤りの訂正以外は書きっぱなしになります。
用意するファイル
用意するファイルは以下の2つです。適当なディレクトリに適当なディレクトリ(今回はwebcomponentsにしています)を作成してください。
Custom Elementは全てjavascriptで記述します。その記述されたCustom ElementをHTMLファイルで利用するという流れです。
webcomponents/
|- index.html
|- example-template.js
コードと解説
それぞれのファイルとコードについて解説をします。
HTMLファイルで重要なのは、Custom Elementを引っ張ってくるときに'defer'を入れないと、正しく動かないことです。javascriptを参照するときに、必ず入れましょう。
<!DOCTYPE html>
<html lang='en'>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
<script type="text/javascript" src="./example-template.js" defer></script> <!-- Custom Elementを引っ張ってくる "defer" を書かないと動かない -->
<title>custom elements example</title>
</head>
<body>
<!-- Custom Elementの利用。nameTitleとplaceHolderは作成した新しい属性(Attribute) -->
<example-template nameTitle="Text form" placeHolder="Please type your name"></example-template>
<example-template nameTitle="Text form2" placeHolder="複数elementを使っても、きちんと別々に文字が入る。"></example-template>
</body>
</html>
class ExampleTemplate extends HTMLElement {
constructor() {
// superは必ず一番最初に呼び出される。
super();
// これより下にCustom Elementに関する記述を行う
//shadow rootの作成。これが今回の一番上のノード(ルート)
const shadow = this.attachShadow({ mode: 'open' });
// 今回はひとまとまりをsectionで包む
const wrapper = document.createElement('section');
//* Sectionの下に並べるElementsの情報を入れていく *//
// h2タグ(タイトル)
const subtitle = document.createElement('h2');
const titleSub = this.getAttribute('nameTitle'); // nameTitleというAttributeの値を取得
subtitle.textContent = titleSub; // nameTitleの値をh2タグで表示
// form & input (テキストフィールド)
const formF = document.createElement('form');
const textField = document.createElement('input');
textField.setAttribute('type', 'text'); // inputのtype指定
textField.setAttribute('class', 'textField'); // classをtextFieldに
const contents = this.getAttribute('placeHolder'); // placeHolderというAttributeの値を取得
textField.setAttribute('placeholder', contents); // input(type=text)のplaceholderにplaceHolderの値を代入
formF.appendChild(textField); // formの下にtextFieldをネストする
// Shadow domにCSSを適用する
const style = document.createElement('style');
console.log(style.isConnected);
style.textContent = `
.textField {
width: 500px;
height: 300px;
}
`; //今回はtextFieldの幅と高さを指定した。
// shadow domを一番上にして、上で作ったものをネストしていく
// shadow |- style
// |- wrapper |- subtitle
// |- formF
shadow.appendChild(style);
shadow.appendChild(wrapper);
wrapper.appendChild(subtitle);
wrapper.appendChild(formF);
}
}
// 新しいElementの定義
customElements.define('example-template', ExampleTemplate);
実際に表示される画面
まとめ
- HTMLとjavascriptでCustom Elementを作った
- 同じelementの同じ属性に異なる入力を入れたところ、表示はきちんと異なるそれぞれの入力値が表示された
問合せ
間違えや「ここ、こうした方がいいよ!」という意見や「詳しく聞きたい!」ということがありましたら、以下のメールアドレスまたは本記事にコメントをお願いします。
akira.kashihara@hotmail.com