Join MDN and developers like you at Mozilla's View Source conference, 12-14 September in Berlin, Germany. Learn more at https://viewsourceconf.org

Binding Attachment and Detachment

CSS を使った取り付け

バインディングは -moz-binding プロパティを使って CSS を通して要素に結びつけることができます。

-moz-binding
値: none | [<uri>,]</uri>* <uri> | inherit
初期値: none
適用先: すべての要素 (生成された内容と疑似要素は除く)
継承: なし
パーセンテージ: 適用不可

-moz-binding プロパティの値は特定のバインディングを一意に識別する URL のセットです。セットの中の個々の URL はバインディングのドキュメント URL とバインディングのドキュメントで固有の識別子から成っています。

以下の例では、バインディングはすべての HTML checkbox (チェックボックス) 要素に結びつけられいるものに参照されています。

input[type="checkbox"] {
  -moz-binding: url("http://www.mozilla.org/xbl/htmlBindings.xml#checkbox");
}

CSS によって結びついたバインディングは要素がスタイルルールに合致しつづけている限り、バウンド要素上に残るでしょう。バウンド要素のスタイルが他のバインディングを結びつけると決定した場合、いつでも元のバインディング (とその継承のつながりで明示的に拡張されるすべてのバインディング) は分離されます。

スタイルルールにマッチする要素にはバインディングは結びつけられませんが、display:none スタイルが設定されている要素内には結びつけられます。バグ 307098 を参照してください。

要素がドキュメントから取り除かれたときはいつでも、ドキュメントに読み込まれた CSS を通して結びつけられたどのバインディングも分離されるでしょう。

element.style プロパティを使った取り付け

バインディングは、element.style.MozBinding プロパティを適用するスクリプトを通じて要素に取り付けられます。それぞれのバインディングは、element.style.MozBinding を空文字列に設定することで取り外しできます。

注: 古い資料に書かれている document.addBindingdocument.removeBinding という DOM メソッドは不要として破棄され、現在は実装されていません。

var checkbox = document.getElementById("mycheckbox");
checkbox.style.MozBinding =
 "url(http://www.mozilla.org/xbl/htmlBindings.xml#checkbox)";       

この結びつけは必ずしも同期化されません。このメソッドを呼び出すスクリプトは、メソッドから返った直後にはバインディングが設定されていると仮定すべきではありません。 詳細は バインディングドキュメント を参照。

バインディングが DOM を使って結びつけられるとき、それはすでに要素に結びつけられているだろう現在もっとも派生が直近のバインディングから継承します。要素に結びつけられたどのバインディングも、要素が破棄されるか対応するスタイルルールが削除されるまで要素上に残るでしょう。

バインディングが結びつけられ、そのバインディングが既に extends 属性によって派生バインディングを定義していたなら、継承のつながりの最後の基底バインディングはすでに結びつけられたもっとも派生が直近のバインディングから継承したものになります。

例を挙げてみます。以下の明示的継承のつながりをもつ d1 を考えてみましょう。

d1 -> d2 -> d3

element.style.MozBinding を使ってこの要素がすでに次の継承のつながりをもっている要素と結びつけたとすると、

s1 -> s2 -> s3

このバインディング付加の結果としてできるバインディングのつながりは、

d1 -> d2 -> d3 -> s1 -> s2 -> s3

「d3」と「s1」の間の継承は「暗黙」で、2 つのバインディングの間の XBL ドキュメントに何のつながりもありません。継承のリンクは element.style.MozBinding の呼び出しを通して動的に形作られます。

<constructor> の呼び出し

ドキュメントが呼び出され、スタイルのルールが要素に一致すると、遭遇したどのバインディングドキュメントも必要に応じて読み込まれます。バインディングドキュメントの読み込みが完了するまではバウンドドキュメントでは DOM の load イベントが発生しません。 load イベントが発生したとき、もしすべてのバインディングドキュメントの読み込みが成功したなら、すべてのバインディングはすべての要素に結びつけられたと仮定することができます。 load イベントが発生する間もしくは後に生成された要素については、バインディングの結びつけの順序についてどんな仮定もできません。

バインディングが結びつけられると、以下のイベントが発生します。

  • 必要なら、無名コンテントがバインディングのコンテントテンプレートから複製され、バウンド要素に挿入されます。
  • バインディングのメソッドとプロパティは要素上にインストールされ、バウンド要素を参照するスクリプトから利用可能になります。
  • 定義したイベントハンドラはすべてその指定対象上に設定されます。

もし、バインディングが要素への結びつけに続いて初期化コードの実行を必要とするなら、<implementation> セクション内の <constructor>ブロックを使ってそれを行うことができます。このブロックはバインディングの結びつけの完了の後に実行されるスクリプトを含みます。このブロック内では this はバウンド要素を参照します。

