JavaScript プログラミング講座

 

カスタム要素について

 


■カスタム要素について

 
カスタム要素は、Web Components 関連の機能です。
 
http://www.w3.org/TR/custom-elements/ (Working Draft)
 
カスタム要素を使用すると、既存の要素を拡張して、独自の要素とする事ができます。
 
カスタム要素を使用するには、ドキュメントに登録処理を行う必要があります。
 


 

カスタム要素を登録する

 


■カスタム要素を登録する

 
ドキュメントにカスタム要素を登録するには、document.registerElement() メソッドを使用します。
 
document.registerElement( "カスタム要素タイプ名" , ElementRegistrationOptions ) :Function
第01引数 String好きなカスタム要素タイプ名を指定。
第02引数(略可)ElementRegistrationOptionsElementRegistrationOptions オブジェクトを指定。
戻り値 Functionカスタム要素コンストラクタオブジェクトが得られる。
 
■登録例
 
<IMG> 要素を拡張した、カスタム要素を登録する

// ------------------------------------------------------------
// ElementRegistrationOptions オブジェクトを用意する
// ------------------------------------------------------------
var elemen_tregistration_options = {

	// カスタム要素のプロトタイプ
	prototype: null,

	// 派生元の要素名
	extends: "img"
};

// ------------------------------------------------------------
// ドキュメントにカスタム要素を登録する
// ------------------------------------------------------------
var custom_element_constructor = document.registerElement( "x-my-element" , elemen_tregistration_options );
 

■カスタム要素タイプについて

 
タイプ名には、ハイフン "-" を含める必要があります。(最先頭は不可)
 
また、大文字を指定する事はできません。
 

■ElementRegistrationOptions オブジェクトについて

 
オブジェクトを作成し、以下のプロパティを含めます。
 
プロパティ名説明
prototypeObjectカスタム要素のプロトタイプとなるオブジェクトを指定する。
extendsStringカスタム要素の派生元となる、既存の要素名を指定する。
 

■カスタム要素プロトタイプについて

 
プロトタイプについては、こちらで解説しています。
 
■カスタム要素プロトタイプを作成する
 
Object.create() メソッドを使ってオブジェクトを作成します。
 
引数には、派生元 DOM コンストラクタが所持している、プロトタイプを指定します。
 
<IMG> 要素を基礎とした、カスタム要素プロトタイプを作成する

// カスタム要素プロトタイプを作成する
var custom_element_prototype = Object.create(HTMLImageElement.prototype);

// カスタム要素プロトタイプを作成する
var custom_element_prototype = Object.create(document.createElement("img").constructor.prototype);
 
■カスタム要素の初期化処理について
 
本格的なカスタマイズは、ライフサイクルコールバック内で行います。
 


 

カスタム要素を生成する

 
 


■カスタム要素を静的に配置する

 
■既存の要素をカスタム要素と関連付ける
 
静的な要素を、カスタム要素と関連付けるには、is 属性を使用します。
 
is 属性には、カスタム要素タイプを記述します。
 
タグ名とタイプ名は、完全一致している必要があります。
 
■使用例
 
静的にカスタム要素を配置する

<html>
  <body>

    <img is="x-my-element" id="aaa" > <br>
    <img is="x-my-element" id="bbb" > <br>
    <img is="x-my-element" id="ccc" > <br>

    <script type="text/javascript">
    <!--

	// ------------------------------------------------------------
	// ドキュメントにカスタム要素を登録する
	// ------------------------------------------------------------
	document.registerElement( "x-my-element" , { extends: "img" } );

	// ------------------------------------------------------------
	// "aaa" という ID 属性のエレメントを取得する
	// ------------------------------------------------------------
	var my_element = document.getElementById("aaa");

	// 出力テスト
	console.log(my_element);

    //-->
    </script>

  </body>
</html>
 

■カスタム要素を動的に生成する

 
カスタム要素を動的に生成するには、document.createElement() メソッドを使用します。
 
タグ名とタイプ名は、完全一致している必要があります。
 
document.createElement( "要素名" , "カスタム要素タイプ名" ) :Element
第01引数 Stringタグ名を指定。
第02引数 Stringカスタム要素タイプ名を指定。
戻り値 Elementカスタム要素が得られる。
 
■使用例
 
<IMG> 要素を拡張した、カスタム要素を生成する

// ------------------------------------------------------------
// ドキュメントにカスタム要素を登録する
// ------------------------------------------------------------
document.registerElement( "x-my-element" , { extends: "img" } );

// ------------------------------------------------------------
// カスタム要素を生成する
// ------------------------------------------------------------
var my_element = document.createElement("img" , "x-my-element");

