日々のコンピュータ情報の集積と整理

Dr.ウーパのコンピュータ備忘録

2015年3月4日水曜日

JavaScript:iframe:外部のページを埋め込むのではなく、HTMLをそのまま埋め込みたい

イントロダクション

HTML の iframe タグを使用すると、ある HTML 文書の中に、別の HTML 文書を埋め込むことができます。



通常、iframe タグを使って別の HTML 文書を埋め込む場合には、src 属性に外部の HTML 文書の URL を記載し、外部の HTML 文書を埋め込みます。


そのような目的であれば特にこれ以降のこの文章を読む必要は無いのですが、場合によっては外部の HTML 文書を埋め込むのではなく、HTML 文書をそのまま埋め込みたい場合があります。

想定する用途としては、次のケースが挙げられます。
  • グローバルな変数・オブジェクト・関数などを多用するような JavaScript コードを埋め込みたいが、それらのグローバルな変数・オブジェクト・関数などによって、埋め込み元のページに影響を与えたくないケース(グローバル領域の汚染を防ぐ)
  • 埋め込み元のスタイルシートなどの影響を与えたくない情報を表示するケース(ブラウザ標準のスタイルシートを適用したいケース)


さて、そのような外部の HTML 文書ではなく、HTML 文書をそのまま埋め込みたい場合には、どうしたらよいでしょうか?

iframe タグの間に、埋め込みたい HTML 文書を書いたら実現できそうですが、残念ながらその方法では実現できません。

iframe タグの間には、埋め込む HTML 文書を書くのではなく、iframe 非対応のブラウザに向けたメッセージを記載します。

<iframe> - インラインフレーム
http://www.tohoho-web.com/html/iframe.htm


iframe に HTML 文書をそのまま埋め込む方法


srcdoc 属性

iframe に HTML 文書をそのまま埋め込むには、iframe タグの srcdoc 属性に HTML 文書を埋め込みます。

ただし、この srcdoc 属性は最近採用された属性であり、まだ対応していないブラウザもあります。現在の対応状況は、以下のページの「ブラウザ実装状況」にデスクトップブラウザ・モバイルブラウザともに記載があります。

iframe 要素 - HTML | MDN


特に、まだデスクトップブラウザでは、多くのシェアを持っている Internet Explorer では、現時点の最新のバージョン{Internet Explorer 9(9.0.8112.16421) , Internet Explorer 11(11.0.9600.17501)} でも、srcdoc 属性が対応していないことを確認しました。

ソースコード解説:スタイル付きテキストを、コピーでブログに張り付け - Dr.ウーパのコンピュータ備忘録
http://upa-pc.blogspot.jp/2015/02/explain-css-copy-to-blog-v1.0.html


そのため、srcdoc 属性による HTML 文書の埋め込みのみで、iframe タグへの外部のページではない HTML 文書を埋め込むには、まだ時期尚早であると考えられます。


そこで、JavaScript を用いることで、iframe タグへの外部のページではない HTML 文書を埋め込む方法を 2 つ考えました。


JavaScript を用いて、iframe に HTML 文書をそのまま埋め込む方法

srcdoc 属性に対応していない場合のみ、JavaScript で動的に iframe に HTML 文書を追加する

srcdoc 属性に HTML 文書をそのまま埋め込みます。

ただし、それだけでは srcdoc 属性に対応していないブラウザでは、埋め込んだ HTML 文書を見ることができません。

その対策として、JavaScript にて、iframe タグの srcdoc 属性に設定されていた HTML を、動的に iframe タグの中身として書き出しています。


ソースコード:
<iframe srcdoc='<p>ここに埋め込むHTML文書を記載</p>' id="iframe-copy_css">
</iframe>


<script type="text/javascript">
<!--
    // iframe の srcdoc 非対応ブラウザ用
    // javascript で iframe の中身を作成する
    (function () {
        var iframe = document.getElementById("iframe-copy_css");

        // iframe の中身が無ければ、作成する
        if (iframe.contentWindow.document.body) {
            if (iframe.contentWindow.document.body.innerHTML != "") {
                return;
            }
        }

        iframe.contentWindow.document.open();
        iframe.contentWindow.document.write("<html><head></head><body>" + iframe.getAttribute("srcdoc") + "</body></html>");
        iframe.contentWindow.document.close();
    })();
//-->
</script>


実際に埋め込んだ結果:
実際にこの方式にて、HTML 文書を iframe に埋め込んだ結果を以下に示します。




