LoginSignup
14
13

More than 5 years have passed since last update.

Web ComponentsをHTML Importsでロードする必要性

Last updated at Posted at 2014-08-29

慣例的に<link rel="import" href="x-element.html">な感じでロードされているけど、前提として、 HTMLImportsである必要はない 。何故ならば、Web Componentsを構成する4つの仕様はそれぞれ独立しているからである。だから、インポートを使わなくてもdocument.registerElement()でカスタム要素の定義は出来るし、HTMLのひな形を使いたい場合に<template>タグを使っても良い。

HTMLを部品として含む場合

HTMLやCSSを部品として含む場合は、<template>タグや、ShadowDOMを駆使しながらパーツを構成していくので、HTMLファイルに書かざるを得ない。もちろん、JavaScriptだけで書けないこともないんだけど、本質ではない。

先日画像をスクロール同期的にロードする要素、 1000ch/lazyload-image を作ったけど、こちらはHTMLファイルではなく、単一のJSファイル。GitHubが作っている github/time-elements なんかも、time-elements.jsだけで構成されているけど、こういう場合は<link rel="import" href="x-element.html">ではなく、<script src="x-element.js"></script>で事が足りる。

他のWeb Componentsに依存している場合

<x-element><y-element>に依存している場合は以下のように、x-element.html内でy-element.htmlをインポートする。

x-element.html
<link rel="import" href="y-element">
<template id="tmpl">
  <div>This is x-element!</div>
</template>
<script>
  var XElementPrototype = Object.create(HTMLElement.prototype);
  XElementPrototype.createdCallback = function () {
    console.log(document.querySelector('#tmpl'));
  };
  window.XElement = document.registerElement('x-element', {
    prototype: XElementPrototype
  });
</script>

そのコンポーネントからの相対パスを得たい

これは @hokaccha 氏が詳しく書いているが、Web Componentsとして配布するときに、画像等のサブリソースを含む場合は一工夫が必要になる。

例えば<x-element>というカスタムエレメントが以下のように、imgフォルダの配下にfoo.pngbar.pngを含んだ構成とする。

  • x-element
    • x-element.html
    • img
      • foo.png
      • bar.png

bowerなんかでインストールされればx-elementというフォルダごとダウンロードされて、いざインポートするときには<link rel="import" href="bower_components/x-element/x-element.html">のようになる。

このとき、foo.pngbar.pngを含むフォルダはbower_components/x-element/imgというパスになるけど、x-element.html側で素直にimg/foo.pngと参照していると、インポート元のドキュメントルートからそのパスを辿ることになるので、上手く参照出来ない。

だからdocument.baseURIを使って相対パスを得たいということになるが、この場合に、HTMLファイルでないとdocument.currentScript.ownerDocument.baseURIと、x-element.htmlからみたベースのURLを辿れない。URLオブジェクトと組み合わせるとアレコレするときに幾分スマートかも。

x-element.html
<script>
  var doc = document.currentScript.ownerDocument;
  var imgRoot = new URL('img', doc.baseURI);

  console.log(imgRoot.href);
  // => bower_components/x-element/img
</script>

ネタに走った感あるけど、 https://github.com/1000ch/x-zangief は上記のようなパス解決をしている。

14
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
13