9. FRAME文書

Contents

  1. Introduction to FRAMES
    • 導入
    • FRAMESET要素の入れ子による複雑なフレーム
    • FRAME文書の一般的構造
  2. NOFRAMES Elements
    • FRAMEの分割体裁
    • FRAMSETの入れ子
  3. FRAMESET Elements
  4. FRAME Elements
  5. target属性の目標としてのname属性
  6. BASE Elements
    • target属性
    • href属性
  7. おまけ Javascript による複数フレームへのターゲット

この章ではFRAME文書を紹介します。 FRAME文書とは、複数のHTML文書を組み合わされて一つになったものの事です。

それ以上の正確な知識は、HTML4.0仕様書邦訳計画、引いてはW3C原典に当たるのがスジと云うものです。HTMLは英語でしか定義されていません。

1. Introduction to Frames

導入

二つのHTMLファイル;navi.htmlbody.htmlを組み合わせて、一つの文書として表示したいとします。

表示枠の上側に navi.html、下側に body.html を組み合わせて表示した文書を frame.html とすると、 frame.html の HTML は、次のようになります。

【表示概念図】

 ----------------------
|        bar           |   <-- navi.htmlが表示
|----------------------|
|                      |
|        main          |   <-- body.hmtlが表示
|                      |
|                      |
 ----------------------

【例文】

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
            "http://www.w3.org/TR/html4/frameset.dtd">
<HTML lang="ja">
 <HEAD>
   <TITLE>フレーム文書</TITLE>
 </HEAD>
 <FRAMESET rows="20,*">
   <FRAME src="./navi.html" name="bar">
   <FRAME src="./body.html" name="main">
   <NOFRAMES>
   <BODY>
   </BODY>
   </NOFRAMES>
</FRAMESET>
</HTML>
上段
  • 縦幅 20 ピクセル。
  • barと名付けて(name="bar")、HTMLファイル navi.html を表示。