この方式のメリット

この方式のメリットは、iframe タグの srcdoc 属性に対応したブラウザでは、JavaScript による動的な HTML 文書の追加が行われないという点です。


この方式のデメリット

この方式のデメリットは、srcdoc 属性に対応したブラウザと、対応していないブラウザとで、異なる挙動(見え方は同じになりますが、内部で走る処理が JavaScript で iframe にコンテンツが追加されるケースと、されないケースがあるという 2 通りの挙動が生まれる)になるという点です。


すべてのケースにおいて、JavaScript で動的に iframe に HTML 文書を生成する

iframe タグの srcdoc 属性を使用せずに、すべてのブラウザにおいて、JavaScript で動的に iframe に HTML 文書を生成する方式です。


ソースコード:
<iframe id="iframe-preview"></iframe>
<script type="text/javascript">
<!--
    // iframe の中身を作成する
    (function () {
        var iframe = document.getElementById("iframe-preview");

        iframe.contentWindow.document.open();
        iframe.contentWindow.document.write("<html><head></head><body><p>ここに埋め込むHTML文書を記載</p></body></html>");
        iframe.contentWindow.document.close();
    })();
//-->
</script>


実際に埋め込んだ結果:
実際にこの方式にて、HTML 文書を iframe に埋め込んだ結果を以下に示します。



この方式のメリット

この方式のメリットは、すべてのブラウザで iframe に HTML 文書を追加するときの挙動が統一されるという点です。


この方式のデメリット

この方式のデメリットは、srcdoc 属性が使える環境でも、JavaScript によって HTML 文書を動的に生成するため、
  • JavaScript が OFF になっている環境では iframe 内に HTML 文章を表示できない
  • JavaScript による処理負荷が発生する

というデメリットがあるのではないでしょうか。


とはいえ、JavaScript が OFF というあまり一般的ではない環境のために、どのくらい労力を割くか・また考慮すべきなのかという点は、検討が必要です。

また、srcdoc 属性の HTML 文書がそのままブラウザで表示された場合と、JavaScript で動的に追加した場合とでどの程度処理負荷に差があるのか検討が必要です。
(この部分はブラウザなどの環境によって異なるはずであり、調べるのに手間がかかるため調べていません。)


それと、srcdoc 属性に HTML 文書を書く場合には、複数行の HTML 文書も srcdoc の値を囲む"(ダブルクォーテーション) または、'(シングルクォーテーション) と HTML 文書の中身が被らなければ、そのまま HTML 文書を記載できます。

しかし、document.write などで HTML 文書を生成する場合には、複数行の HTML 文書を埋め込もうと思った場合には、行ごとに文字列として扱うために"(ダブルクォーテーション) または、'(シングルクォーテーション) で囲み、+ で連結する必要があります。(人間がテキストエディタで見て、見やすいような HTML/JavaScript の表現をしようと思った場合)

そのため、長い HTML 文書をデータとして埋め込むには、手間がかかるのではないかと思われます。
(本文中に、HTML として解釈されない形で HTML 文書を埋め込めるのであれば、その部分のデータを動的にコピーして、iframe 内のコンテンツとして生成するというのも可能ですね。)


iframe に埋め込む HTML 文書は、別のファイルとして編集・保存しておき、埋め込む段階で、JavaScript 内に埋め込めるように成形(プログラム等を用いて)すると良いかもしれません。


まとめ

このように、iframe タグに外部のページではなく、HTML をそのまま埋め込むには、現状 JavaScript による支援が必要になってくると考えます。


追記:第3の選択肢

第3の選択肢を作成しました。


JavaScript:iframe:外部のページを埋め込むのではなく、HTMLをそのまま埋め込む、第3の可能性:独自のデータ属性を使用する
http://upa-pc.blogspot.com/2015/03/javascript-iframe-srcdoc-3.html
Dr.ウーパのコンピュータ備忘録




このページにて、以下の謎の現象を確認しました。


謎:ChromeでWebページのアイコンがサイトオリジナルではなく、標準のアイコンになる現象 - Dr.ウーパのコンピュータ備忘録
http://upa-pc.blogspot.com/2015/03/chrome-javascript-iframe-srcdoc-trouble.html
→ ページを再編集したら直りました。結局原因は謎のままです。






関連記事

関連記事を読み込み中...

同じラベルの記事を読み込み中...