Firefoxで、別ページから飛んできたアンカーリンクの位置がずれる問題の対策

Firefoxでアンカー付きで別のページに移動したときに、ページが正しくない位置にスクロールするという現象が発生しました。
A.htmlページ内のリンクで、「href="B.html#anc1"」などとなっていて、クリックすると、B.htmlのanc1の箇所が表示されないということです。

この現象、ググってみると、同じような症状の報告が結構古くから有るようです。
Firefoxに以前から存在する問題なのかも。

ただし、古くから報告されている問題が、現在発生している問題と同じものかどうかは分かりません。
現象が同じでも原因が違うことは考えられます。

当然もともと発生しない場合もあるし、「こうするとなおる(かも)よ」というアドバイスはいろいろ出てきます。
しかし、いくつかの方法を試しても今回僕が遭遇した現象は解消しなかったのと、いちいち原因を考えるのもしちめんどくさえので、一気に解決できるJavaScriptを組んでみました。

■■==スクリプトここから
 window.onpageshow = function(){
  //ページのURLからアンカー部分を取得
  var myhash = $(location).attr('hash');
  if ( myhash.length > 1 ) { //アンカーがあった場合
    if($(myhash).length){ //アンカーに対応するidの要素があった場合
      var nScrolltop = $(window).scrollTop();
      var nOffset = $(myhash).offset().top;
      //現在のスクロール位置とアンカーに対応するidのY座標(本来有るべき位置)を取得
      if( Math.abs(nScrolltop-nOffset) > 5 ) { //2つの位置の差が5以下の場合
        //本来有るべき位置に調整
        $(window).scrollTop(nOffset);
        console.log("調整しました");
      } else {
        console.log("調整の必要なし");
      }
    } else {
      console.log("idに対応する要素がない");
    }
  } else {
    console.log("アンカーがない");
  }
};
■■==スクリプトここまで

【使用上の注意】
jQuery必須です。
アンカーの飛び先は、nameではなくidで設定されている前提です。

上記では、ブラウザが設定したスクロール位置と本来有るべきスクロール位置の差が5ピクセルを超えていたときだけ動作するようにしています。

数値をモニタしてみると、$(myhash).offset().topで出てくる数値には小数点が含まれており、「==」でつなぐと常に動作してしまう状態だったため、このようにしました。
・・・もっともここは分岐せず、常に動作させても良いんですけどね。

なんかもう、理由を考えるのが面倒なので、強引にスクリプトで対応した形です。
こんな処理は無いに越したことは無いですよね。。。
本当は原因が分かれば正しい対策も出来るのかもしれませんけど。

なんか良い方法があったら知りたいところです。

コメント