小規模Webサイト向け CMS 「すぐ使えるCGI」のサポート情報

インラインフレーム内のアンカーまでお知らせをスクロール

最終更新日: 2016-08-04
<iframe> 内のアンカーまでリンク時にスクロールする

お知らせページを <iframe>(アイフレーム、インラインフレーム)内に表示している時、外部のページから直接、 <iframe> 内の指定位置にリンクしたい場合があります。ところが通常、親ページにアンカー(#anchor)を付けてアクセスしても <iframe> 内のページの表示位置は指定できず、常に先頭が表示されます。

このサポート情報では、「すぐ使えるCGI」で更新したお知らせページをインラインフレームで別のページに組込んだ想定で、親ページにアクセスした時に <iframe> 内の指定したアンカーまで自動的にスクロールさせる方法をご紹介します。JavaScript を使います。

設定済サンプルのダウンロードはこちら。

「すぐ使えるCGI」対象製品

「すぐ使えるCGI」の「タイムライン」形式の製品でこの方法が使えます。「お知らせ更新ツール」と分類されているものが概ね該当します。

下記リンクからサンプルをダウンロードすれば既にこの設定が組み込まれています。

<iframe> 内アンカーへのリンク時自動スクロールの設定方法

<iframe> 内アンカーへリンク時にスクロールする仕組みは以下の通りです。(1) <iframe> を組み込む親ページ と (2) 組み込まれる方の一覧ページ(全一覧) に両方設定が必要です。

1. <iframe> ページ(親ページ)の設定

まず、<iframe> を組み込む親ページの方を設定します。これは例えばサイトに元からあった 「/news.html」などのページの事です。ダウンロードできるサンプル製品では listpage_sample.html が該当します。

設定のポイントは以下の2点です。

  1. 「全一覧」を表示するインラインフレームの id 属性を指定
  2. アンカーを検出してスクロールするための JavaScript を追加

<iframe> 編集例

下記例を参考にお知らせを組み込むページに <iframe> タグを追加して下さい。

  • <iframe> の場所はページ内のどこでも構いません。style 属性や class 属性も自由に設定して下さい。
  • id 属性は必ず設定して下さい(青字部分)。
  • onload 属性は下記例のまま設定して下さい。
  • src 属性は <iframe> で表示するお知らせページ(全一覧)のURLを指定して下さい(赤字部分)。
<iframe
	id="newsframe"
	onload="iframe_scroll(this, document.location.hash)"
	src="webdir/index.html"
	>(IFRAME 機能を有効にして下さい)</iframe>

JavaScript の追加

下記のJavaScript を </body> (終了タグ)の直前に追加して下さい。

  • 冒頭にある「//フレームID」とある行は、青字部分を上で設定したインラインフレームの id属性と一致させて下さい。
  • 赤字で示してある「e」は後で編集する一覧内のid属性の指定と一致させます。通常はこのまま使用して下さい。
<script type="text/javascript">
var UrlCtl = {
	FrameID:    "newsframe",	//フレームID
};

//アンカーによって、2ページ目以降に切り替える必要があれば切り替える。

//アンカーの形式は以下のいずれか
//#(eで始まるアンカー)
//#(pページ番号)
//#(pページ番号)(eで始まるアンカー)

UrlCtl.AncFmt = new RegExp("^#(p(\\d+))?(e\\d+)?$", "i");
UrlCtl.res = document.location.hash.match(UrlCtl.AncFmt);
UrlCtl.myPageIndex = RegExp.$2;

if (0 < UrlCtl.myPageIndex.length && 0 < parseInt(UrlCtl.myPageIndex)){ // p でページが指定されているので正しいページを読み込む
	UrlCtl.SrcFmt = new RegExp("(.*?)(_(\\d+))?\\.(\\w+)$", "i");
	UrlCtl.NewsFrame = document.getElementById(UrlCtl.FrameID);
	UrlCtl.FrameSrc = UrlCtl.NewsFrame.contentWindow.location.pathname;
	UrlCtl.res = UrlCtl.FrameSrc.match(UrlCtl.SrcFmt);
	if (!UrlCtl.res){
		UrlCtl.FrameSrc = UrlCtl.NewsFrame.getAttribute("src");
		UrlCtl.res = UrlCtl.FrameSrc.match(UrlCtl.SrcFmt);
	}
	if(UrlCtl.res){
		UrlCtl.mySrc = {
			Path: RegExp.$1,
			Index: RegExp.$3,
			SrcExt: RegExp.$4
		};
		if (UrlCtl.mySrc.Index !== UrlCtl.myPageIndex){
			UrlCtl.NewsFrame.setAttribute("src", UrlCtl.mySrc.Path + "_" + UrlCtl.myPageIndex + "." + UrlCtl.mySrc.SrcExt);
			UrlCtl.NewsFrame.contentWindow.location.href = UrlCtl.mySrc.Path + "_" + UrlCtl.myPageIndex + "." + UrlCtl.mySrc.SrcExt;
		}
	}
}

function iframe_scroll(NewsFrame, myHash){
	var res = document.location.hash.match(UrlCtl.AncFmt);
	var myAnchor = RegExp.$3;
	if (0 < myAnchor.length){
		var MyNews = NewsFrame.contentWindow.document.getElementById(myAnchor);
		window.scrollTo(0, NewsFrame.offsetTop); /* 親ページをスクロールしない場合はこの行を削除 */
		if (MyNews){
			NewsFrame.contentWindow.scrollTo(MyNews.offsetLeft, MyNews.offsetTop);
		}
	}
}
</script>

2. <iframe> 内ページ(お知らせページ、全一覧)の設定

<iframe> 内に読み込む子ページ(お知らせページ、全一覧)には記事1件ごとにアンカーを指定し、URL調整用の JavaScript を追加します。

アンカーの形式

アンカーの形式は、親ページに追加した JavaScript と連動する必要があります。JavaScript は「e1」、「e2」... という形式のアンカーを想定しています。

「すぐ使えるCGI」の設定例

「すぐ使えるCGI」の「全一覧」にこの指定をするには、テンプレートファイル templates/article/article_list.txt の一番外側のタグに、下記例のように id 属性を指定して下さい(赤字部分)。

<div class="sugu-entry" id="e%_d_%">
	<div>
		<h2>%_subject_% <small>(%_yyyy_%-%_mm_%-%_dd_%)</small></h2>
		<div>%_body_%</div>
	</div>
	:
</div><!-- /sugu-entry -->

注意事項

  • 初期設定のファイル内容は製品やバージョンによって異なります。id属性だけ追加して下さい。
  • 記事1件分が一つのタグにまとまっていなかったら、一番外側を <div> タグで囲ってから id属性を追加して下さい。
  • 既に id属性が指定されていた場合は、その id属性に合わせて JavaScript 内の設定(上で赤字で示した部分)を変更して下さい。

URL調整用の JavaScript の追加

全一覧用テンプレート templates/article/article_list.html を開いて、 <head> と </head> の間に下記の JavaScript を追加して下さい。

  • 冒頭にある「//親(フレームのあるページ)のURL」とある行は、赤字部分を <iframe> を設定した親ページのURLに変更して下さい。
<script type="text/javascript">
if (top.location.href == self.location.href){
	var UrlCtl = {
		myParent: "/news.html",	//親(フレームのあるページ)のURL
	};

	//フレーム内に読み込まれていなかったら、
	//以下のURLにリダイレクト(location 書き換え)
	//親ページ.html#(pページ番号)(元のアンカー[eで始まるアンカー])
	UrlCtl.newHash = "";
	UrlCtl.myPath = self.location.pathname;
	UrlCtl.myAnchor = self.location.hash.replace(/^#/, "");
	UrlCtl.res = UrlCtl.myPath.match(new RegExp("([^/]+?(?:_(\\d+))?\\.\\w+)$", "i"));
	UrlCtl.myPage = {
		Name: RegExp.$1,
		Index: RegExp.$2
	};
	if (UrlCtl.myPage.Name != "%_page_first_%" && UrlCtl.myPage.Index != ''){ // このページは2ページ目以降
		UrlCtl.newHash = "p" + UrlCtl.myPage.Index;
	}
	if (0 < UrlCtl.myAnchor.length && UrlCtl.myAnchor.match(/^e\d+/)){
		UrlCtl.newHash = UrlCtl.newHash + UrlCtl.myAnchor;
	}
	top.location.href=UrlCtl.myParent + "#" + UrlCtl.newHash;
}
</script>

アップロード

以上の編集が終わったら、編集したファイルをサーバに上書きアップロードして下さい。

再構築

管理画面一覧にある「再構築(テンプレート変更反映)」ボタンを押して下さい。

自動スクロールのためのリンク指定方法

設定した <iframe> 内のアンカー位置に自動スクロールするには、他のページからは以下のようにリンクします。

リンク設定例

<a href="/path/to/news.html#e1">リンクテキスト</a>


「/path/to/news.html」は <iframe> は組み込んだ親ページのURL です。ダウンロードできるサンプルでは、listpage_sample.html です。「e1」は お知らせページ(全一覧)上のアンカーです。

他のWebサイトからのリンクや、メールにURLを記載する時は http からのURLの末尾に上記と同じアンカーを付ければOKです。

新着情報(短い一覧)のリンク設定例

「すぐ使えるCGI」の「短い一覧」から親ページに組み込んだ「全一覧」にアクセスするには、テンプレートファイル templates/article/short_list.txt のリンクタグを下記例を参考に設定して下さい。赤字部分は <iframe>を設定した親ページのURLです。また、target属性は 「_top」 にして下さい(青字部分)。

<a href="/path/to/news.html#e%_d_%" target="_top">%_subject_%</a>

「短い一覧」の件数が多い場合

もし大容量版をお使いで「短い一覧」の件数が「全一覧」の1ページ件数より多い場合は、以下の様に設定して下さい(緑字部分が上記と異なる)。

<a href="%_to_index_%#e%_d_%" target="_top">%_subject_%</a>

アップロード

編集が終わったら、編集したファイルをサーバに上書きアップロードして下さい。

再構築

管理画面一覧にある「再構築(テンプレート変更反映)」ボタンを押して下さい。

制限事項

大容量版で「全一覧」を分割して運用している場合、一つの記事が「全一覧」のどのページに掲載されるかは、記事の追加に伴って変化します。外部ページやメールなどに指定したリンク表記は、更新が進んだ時は期待通りスクロールできなくなります。

関連リンク

さらに詳しく