非常にニッチな気もしますが、誰かの役に立てばと思いまとめてみます。
【解決したい問題】
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ページっぽくなります(この処理が入っていないと画面遷移してもスクロール位置が保持される)。