// 出力テスト
console.log(my_element);

// ------------------------------------------------------------
// BODY 要素のノードリストに登録する
// ------------------------------------------------------------
document.body.appendChild(my_element);
 

■カスタム要素コンストラクタを実体化する

 
document.registerElement() メソッドの戻り値から、カスタム要素コンストラクタが得られます。
 
カスタム要素コンストラクタは、new 演算子を使って、インスタンス化する事ができます。
 
■使用例
 
カスタム要素コンストラクタを使って、カスタム要素を作成する

// ------------------------------------------------------------
// ドキュメントにカスタム要素を登録し、コンストラクタを取得する
// ------------------------------------------------------------
var MyElement = document.registerElement( "x-my-element" , { extends: "img" } );

// ------------------------------------------------------------
// カスタム要素を作成する
// ------------------------------------------------------------
var my_element = new MyElement();

// 出力テスト
console.log(my_element);

// ------------------------------------------------------------
// BODY 要素のノードリストに登録する
// ------------------------------------------------------------
document.body.appendChild(my_element);
 


 

ライフサイクルコールバックについて

 


■ライフサイクルコールバックについて

 
■コールバックの一覧
 
カスタム要素プロトタイプに、以下のプロパティを追加し、関数をセットします。
 
プロパティ名説明
createdCallbackFunctionカスタム要素が作成されると呼び出される。
attachedCallbackFunctionカスタム要素がノードリストに登録されると呼び出される。
detachedCallbackFunctionカスタム要素がノードリストから除外されると呼び出される。
attributeChangedCallbackFunction属性が変化すると呼び出される。
 
■コールバック関数内から、カスタム要素を取得する
 
this キーワードを使用します。
 
■使用例
 
ライフサイクルコールバックの動作確認

// ------------------------------------------------------------
// ElementRegistrationOptions オブジェクトを用意する
// ------------------------------------------------------------
var elemen_tregistration_options = {

	// ------------------------------------------------------------
	// カスタム要素のプロトタイプ
	// ------------------------------------------------------------
	prototype: (function(){

		// ------------------------------------------------------------
		// プロトタイプを作成
		// ------------------------------------------------------------
		var self = Object.create(document.createElement("img").constructor.prototype);

		// ------------------------------------------------------------
		// カスタム要素が作成されると呼び出される
		// ------------------------------------------------------------
		self.createdCallback = function (){

			// ------------------------------------------------------------
			// カスタム要素を取得する
			// ------------------------------------------------------------
			var _this = this;

			// ------------------------------------------------------------
			// 初期化処理
			// ------------------------------------------------------------
			_this.aaa = "aaa";
			_this.bbb = "bbb";
			_this.ccc = "ccc";

			// ------------------------------------------------------------
			// 出力テスト
			// ------------------------------------------------------------
			console.log("created");
			console.log(this);
		};

		// ------------------------------------------------------------
		// カスタム要素がノードリストに登録されると呼び出される
		// ------------------------------------------------------------
		self.attachedCallback = function (){
			console.log("attached");
			console.log(this);
		};

		// ------------------------------------------------------------
		// カスタム要素がノードリストから除外されると呼び出される
		// ------------------------------------------------------------
		self.detachedCallback = function (){
			console.log("detached");
			console.log(this);
		};

		// ------------------------------------------------------------
		// 属性が変化すると呼び出される
		// ------------------------------------------------------------
		self.attributeChangedCallback = function (name , value_old , value_new){
			console.log("attributeChanged");
			console.log(this);
			console.log(arguments);
		};

		return self;
	})(),

	// ------------------------------------------------------------
	// 派生元の要素名
	// ------------------------------------------------------------
	extends: "img"
};

// ------------------------------------------------------------
// ドキュメントにカスタム要素を登録する
// ------------------------------------------------------------
var MyElement = document.registerElement( "x-my-element" , elemen_tregistration_options );

// ------------------------------------------------------------
// カスタム要素を作成する
// ------------------------------------------------------------
var my_element0 = new MyElement();
var my_element1 = new MyElement();

// ------------------------------------------------------------
// BODY 要素のノードリストに登録する
// ------------------------------------------------------------
document.body.appendChild(my_element0);
document.body.appendChild(my_element1);

// ------------------------------------------------------------
// BODY 要素のノードリストから除外する
// ------------------------------------------------------------
document.body.removeChild(my_element0);
document.body.removeChild(my_element1);

// ------------------------------------------------------------
// 属性値を変更する
// ------------------------------------------------------------
my_element0.setAttribute("my_name" , "my_value0");
my_element0.setAttribute("my_name" , "my_value1");
my_element0.removeAttribute("my_name");