下段
  • 縦幅は上段の残り全て。
  • mainと名付けて(name="main"body.html を表示。

最初の行は文書型定義の宣言で、FRAME文書を記述するための文書型; Frameset DTD が宣言されています。 FRAME 文書の組み合わせ方は、 FRAMESET 要素で表現します。

組み込む個々のHTML文書は、 FRAME 要素で表わします。

リストを表わすUL, OL要素を思い出して下さい。順番無しリストをULで表わし、個々の項目はLI要素で表わしました。

最後に、 FRAME 文書非対応のブラウザの為に代替テキストを記述しておきます。そのための要素が NOFRAMES 要素です。

これが基本的なフレームの説明です。

ここでは、表示枠を上下に分割する為に、 FRAMESET 要素に rows 属性を与えました。左右に分割する場合、 cols 属性を用います。

FRAMESET要素の入れ子による複雑なフレーム

FRAMESET要素を入れ子にする事で、もっと複雑なフレームも作れます。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
            "http://www.w3.org/TR/html4/frameset.dtd">
<HTML lang="ja">
 <HEAD>
   <TITLE>フレーム文書</TITLE>
 </HEAD>
 <FRAMESET>
   <FRAME>
   <FRAMESET>
      <FRAME>
      <FRAME>
   </FRAMEEST>
   <NOFRAMES>
   <BODY>
   </BODY>
   </NOFRAMES>
 </FRAMESET>
</HTML>

ここでは、FRAMESET要素の子要素として、別のFRAMESET要素が入っています。この FRAME 文書は三つの HTML 文書を組み合わせて表示します。

このようにFRAMESET要素の入れ子がある場合には、NOFRAMES要素は、一番外側のFRAMSET要素の末尾に記述して下さい。

【要素構造の模式図】

    <HTML>
        |----<HEAD><TITLE>フレーム文書</TITLE></HEAD>
        |----<FRAMESET>
        |       |----<FRAME>
        |       |----<FRAMESET>
        |       |       |----<FRAME>
        |       |       |----<FRAME>
        |       |    </FRAMESET>
        |       |----<NOFRAMES>
        |       |       |----<BODY>
        |       |       |       |
        |       |       |    </BODY>
        |       |    </NOFRAMES>
        |    </FRAMESET>
    </HTML>

FRAMES文書の一般構造

上の例文を基に、フレーム文書の一般的構造を列挙します;

FRAMESET要素
文書表示枠(新規に開く場合はウィンドウ)を複数の矩形に分割表示させるための設定を行うものです。
FRAME要素
ある1つのフレーム枠の内容とその表示方法を設定するものです。終了タグは存在しません。
NOFRAMES要素
フレーム分割が機能しない場合にのみ表示されます。

2. NOFRAMES要素

フレームが表示できないブラウザでこのファイルにアクセスしてきた閲覧者のために、代替テキストも書いておきます。

【例文】

<FRAMESET rows="20,*">
   <FRAME src="./navi.html" name="bar">
   <FRAME src="./body.html" name="main">
   <NOFRAMES>
   <BODY>
    <P>これはフレーム文書です。</P>
    <P><A href="./cont.html">フレームを使わない文書</A>で御覧ください。</P>
   </BODY>
   </NOFRAMES>
</FRAMESET>

フレームを表示できない(しない)ブラウザの為の代替テキストはNOFRAMES要素で書きます。Frameset DTDに於いては、NOFRAMES要素の採りうる子要素は、BODY要素だけです。

BODY要素の中に入る子要素は、 Transitional DTD の場合と同様です。

フレームを表示できないブラウザは、 Framesset DTD を Transitional DTD と解釈し、この文書のHEAD要素を読み込むと、NOFRAMES要素を読み込みます。結果、HEAD要素とBODY要素から成るHTML文書として表示します。

3. FRAMESET要素

FRAMESET要素は、フレーム定義のFRAME要素と、代替表示内容のNOFRAME要素、FRAMESET要素を子要素に持ち得る。

<FRAMESET>
  <FRAME>
  <FRAME>
  <FRAMESET>
    <FRAME>
    <FRAME>
  </FRAMESET>
  <NOFRAMES>
    <BODY>
    </BODY>
  </NOFRAMES>
</FRAMESET>

FRAMEの分割体裁

フレームの分割方法・表示体裁はFRAMESET要素の属性;rows, colsで行う。

次の例は 3 つの横並びの枠を設定しています。 2 番目の枠は 250 ピクセル幅の固定幅(例えば画像を横幅通りに収めたいときに便利)に指定されており、 1 番目の枠と 3 番目の枠はその残りの部分を 1:3 の比率、すなわち 25% 対 75% づつ分かち合います。

<FRAMESET cols="1*,250,3*">
...フレーム定義続く...
</FRAMESET>

rows 属性が設定されていない場合、 cols 属性による垂直分割は、ページの高さ(長さ)全体に及びます。 cols 属性が設定されていない場合、 rows 属性による水平分割は、ページ幅全体に及びます。両方の属性が設定されている場合は、指定通りの分割が行われます。

<FRAMESET rows="30%,70%" cols="1*,1*,1*">
...残りの定義...
</FRAMESET>

この場合、2行3列に分割されます。

 -----------
|   |   |   |
|-----------|
|   |   |   |
|   |   |   |
|   |   |   |
 -----------

但し、この使い方は好ましくありません。実際には FRAMESET 要素を入れ子にして実現すべきでしょう。

FRAMESET の入れ子

フレーム枠は何層にでも入れ子にできます。次の例では、外側の FRAMESET 要素が全体を縦に 3 等分し、内側の FRAMESET 要素が2つ目の枠を上下に2等分しています。

<FRAMESET cols="1*, 1*, 1*">
     ...第一フレームの中身...
     <FRAMESET rows="50%, 50%">
        ...第二フレーム第一段の中身...
        ...第二フレーム第二段の中身...
     </FRAMESET>
     ...第三フレームの中身...
</FRAMESET>

4. FRAME要素

FRAME要素が取り得る属性を一部列挙します。W3C HTML 4.0仕様書の抜粋です。

name = "cdata"
src = "URL"
当該フレーム枠を読み込んだときに、最初に枠内に表示させる文書内容の所在を示します。
noresize
この論理型属性が設定されていた場合、ウインドウサイズが変更不可であるとユーザエージェントに指示します。
scrolling = "auto|yes|no"
フレーム枠内のスクロールを制御するものです。可能な値は次の3つです。
frameborder = "1|0"
フレームの枠線の表示をどのようにするかを指示するものです。可能な値は次の2つです。

noresize 属性には属性値が有りますが、値は noresize のみが許されます; noresize="noresize" 。したがって省略可能です。しかし、HTML 4 の後継言語である XHTML 1.0 では属性値の省略が認められていません。

【記述例】

<FRAME src="./index.html" name="main" noresize scrolling="auto" frameborder="0">
【記述例】の属性の意味
属性属性値意味
src./index.html 初期表示内容を、'./index.html'に設定
namemain target属性の目標名を、'main'に設定
noresize属性値は常に noresize 表示枠の大きさを、変更不可に設定
scrollingauto スクロール・バーの表示を、自動に設定
frameborder0 表示枠の境界線を、非表示に設定

src属性と、name属性は必ず記述した方が良いでしょう。

5. target属性

FRAME要素のname属性は、HyperLinkのtarget属性の目標になります。

【記述例】

<FRAMESET cols="1*,2*">
  <FRAME name="nav">
  <FRAME name="main">
  <NOFRAMES>...<NOFRAMES>
</FRAMESET>

【表示概念図】

 ----------------
|     |          |
|     |          |
| nav |   main   |
|     |          |
|     |     <----+------target="main"の目標枠
|     |          |
 ----------------

上の例で、フレーム名 nav に表示されているHTML文書の中に、

<A href="./index.html" target="main">hogehoge</A>

と記述されているとき、この target="main" により、 index.html は、フレーム枠 main 内(右側)に表示される。

FRAMESET要素のname属性の属性値として採り得るものは、半角英数文字(スペース除く)なら何でも可だが、target属性の属性値には、あらかじめ予約されている名前が4つ有る;

_blank
指定文書を名前のない新規ウインドウを開き、そこに読みこむ。
_self
指定文書を、当該目標を指している要素が存在する現在のフレーム自身に読みこむ。
_parent
指定文書を、現在のフレームの直接の親である FRAMESETに読みこむ。この値は、現在のフレームに親フレームが存在しない場合、_selfと等価である。
_top
全てのフレーム分割を解消し、元ウインドウ全体に指定文書を読み込む。この値は、現在のフレームに親が存在しない場合、 _selfと等価である。

target属性の属性値hogehogeが、読み込まれているフレーム文書の、FRAME要素に与えられたname属性値として存在しない場合、target="hgehoge"が与えられたハイパー・リンクは、hogehogeと名づけられた新規ウィンドウが開かれ、そこに読み込まれる。

上の例で、target="what"を持ったリンクは、whatと名付けられた新規ウィンドウに読み込まれる。target="what"を持つハイパー・リンクが何度働いても、一度開いたウィンドウの名前は記憶されており、そこに繰り返し読み込まれる。

target="_blank"の場合、名前の無い新規ウィンドウが別途開かれるので、繰り返し働く事で、複数個の無名のウィンドウが開かれる。

5. BASE属性

BASE要素は、HTML文書のHEAD要素の中に書きます。理由は後述しますが、HEAD要素の開始直後に書くように心掛けましょう。

target属性

同一文書内の多くのリンクが同じ目標を指し示している場合、1回target属性を指定すれば各リンク要素からは指定を省くことができます。その1回のtarget属性指定は、BASE要素によって行います。

BASE要素によってtarget="main"を指定し、各A要素からは取り除きます。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<HTML lang="ja">
  <HEAD>
    <BASE target="main">
    <TITLE>Table of Contents</TITLE>
  </HEAD>
  <BODY>
    <P>
    [<A href="./hogehoge.html">hogehoge</A>,
    <A href="./tyome.html">tyome</A>,
    <A href="./../index.html" target="_top">Top Page</A>]
    </P>
  </BODY>
</HTML>

BASE要素のtarget属性は、A要素のtarget属性によって上書きされます。

上の例では、最後のTop PageをアンカーとするA要素だけが、target="_top"で働きます。全てのフレーム枠が解消されて、元フレーム(ウィンドウ全体)に読み込まれる事になります。

href属性

相対URL(相対パス)は絶対URL(フル・パス)に翻訳されて解釈されます。通常は当該文書のURLからの相対位置として解釈されますが、BASE要素で基準URLを明示的に指定できます。

<BASE href="http://fides.dti.ne.jp/%7Esugai/public/" target="main">

このようなBASE要素がHEAD要素内に記述してあるHTML文書においては、相対URL「 ./index.html#HTML 」は、「 http://fides.dti.ne.jp/%7Esugai/public/index.html#HTML 」として解釈されます。

BASE要素で「基準URL」を指定する場合、相対URLが表れるより先に記述する必要が有ります。BASE要素が記述されるHEAD要素内には、相対URLを記述する可能性が有る要素が有る(LINK要素、META要素)ので、BASE要素はそれらよりも先、HEAD要素開始タグ直後に記述するようにした方が良いでしょう。

おまけ;複数方向へのリンク

HTML で用意されているリンクは終点と始点が一対一対応の単純リンクです。 XML LINK 言語では複数の端点同士を結び付ける事も可能ですが HTML では不可能です。

しかし、一つのフレームから複数のフレーム枠内を同時に変更したい場合などがあるでしょう。そういう場合には Java Script を利用します。

ここではサンプルとして、 a フレーム内のファイルのリンクから、 b, c フレーム内に表示するファイルを同時に変更する事にします。

サンプル・ファイル

フレーム文書の構成です;

<frameset rows="20%,*">
  <frame src="a.html" name="a">
  <frameset cols="30%,*">
   <frame src="b.html" name="b">
   <frame src="c.html" name="c">
  </frameset>
  <noframes>...</noframes>
</frameset>

a.html 内の記述です;

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
            "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
<head>
<title>sample-a</title>
<!--デフォルトで用いるスクリプト言語の指定-->
<meta http-equiv="content-script-type" content="text/javascript">
<!--javascript の記述-->
<script type="text/javascript">
<!-- to hide script contents from old browsers
function jump(x1, x2) {
  window.open(x1,"b");
  window.open(x2,"c");
}
// end hiding contents from old browsers  -->
</script>
</head>
<body>
<p><a href="javascript:jump('d.html', 'e.html')">click me!</a></p>
</body>
</html>

ファイル

ちょっとした解説

ここではスクリプト内をサポートしていない古いブラウザが表示してしまうのを避ける為にコメントアウトしています。

HTML では通常のコメントアウトは <!-- から --> までですが、今の場合は特に Javascript のコードではない事を示す為に // を挿入しました。単一行内でこれの後ろはコード内でコメントアウトされます。

メタ宣言文で、このファイル内で通常使うスクリプト言語タイプを指定しています。それと同時に SCRIPT 要素にも MIME タイプを text/javascript と宣言しています。

しかし、この MIME タイプは W3C の仕様書中で例文として採り挙げられてはいるものの、 IANA に登録された正式な MIME タイプではありません。

似た属性として、 SCRIPT 要素における language 属性が有ります。こちらは廃止予定ですが、古いブラウザがサポートしている、スクリプトのバージョンが指定できるなどのメリットも有ります。 ここで記述した JavaScript のバージョンは JavaScript1.0 以降です。

ではこの HTML 文書内のスクリプトの動作を順を追って見てみましょう。まずはリンクをクリックします;

リンクをクリックすると同時に、 javascript 関数 jump(x1,x2) が呼ばれます。

関数 jump(x1,x2) は「ウィンドウ内の或る子フレーム (a, b) に、或るファイル (x1,x2) を表示する」と云う内容になっています。

関数名 jump は任意に指定できます。しかし、規定のメソッドなどと重複してはなりません。

上のスクリプトで、リンク内の関数値 x1,x2 と、関数定義内のフレーム名 b, c を変更すれば自由にカスタマイズできます。

JavaScript では扱う対象を「オブジェクト」として取り扱います。この例では、ナビゲータオブジェクトの最上位階層の一つである window オブジェクトから始まっています。これに window オブジェクトが選択し得るメソッドの一つである open() が続きます。

open() メソッドは、 open(URL, フレーム名) の形で値を取ります。このフレーム名には HTML の予約済み target 名も全て使う事が出来ます。

ここでは、クリックイベントを拾うのに href="javascript:" を利用しましたが、イベントハンドラ onclick ( onclick 属性)を利用しても出来ます。

<a href="xxx.htm" onclick="jump('c.html','d.hmtl'); return false">xxx</a>
<!-- return false のため、本来の href 属性は働かない
  但し、 JavaScript1.0 ではない -->

また、ここで記述したスクリプト以外でも、 location オブジェクトのプロパティ href に値を代入することで、指定した URL に有る文書が、 window.parent.b に表示させることも出来ます。

function jump(x1, x2) {
  window.parent.b.location.href = x1;
  window.parent.c.location.href = x2;
  return false;
}

JavaScript はそもそも Netscape 社の独自拡張から始まり、現在も各バージョンが乱立している状態で標準規格ではありません。安定して動作する保証は何処にもありません。

一応標準規格化された JavaScript (ECMAScript) も存在しますが、これはスクリプトの言語仕様を規定しただけで、その実装はバージョンによって異なります。これに準拠した言語は、 Netscape 社の JavaScript1.3、 Microsoft 社の JScript4(5?) がありますが、これらの間の互換性は完全ではありません。

スクリプトをサポートしていないブラウザへの配慮

I.E. も JavaScript をサポートし、なぜかこちらの方が完成度が高いようですが何れにせよブラウザのバージョンによって動作が一定しない代物です。ここに挙げたスクリプト程度はブラウザによらず動作するはずですが、 JavaScript を利用する場合には、サポートしていないブラウザの可読性を損なわない様に十分注意しなければなりません。

スクリプトをサポートしていないブラウザの可読性を損なわない為に、 NOSCRIPT 要素があります。 SCRIPT 要素は INLINE 要素でしたが、 NOSCRIPT 要素は Block-level 要素です。

NOSCRIPT 要素の使い方は NOFRAMES 要素に似ていますが、 SCRIPT 要素内で記述するわけではない事に注意して下さい;

<!-- スクリプトをサポートしていないブラウザへの配慮 -->
<p>
<script type="text/javascript">
<!--
document.writeln(
  '<a href="javascript:jump('d.html', 'e.html')">click me!</a>'
);
// -->
</script>
</p>
<noscript>
<p>
<a href="d.html" target="b">d.html</a>, <a href="e.html" target="c">e.html</a>
</p>
</noscript>

ブラウザの環境変数をスクリプトで取得し、読み込みページを振り分ける事も有効でしょう。

JavaScript のリファレンス

FC2> モビット