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

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

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

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

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

自動スクロールするページの設定方法

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

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

まず、<iframe> を組み込む親ページの方を設定します。これは例えばサイトに元からあった 「/news.html」などのページの事です。

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

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

I. <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>

II. 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」... という形式のアンカーを想定しています。

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

「すぐ使えるCMS」の「全一覧」にこの指定をするには、テンプレートファイル 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: "/path/to/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>

アップロード

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

再構築

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

リンクの指定方法(クリックするとスクロールするための設定)

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

「すぐ使えるCMS」の「短い一覧」から親ページに組み込んだ「全一覧」にアクセスするには、テンプレートファイル 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>

アップロード

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

再構築

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

外部からのリンク設定

外部からのリンクで設定した <iframe> 内のアンカー位置に自動スクロールするには、以下の様に設定します。「外部」とは「すぐ使えるCMS」で書き出されるページの範囲外、の意味です。

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

「/path/to/news.html」は <iframe> は組み込んだ親ページのURL です。「e1」は お知らせページ(全一覧)上のアンカーです。

Webサイト外からのリンク

上記例は、同じサイトの「外部」からのリンクです。他のWebサイトからのリンクや、メールにURLを記載する時は http からのURLの末尾に上記と同じアンカーを付けて下さい。

制限事項

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