サイト設計に便利で、ユニークなJavaScriptを公開していきます。 なお、基本的なJavaScript Tips集サイトはこちら TECH::Recomends にまとめております。 併せて参照ください。 このページでは、上記 Tips集サイトでは見つからないような (多少やっかいな(^^;;;)Tipsを公開していく予定です。
【使用上の注意 1】
本ページで記載されている全ての JavaScript ソースコードは、最新の Internet Explorer 、Netscape Navigator
でのみ確認しております。
【使用上の注意 2】
ここに記載される JavaScript が W3C 的に正しいかどうかはまったく考えておりません(^^;ご利用になられます際は、自己責任において採用していただけますよう、お願い申し上げます。
JavaScript Tips 目次
検索エンジンや直リンク対応フレームページの作成
★このサンプルを実装するには、それなり JavaScript / HTML の知識が必要です。
★知識無しに実装してしまうと、標準的なウェブ作成ツールが上手く使えずに悩むでしょう。
★予めご了承ください。
フレームは、批判もあるものの、アナログ回線全盛の現在(2001/1現在)においては、まだまだ『使える』機能です。
スタイルシート等でメニューバーを作っていると、ページが変わる時、どうしてもメニューごとロードしなおさなければなりませんし、大分ツールが賢くなってきているとは言ってもメンテナンスが容易ではありません。メニュー変更時、メニューを持っている全ページ変更しなければならないからです。
しかし、フレームを使っている場合に悩ましいのは以下2点です。
- 検索エンジン等で引っかかるのはフレームの『中身』ページ。サイト全体を見てくれない。
- 他ページからページ参照の直リンクができない。
あるフレーム内のページ参照が行われたとき、親フレームが自動的に復帰すると便利ですよね。
そんな JavaScript を書いてみました。
1.まずは通常通りのフレーム作成
ツールを使うなりして、フレームページを作成します。 今回サンプルとして、以下のページを使って、順に変更手順を示します。
フレーム本体のページが index.htm、左側のメニュー(leftFrame)が menu.htm、右側メインフレーム (mainFrame) には、right-00.htm、right-01.htm の2枚を leftFrame から制御できるようになっています。
今回問題とするのは以下のようなケースです。例えば、検索エンジンで、right-00.htm や right-01.htm が引っかかった場合、以下のリンクで表示されることになります。
ね?これじゃあイケてませんよね。
さて、対応前の HTML ソースリストはそれぞれ以下の通りです。これを素材にして、改変手順をご紹介していこうと思います。
index.htm (フレーム本体)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="ja-JP">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<title>Extended Frame Sample</title>
</head>
<frameset cols="193,*" frameborder="YES" border="2" framespacing="2" rows="*">
<frame name="leftFrame" scrolling="AUTO" src="menu.htm">
<frame name="mainFrame" src="right-00.htm" scrolling="AUTO">
<noframes>
<body bgcolor="#FFFFFF" text="#000000">
フレーム対応のブラウザで参照ください。
</body>
</noframes>
</frameset>
</html>
menu.htm (左側メニュー)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="ja-JP"> <head> <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <title>Extended Frame Sample</title> </head> <body bgcolor="#FFFFFF" text="#000000"> <p>(メニューのサンプル)</p> <p> <a href="right-00.htm" target="mainFrame">ページその1の表示</a><br> <br> <a href="right-01.htm" target="mainFrame">ページその2の表示 </a> </p> </body> </html>
right-00.htm (メインページに表示するサンプルその1)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="ja-JP">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<title>Extended Frame Sample</title>
</head> <body bgcolor="#FFCCFF" text="#000000">
<p align="center"><b><font size="3" color="#cc0000">サンプルページ - その1</font></b> </p>
</body>
</html>
right-01.htm (メインページに表示するサンプルその2)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="ja-JP">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<title>Extended Frame Sample</title>
</head> <body bgcolor="#99FFFF" text="#000000">
<p align="center"><b><font size="3" color="#0033cc">サンプルページ - その2</font></b> </p>
</body>
</html>
2.親フレームの改変
親フレームは以下のようにして、 JavaScript で動的にフレームコードを生成するようにします。
index.htm (フレーム本体)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="ja-JP">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<meta http-equiv="Content-Style-Type" content="text/css">
<title>Extended Frame Sample</title>
<script language="JavaScript" TYPE="text/javascript">
<!--
// ★1 /////////////////////////////////////////////////////////////////////////////
// mainFrameにくる、file名を取得 //
function GetmainFrame(){
var mainFrameFilename;
var DataPos = name.search( "YourPageData:" );
if( DataPos < 0 ){
return "right-00.htm";
}
mainFrameFilename = name.substring( 13, name.length );
name = "";
return mainFrameFilename;
}
// ★1 /////////////////////////////////////////////////////////////////////////////
//-->
</script>
</head>
<script language="JavaScript" TYPE="text/javascript">
<!--
// ★2 /////////////////////////////////////////////////////////////////////////////
document.write('<frameset cols="193,*" frameborder="YES" border="2" framespacing="2" rows="*">');
document.write('<frame name="leftFrame" scrolling="AUTO" src="menu.htm">');
document.write('<frame name="mainFrame" scrolling="AUTO" src="');
document.write(GetmainFrame());
document.write('" >');
document.write('<noframes><body bgcolor="#FFFFFF" text="#000000">');
document.write('フレーム対応のブラウザで参照ください。 </body>');
document.write('</noframes> </frameset>');
// ★2 /////////////////////////////////////////////////////////////////////////////
//-->
</script>
<noscript>
<frameset cols="193,*" frameborder="YES" border="2" framespacing="2" rows="*">
<frame name="leftFrame" scrolling="AUTO" src="menu.htm">
<frame name="mainFrame" src="right-00.htm" scrolling="AUTO">
<noframes>
<body bgcolor="#FFFFFF" text="#000000">
フレーム対応のブラウザで参照ください。
</body>
</noframes>
</frameset>
</noscript>
</html>
★1について
★1 で定義されている JavaScript関数、GetmainFrame() は、右側のメインページにくる HTML ファイル名を他のページから持ってきて返す関数です。Window Name を YourPageData:hogehote.htm として媒介しますので、YourPageData: にはユニークになりそうな、名前をつけてください。
★2について
GetmainFrame() 関数で得られるファイル名を右側メインページ(mainFrame)として frameset HTML を出力させています。元の Frameset ソースから、 mainFrame の src 属性値だけを GetmainFrame() 関数から取得するようにします。
noscript タグの中は、元の frameset のソースをそのまま適用するのが良いでしょう。
3.子フレームの改変
子フレーム right-00.htm / right-01.htm は以下のよう改変します。
right-00.htm / right-01.htm (子フレーム)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="ja-JP">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<META http-equiv="Content-Script-Type" content="text/javascript">
<META http-equiv="Content-Style-Type" content="text/css">
<title>Extended Frame Sample</title>
<script language="JavaScript" TYPE="text/javascript">
<!--
// ★1 ///////////////////////////////////////////////////////////////////////////// // filepath から、file名のみを取得 //
function GetFileName(file_path){
var maxvalue = file_path.length;
var retstring = file_path;
for( var i = maxvalue; i >= 0; i-- ){
if( file_path.charAt(i) == "/" || file_path.charAt(i) == "\\" ){
retstring = file_path.substring(i+1,maxvalue);
break; }
} return retstring; } // 親フレームがいなければ、作成 // function MakeParentFrame() {
// 親フレームがいるかいないかの判別 if( parent == self ){
// frame でない場合はフレームページへ
if( location.hostname == "www.yourhostname.ne.jp" || !location.hostname.length ){
// すでに Window Name に文字列が入っていなければ実効 if( self.name.length == 0 ){ self.name = "YourPageData:" + GetFileName( location.pathname );
location.replace( "index.htm" ); // 親 Frame 呼び出し
} } } }
// ★1 ///////////////////////////////////////////////////////////////////////////// //-->
</script>
</head>
<body bgcolor="#FFCCFF" text="#000000" onLoad="MakeParentFrame()">
<p align="center"><b><font size="3" color="#cc0000">サンプルページ - その1</font></b> </p>
</body>
</html>
★1は言わずともがな、JavaScript 関数宣言です。 MakeParentFrame 関数は、 parent オブジェクトと、自分自身が一致しているかどうかを見ることで 親フレームがいるかどうかをチェックします。 親フレームがいない場合、parent オブジェクトは自分自身 self と一致します。
親フレームがいない場合は window.name 属性に、親フレームに送る自分自身のファイル名を YourPageData:ファイル名 と言う形で忍ばせています。その上で、window.location.replace メソッドを使って、 親フレーム index.htm を呼び出します。 window.name 属性は親フレームが呼び出された後も残っています。 先程の親フレームソースは、YorPageData: をキーに、 後に続く文字列を自分の初期子フレームのファイル名としています。
ですので、YourPageData: は親フレームで命名したのと同じ文字列としてください。
また、検索エンジンキャッシュ対策として、www.yourhostname.ne.jp に、ご自分のアップロードするサイトのホストネームを文字列で変更ください。これがないと、google あたりのキャッシュ表示でも実行されてしまい、ユーザー的には感じ悪い 。と言うのも、キャッシュ表示を利用する人は検索文字列のフォーカシング(色が変わって表示)がしたくて行っている事が多いからです。 ホストネームは、例えば http://www13.u-page.so-net.ne.jp/ga2/yyamag/ がサイトの URL であるならば、www13.u-page.so-net.ne.jp がホストネームです。このページならば www.idea-tech.net 。で、要は http:// のすぐ後から、次の / が来るまでの間にある URL です。
後は <body> タグに onLoad イベントを忍ばせて、 MakeParentFrame() を呼び出せば OK です。
4.出来上がり!
こんな具合で出来上がりました。
では、検索エンジンに引っかかったとして、実験してみましょう。
各ページから親フレームがきちんと呼び出されて、 自分がその子フレームとして動的にフレームサイトを生成するのが分かりますね。
5.補足
本来、JavaScript と言うのは、自分が生成したわけでない ブラウザの Window から 他のWindow へデータを渡せないもののようです。
今回それを window.name 属性を媒介させると言う、それなりトリッキーな技で解決してみました。
が、これってまずいのかな(^^;
window.name は本来、 <frame>タグの name 属性と一対一になる値です。本来はクッキーなりを使うものなのかも知れません。どうにも標準的な手法、と言うものが今ひとつ見えていない僕です。
後、フレームの中に JavaScript を入れてはイケナイものらしいのですが、じゃあ、フレーム自体を JavaScript で作ってしまえ、と言う発想です。これもなんとなくやってはイケナイことをしているような気がします。うん。凄くします(^^;;;
window.name 属性は、先に誰かが書いてしまうと、書き込むことができません。 少なくとも私の調査では、その場では書き込まれるのですが、 window.replace 等、操作を行うと書き込む前の文字列に戻るようです。 従って、書き込む前に値が入っているかどうかをチェックして、値が入っている場合は実行しないようにしています。
window.name 属性が既に入っている状態とは、例えば Google の「検索結果を新しいウィンドウに開く」設定にしてある場合です。ユーザーがこの設定にしている場合、window.name
には「nw」と言う値が入っています。この状態では window.name に値を書き込むことが出来ません。結果、いきなり default の子フレームに飛ばされてしまいます。これはユーザー的には感じ悪いはず。
兎に角フレームで一番の問題点とされる、検索エンジンや直リンクの問題に対してある程度の対処法、程度に参照頂ければ幸いです。などと言いつつ、本サイトで既に実装済みなんですが(^^;