非常にニッチな気もしますが、誰かの役に立てばと思いまとめてみます。
【解決したい問題】
Firefox(4.0以降)には、インラインフレーム(iframe)内に定義されたアンカー(「#test」のような記述)でページ全体が正しくスクロールしない事象があります。このため、独自コンテンツをiframeで埋め込むFacebookページでは、Firefoxにおいてページ内のアンカー移動ができません。
【解決方法の概要】
Facebook JavaScript SDKの「FB.Canvas.scrollTo」メソッドを使って画面全体をスクロールさせることで、アンカーのような動きを実現させます。
【サンプルコード】
1. HTMLファイル(index.php)
<html>
<head>
<title>anchor test</test>
<script src="script/fb_scroll.js"></script>
</head>
<body onload="fb_gotoTop();">
<!-- Facebook SDKロードここから -->
<div id="fb-root"></div>
<script src="script/fb_load_sdk.js"></script>
<!-- Facebook SDKロードここまで -->
<a href="javascript:fb_anchor('test')">アンカーへ</a><br/>
<!-- 中略 -->
<div name="test" id="test">ここにスクロールさせたい</div>
</body>
</html>
2. JavaScript SDKをロードするためのJSファイル(fb_load_sdk.js)
window.fbAsyncInit = function() {
FB.init({
appId : 'YOUR_APP_ID', // App ID
channelUrl : '//WWW.YOUR_DOMAIN.COM/channel.html', // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
// Additional initialization code here
};
// Load the SDK Asynchronously
(function(d){
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
3. スクロールを実行する処理を記述したJSファイル(fb_scroll.js)
/**
* idが指し示す要素の位置へスクロール(anchor代用)
*/
var fb_anchor=function(id)
{
// Firefoxの場合のみFacebook APIでスクロール
var strUA = navigator.userAgent.toLowerCase();
if(strUA.indexOf("firefox") != -1)
{
FB.Canvas.getPageInfo(
function(info) {
var elemOffsetTop = document.getElementById(id).offsetTop;
FB.Canvas.scrollTo(0, elemOffsetTop + info.offsetTop);
}
);
}
// それ以外はAnchorが効くので普通に遷移
else
{
location.href="#" + id;
}
};
/**
* ページ先頭に遷移
*/
var fb_gotoTop = function()
{
FB.Canvas.scrollTo(0, 0);
};
【理屈】
HTMLファイルの拡張子が.phpになっているのは、FacebookページがコンテンツをPOSTでロードするのに対して、私が使っているサーバー(CORESERVER)において.htmlファイルへのPOSTがエラーになるための回避策で、それ以上の意味はありません。
Facebook JavaScript SDKのロードはFacebookの技術ドキュメントを参照して実装してください。この例では見通しを良くするためにJavaScriptを別ファイルに切り出しています。
アンカーへ飛ばすリンクにはhref記述に「#test」のような記述の代わりに「javascript:fb_anchor(‘test’)」のように記述してJavaScriptの処理をコールするようにします。
fb_scroll.jsに定義されたメソッドfb_anchorでは(1)FB.Canvas.getPageInfoメソッドで取得したiframeの画面最上部からの位置(offsetTop)と(2)パラメータで指定されたidに対応するHTML要素のiframe内における最上部からの位置(offsetTop)を加算して、画面全体におけるスクロール位置を計算し、FB.Canvas.scrollToメソッドでスクロールさせています。(1)を計算して加算するのがミソです。
サンプルコードではUserAgentを見てFirefoxの時のみFB.Canvas.scrollToによるスクロール、それ以外の場合は普通にアンカーによるスクロールを行わせております。このへんはお好みで。
【オマケ】
fb_scroll.jsに定義されたメソッドfb_gotoTopは単純に一番上までスクロールを戻す処理です。この処理をbodyのonLoadに仕込んでおけば、ページ遷移のたびにFacebookページのスクロール位置が一番上まで戻り、普通のWebページっぽくなります(この処理が入っていないと画面遷移してもスクロール位置が保持される)。