phpspot開発日誌さんで紹介されていた 「IFRAMEを使わずにHTMLファイルから他のHTMLファイルを読み込む方法」 を読んでちょこっと補足。
人気エントリーに便乗する感じで。
XHTMLではiframeタグは禁止されているのでValidにしたい場合はこっちを使ったほうがよいらしいです。
iframe 要素は、HTML4.01 Strict 及び XHTML1.0 Strict では未定義 (Transitional、Frameset では定義済み)、XHTML1.1 では廃止されていますので、Strict でコーディングする際に外部オブジェクトを (X)HTML によって読み込むには object を使うことになりますね。
で、object 要素の DTD はどうなっているかというと、(XHTML1.0 Strict)
<!ELEMENT object (#PCDATA | param | %block; | form | %inline; | %misc;)*> <!ATTLIST object %attrs; declare (declare) #IMPLIED classid %URI; #IMPLIED codebase %URI; #IMPLIED data %URI; #IMPLIED type %ContentType; #IMPLIED codetype %ContentType; #IMPLIED archive %UriList; #IMPLIED standby %Text; #IMPLIED height %Length; #IMPLIED width %Length; #IMPLIED usemap %URI; #IMPLIED name NMTOKEN #IMPLIED tabindex %Number; #IMPLIED >
こんな感じ。また基本的なところですが、object 要素はインライン要素として定義されています。
<!ENTITY % special "%special.pre; | object | img ">
なので、元ネタのサンプルソース (下記) に補足すると、
<html> <head> <title>test</title> </head> <body> <!--[if IE]> <object classid="clsid:25336920-03F9-11CF-8FD0-00AA00686F13" data="/exec/some.html" style="width:100;height:100px"> <p>non object</p> </object> <![endif]--> <!--[if !IE]> <--> <object type="text/html" data="/exec/some.html"> <p>non object</p> </object> <!--> <![endif]--> </body> </html>
まず、object 要素はインライン要素ですから、Strict な (X)HTML でコーディングする場合は、body 要素の直接の子要素として記述することはできず、ブロックレベル要素内で記述しなければなりません。また、「classid」 を指定していますが、サンプルでは読み込んでいるファイルが、HTML 文書ですから、あまり必要はありません。省略してもよいでしょう。
逆に、width、height の両属性を記述しておく方が有益でして、(サンプルではスタイルで指定してありすが) IE 以外のブラウザ用として書かれているサンプルも、width、height を指定してあげれば、問題なく IE で表示されます。
ということで、その辺を考慮して記述するならば、
<p> <object type="text/html" data="/exec/some.html" width="100" height="100"> object に対応していない場合はこれが表示される </object> </p>
って書けば OK。
object 要素は、ブロック要素も内包できるので、p 要素を含みたい場合は、
<div> <object type="text/html" data="/exec/some.html" width="100" height="100"> <p>object に対応していない場合はこれが表示される</p> </object> </div>
って感じに。
ちなみに、object 要素は、iframe 要素だけでなく、img 要素の代わりとかにもなります。こんな感じで。
<p> <object data="/img/title.png" type="image/png" width="255" height="36"> 代替テキスト</object> </p>
ただ、object のレンダリングは、ブラウザによってマチマチで、なかなかクロスブラウザなコントロールが難しいのが現状。特に IE は無駄にスクロールバーが表示されたりしてダメダメなので、オススメはしないですね。




![[広告] SwapSkills for the happy web weekend](/img/bnr/ban200.jpg)
DTDチェックやObject要素がインラインであることから、body直下に記述できない指摘、width、height を指定してあげれば、問題なく IE で表示される件など非常に重要だと思います。しかし、せっかく良いエントリーなので一つご指摘させてください。
「元ネタのサンプルソース」が実際の元ネタと違うのは何故でしょうか。phpspotさんの元記事では例のような通常のHTMLコメントでなく、IE向けの条件付きコメントとして、IEの場合とIE以外の場合で記述を分離していますが、ここは重要な部分ではないでしょうか。
そもそも、phpspotでの記事も元ネタがあります。Aleksandar Vacić氏のブログエントリー「Insert HTML page into another HTML page」という記事ですが、こちらの記事でIEとIE以外で記述を分離している理由がわかります。
それによるとAleksandar氏は、IE6や7でうまく動作しなかったため10分ほどいじり回したが、最終的にregeditを開いてtext/htmlのレンダリングに必要なclsidを分析し type=”text/html”の代替としてIE用に記述した旨読み取れます。
最終的にyoshiさんの記述でFirefox2/IE7共表示が確認できたので、最もスマートな記述かと思いますが(IE6は未確認です) はてブのホットエントリーにも入っているので気づいた点お知らせでした。
anonyさんコメントありがとうございます。
ご指摘感謝します。おっしゃるとおりです。サンプルソースを元サイトと同じ記述に直しておきました。本当の元記事をさらっとしか読んでいなかったのが敗因です、、気をつけねば。
初めまして、実際このやり方で、iframeからobjectに変えてみたのですが
ちょっと気になったのでコメントします。
objectで他のhtmlファイルを取り込んだ場合、
その取り込まれたページ(以下、子ページ)にあるリンクは
取り込んだページ(以下、親ページ)をリンク先に飛ばす事ができず、
object内をリンク先に飛ばす事しかできません。
もちろんこれはhtmlだけの話ですので、
javascript のリンクターゲットを用いた場合は
(link.target="_top"; 等)
親ページをリンク先に飛ばすことはできるのですが、
この場合もIE6、IE7では機能しません。
iframeをメニュー欄などのナビゲーションとして使っている場合、
objectに変えてしまっては、大いに問題があると思うのですが。
paramで指定してみるなど、色々と方法を考えたのですが、良い案が浮かびません。
どうしたものでしょうか?
結局 は IE では動かないのですよね?正確にはローカルでは動くけどサーバにあげると動かなくなる(ドメインが対象と別になると)。iframe なら可。
とおりすがるさんコメントありがとうございます。
> iframeをメニュー欄などのナビゲーションとして使っている場合
そうですね。そのような iframe の使い方をしているサイトでは完全な代替案にはならないですね。
ただ、 iframe は Strict (X)HTML で未定義なだけですから、その場合は Transitional などでコーディングして、無理に iframe を廃する必要もないと思いますよ。
どうしても Strict にこだわって、Valid な (X)HTML を書きたいという場合は、メニューの構造を変えるほうが早いですね。
moge さんコメントありがとうございます。
IE + object だと別ドメインにあるオブジェクトの読み込みができないみたいですね。何でかはわかりませんが、、
> IE + object だと別ドメインにあるオブジェクトの読み込みができないみたいですね。何でかはわかりませんが、、
「ツール」 > 「インターネットオプション」でセキュリティを緩くすると表示されたのですが、これではちょっと使えませんね。
objectで表示した際に枠ができてしまうと思うのですが、これを外部スタイルシートで消す方法って無いですか?
>IE + object だと別ドメインにあるオブジェクトの読み込みができないみたいですね。
なるほどそうだったんですね...
何日か前に読んだいろんなところのエントリを探していたらこの記事を見つけてスッキリしました。
今頃になってですが参考になりました。