<destructor> の呼び出し

CSS を通して結びつけられたバインディングは、以下のどれかの条件を満たすとき、切り離されます。

  • 異なるバインディングで定義されたスタイルルールにバウンド要素が一致したとき
  • 要素がバウンド要素から取り除かれたとき
  • (例えば、ドキュメントを閉じるなどして) 要素が破棄されたとき

DOM を通して結びつけられたバインディングは、以下のどれかの条件を満たすとき、切り離されます。

  • MozBinding スタイルルールが削除されたとき
  • (例えば、ドキュメントを閉じるなどして) 要素が破棄されたとき

バインディングが切り離されると、以下のイベントが発生します。

  • バインディングによって生成された無名コンテントは破棄されます。
  • getters/setters をともなうメソッドとプロパティはバインディングからもはやアクセスできません。たとえ、生値をともなうプロパティが残っていてもです。
  • どの定義されたイベントハンドラも、それぞれの対象から外されます。

バインディングは、バインディング分離に先立って実行される、<implementation> セクション内の <destructor> ブロックを定義することができます。バインディングは分解されるより前に、<destructor> ブロックを使って、必要なクリーンアップをすることができます。

継承のつながりのなかのバインディングは必ず、もっとも派生したバインディングから基礎のバインディングへと切り離されます。そのため、派生バインディングの <destructor> ブロックは、実行され、基礎のバインディングのハンドラも実行されます。

スタイルを通して結びつけられたバインディングがスタイルの変更によって切り離されるとき、DOM を使って結びつけられたほかのバインディングへは何の影響も及ぼしません。それらのバインディングはインストールされたままでしょう。もし、新しいバインディングが CSS を通して結びつけられたとき、継承のつながりのなかの DOM バインディングの後ろにインストールされます。

例を挙げてみます。以下のバインディングのつながりをつもなうバウンド要素を考えましょう。

d1 -> d2 -> d3 -> s1 -> s2 -> s3

これは CSS を通して結びつけられたバインディングを表している「s1」をともないます。バウンド要素上のスタイルの意図が新しいバインディング「t」が結びつけられるべきだという決定をすると、以下のバインディングのつながりは切り離されます。

s1 -> s2 -> s3

そして、新しいバインディングが結びつけられます。最後の継承のつながりは、

d1 -> d2 -> d3 -> t

バインディングが element.style.MozBinding を使って切り離されるとき、バインディング上の extends 属性を通して結びつけられたどの基礎バインディングもまた取り除かれます。つまり、element.style.MozBinding を削除すると、もともとの element.style.MozBinding = "url(...)" 呼び出しを通してインストールされたバインディングの同じグループも削除されるということです。

この切り離しのルールは以下のようにまとめられます。バインディングが切り離されるときはいつでも、そのバインディングが明示的に継承しているバインディングもすべて切り離されます。

バインディングドキュメント

バインディングがほかのドキュメントの要素に結びつけられるときはいつでも、バインディングドキュメントがバウンドドキュメントではまだ使われていない場合に限って、バインディングドキュメントはフェッチされます。新しいバウンドドキュメントは使われているバインディングドキュメントごとに分けられたそれぞれの固有のコピーを持っています。

バインディングドキュメント URL の等しいバインディングを 1 つのバウンドドキュメント中で使用していれば、それらは全て同じバインディングドキュメントを共有します。そのため、もしつながりのなかのすべてのバインディングがバウンドドキュメントにすでに読み込まれているバインディングドキュメントからもたらされたのであれば、バインディングの結びつけは (バインディングが CSS によるものでも DOM によるものでも) 同期されることが保証されます。

必要な任意の XBL ドキュメントをプリフェッチするために loadBindingDocument を呼ぶことで全てのバインディングが確実に同期して付加されるようにできます。バインディングドキュメントが load イベントが発生する前に読み込まれている場合、読み込み後に行われる全てのバインディング付加は読み込み済みバインディングドキュメント中のバインディングによるものであれば同期されます。

loadBindingDocument によって得られるドキュメントはバウンドドキュメントに固有のバインディングドキュメントの複製です。バインディングドキュメントの中のバインディングは標準 DOM API を使って変更することができます。バウンドドキュメントの要素上で発生したバインディングドキュメントの中のバインディングに対する結果としてのどのバインディング付加も修正された複製を使います。ですから、新たなバインディングの定義を動的に生成したり、バインディングの無名コンテントテンプレートを作り替えて、バウンドドキュメントで使用することができます。

ドキュメントのタグと貢献者

タグ: 
 このページの貢献者: kohei.yoshino
 最終更新者: kohei.yoshino,