【Tips】Facebookページ内のアンカーリンクをFirefoxでそれっぽく動作させる方法


非常にニッチな気もしますが、誰かの役に立てばと思いまとめてみます。

【解決したい問題】

Firefox(4.0以降)には、インラインフレーム(iframe)内に定義されたアンカー(「#test」のような記述)でページ全体が正しくスクロールしない事象があります。このため、独自コンテンツをiframeで埋め込むFacebookページでは、Firefoxにおいてページ内のアンカー移動ができません。

【解決方法の概要】

Facebook JavaScript SDKの「FB.Canvas.scrollTo」メソッドを使って画面全体をスクロールさせることで、アンカーのような動きを実現させます。

【サンプルコード】

1. HTMLファイル(index.php)

<br />
<html><br />
<head><br />
<title>anchor test</test><br />
<script src="script/fb_scroll.js"></script><br />
</head><br />
<body onload="fb_gotoTop();"><br />
<!-- Facebook SDKロードここから --></p>
<div id="fb-root"></div>
<p><script src="script/fb_load_sdk.js"></script><br />
<!-- Facebook SDKロードここまで --><br />
<a href="javascript:fb_anchor('test')">アンカーへ</a><br />
<!-- 中略 --></p>
<div name="test" id="test">ここにスクロールさせたい</div>
<p></body><br />
</html><br />

2. JavaScript SDKをロードするためのJSファイル(fb_load_sdk.js)

<br />
  window.fbAsyncInit = function() {<br />
    FB.init({<br />
      appId      : 'YOUR_APP_ID', // App ID<br />
      channelUrl : '//WWW.YOUR_DOMAIN.COM/channel.html', // Channel File<br />
      status     : true, // check login status<br />
      cookie     : true, // enable cookies to allow the server to access the session<br />
      xfbml      : true  // parse XFBML<br />
    });</p>
<p>    // Additional initialization code here<br />
  };</p>
<p>  // Load the SDK Asynchronously<br />
  (function(d){<br />
     var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}<br />
     js = d.createElement('script'); js.id = id; js.async = true;<br />
     js.src = "//connect.facebook.net/en_US/all.js";<br />
     d.getElementsByTagName('head')[0].appendChild(js);<br />
   }(document));<br />

3. スクロールを実行する処理を記述したJSファイル(fb_scroll.js)

<br />
/**<br />
 * idが指し示す要素の位置へスクロール(anchor代用)<br />
 */<br />
var fb_anchor=function(id)<br />
{<br />
	// Firefoxの場合のみFacebook APIでスクロール<br />
	var strUA = navigator.userAgent.toLowerCase();<br />
  	if(strUA.indexOf("firefox") != -1)<br />
	{<br />
	    FB.Canvas.getPageInfo(<br />
	        function(info) {<br />
	            var elemOffsetTop = document.getElementById(id).offsetTop;<br />
	            FB.Canvas.scrollTo(0, elemOffsetTop + info.offsetTop);<br />
	        }<br />
	    );<br />
    }<br />
    // それ以外はAnchorが効くので普通に遷移<br />
    else<br />
    {<br />
		location.href="#" + id;<br />
    }<br />
};</p>
<p>/**<br />
 * ページ先頭に遷移<br />
 */<br />
var fb_gotoTop = function()<br />
{<br />
    FB.Canvas.scrollTo(0, 0);<br />
};<br />

【理屈】

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ページっぽくなります(この処理が入っていないと画面遷移してもスクロール位置が保持される)。

コメントを残す

メールアドレスが公開されることはありません。

Time limit is exhausted. Please reload CAPTCHA.