Javascriptで外部ドキュメントを参照する手法

何となく、Javascriptで外部のHTMLドキュメントを参照して、現在のHTMLドキュメント上に外部ドキュメントから取得した要素を配置する手法を考えてみた。まぁ多分、既に何処かで同様の手法はあるんだろうけど、一応思いついたことを簡単にメモということで。

目的
外部のHTMLドキュメントを参照して、現在のHTMLドキュメント上に外部ドキュメントから取得した要素を配置する。
用途
解説サイトを構築する際、用語集等を外部に配置してそこから用語解説を読み込む事で、管理をしやすくすることが事ができる。また、複数のページで同じ解説を載せることができる。
課題
外部ドキュメントを参照するためには、そのドキュメントを完全に読み込む必要がある。また、普段はそれを表示させず、必要に応じて適切な要素を表示させる必要がある。
手法

まず、外部ドキュメントを読み込む必要がある。画像ファイルならばあらかじめ表示させる事なく読み込んでおくことができるが、JavascriptにおいてHTMLファイルで同様のことを行うメソッド等は無い(と思う、多分。あったらこの文章の8割ぐらい無駄)。JavascriptでHTMLドキュメントを読み込むためには、window.open メソッドが考えられるが、これでは新たなウィンドウが開いてしまうので適当ではない。そこで、新たなウィンドウを開かずにドキュメントを読み込ませるために、インラインフレーム(Iframe要素)を利用する。

まず、スタイルを

visibility: hidden; (透明化)
position: absolute; (絶対配置, IEが未対応のfixedは不適当)

とした、視認できないインラインフレーム(Iframe要素)を配置、あるいはJavascriptによって追加する。そこに外部ドキュメントを読み込ませる。
フレームオブジェクトの contentDocument プロパティによって、インラインフレーム内のドキュメントオブジェクトが取得できる。あとはノードを分解して、必要なデータを適宜取得するか、メモリに保持してそこから参照するようにし、外部ドキュメントを破棄すれば良い。

注意点・備考
  • IEではインラインフレームの中身を、現在のドキュメント上の要素を全て読み込んだ後に呼び出すようなので、script要素をiframe要素の後やbody要素内の末尾に配置すると、インラインフレーム内の要素を取得できない。そのため、body要素のonloadイベントから実行するのが適当。
  • Opera7だと contentWindow プロパティが使えない、ここでは contentDocument プロパティを利用したが、どちらの方が正しいのか…。Safariとかどうなっているのかさっぱり分からない。
  • mozilla系だとwindow.[inlineframe].document…とすることでインラインフレーム内のドキュメントを取得できるが、IEだと上手くいかなかった。
  • Javascript未サポート/未使用ブラウザのために、HTMLには外部ドキュメントの内容を表示させる場所にリンクを張っておき、Javascriptからその要素を置き換えてしまうのが望ましい。
  • 外部ファイルを読み込むため、読み込みデータが多くなってしまう。そのため、外部ドキュメントは分割するか、できるだけ小さくするべき。
問題点
  • XHTML1.1では、iframe要素は仕様から廃止されてしまうので、現状でiframe要素を使うのは不適当。なるべくobject要素を利用するのが望ましいが、object要素から呼び出したドキュメントのドキュメントオブジェクトを取得する場合、、IEではcontentDocumentが使えないので取得方法が分からない。

実際少しだけ作ってみたところ、一応何とか物にはなりそうに思えた。ただ、ブラウザに結構依存する可能性があるため、解説サイトのような多数の人間に利用されるサイトへの適用には慎重を期すべきか。

追記

pera7だとcontentWindowプロパティが使えず、IE6だとcontentDocumentが使えない。この場合、ドキュメントオブジェクトは
doc = (frame.contentDocument)||(frame.contentWindow)
とすると両方で取れる。しかしここで気を付けるのは、contentDocumentプロパティの方を先に書く事。でないとOperaでエラーが出る。

12:17追記

今思いついた。インラインフレームで呼び出すドキュメント上でJavascriptを実行し、グローバル変数を使って値を渡してやれば、何も contentDocument / contentWindow プロパティを使う必要は無いんじゃなかろうか。それどころか、これならiframe要素ではなく、object要素で実現できるし、互換性問題もかなり緩和される。
今は作れる状態ではないけど、後で実際に作ってみることにしよう。

20:07

グローバル変数はダメだった。スクリプトの有効範囲はドキュメントのみで、フレームにまたがることはできないということを、今初めて知った。フレームなんぞ使わないから、そんな事知らんかったよ…。
そうなると、完全に contentDocument / contentWindow が頼みの綱か。

18日 23:56

不完全ながらも、実際に作ってみた。

Melog: Archives > Archive – 外部ファイルの要素をポップアップするスクリプト


Posted by:

Posted At:

Modified At:

コメント

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください