ページ内遷移にまつわる処理(ページトップ、位置のずれ、スムーススクロール)

ワードプレス

コンテンツの多いページや、ランディングページっぽいサイトで絡んでくる「ページ内遷移」についてまとめたメモ。

遷移先の記述方法

例えば、本文(#content)まで飛ばす場合、こんな書き方が考えられます。

  1. a href=”#content”
  2. a href=”ページURL#content”
  3. a href=”?id=content”
  4. a href=”ページURL?id=content”
a href=”#content”

ページが1枚しかない、ページ遷移が発生しない、という場合はこう書くと思います。

問題も無いと思います。

a href=”?id=content”

こういう書き方もできますが、この場合ページ読み込み動作が入ります。

ページ内遷移なら不要な書き方です。

a href=”ページURL#content”

他ページのページ内に遷移する場合。

リンク自体は正常に動作しますが、後述の「ページ内遷移をスムースにスクロールさせる」が無効になります。

※このスクリプトに対してだけ、なのかもしれませんが、未検証。

a href=”ページURL?id=content”

こちらも、他ページのページ内に遷移する場合。

他ページから飛んできても、ページ途中までスムースにスクロールします。

fixedヘッダー問題

ヘッダーをブラウザ上部に固定している場合にページ内遷移をすると、遷移先がヘッダーに隠れちゃいます。

回避方法は幾つかあるようです。

CSSで一発回避

コンテンツ領域にこんな感じのCSSを適用する。

「style=”margin-top: -50px; padding-top: 50px;”」

対象をbodyにしたり、pageにしたり、コンテンツ領域にしたり、、、

幾つかの記事を参考にしてトライしたことがありますが、うまくいかないことが多く、また他の部分への影響が出ることもあり、アキラメ。

遷移先を工夫

遷移先に何らかのCSS/HTMLで「padding-top: 50px;」みたいな高さ余白を持たせる。

before疑似要素に高さを持たせたり、表示させたいブロックの50px上の要素に遷移させたり。

動作は安心、確実なのですが、いちいちテンプレートに細工したり、リンクURLが微妙になったりでちとメンドクサイ。

スクリプトで回避

個人的には一番やりたくない手法なのですが、「スムースなスクロール」がそこそこ必須になってきているので、そのついでに採用。

スムーススクロール&固定ヘッダー対策込みのスクリプト

jQuery(function(){
var headerHight = 120; //ヘッダーの高さ
	//*ページ内リンク
	jQuery('a[href^=#]').click(function(){
		var href= jQuery(this).attr("href");
		var target = jQuery(href == "#" || href == "" ? 'body' : href);
		var position = target.offset().top-headerHight;
		jQuery("html, body").animate({scrollTop:position}, 550, "swing");
		return false;
	});
	//*ページ外リンク*/      
	var url = jQuery(location).attr('href');
	if (url.indexOf("?id=") == -1) {
		// ほかの処理
	}else{
		var url_sp = url.split("?id=");
		var hash     = '#' + url_sp[url_sp.length - 1];
		var target2	= jQuery(hash);
		var position2	= target2.offset().top-headerHight;
		jQuery("html, body").animate({scrollTop:position2}, 550, "swing");
	}
});

参考、というか拝借元様

今見返してみると、ちょっとソース内容が違う。ほかのサイトも参考にしていたっぽいですが、ブックマークが見当たらず。他の参照元様、すみません。

そういえば、IE11のみで

「他ページのページ内遷移をさせると、表示された後に謎のスクロールが発生して表示がずれる」
という現象に遭遇したことがありますが、このスクリプトならOKでした。
検索しても既知のバグにも見つからなかったし、なんだったんだろう。

該当IDが無い場合、エラー発生

上記スクリプトだと、該当のIDが無い場合エラーが出ます。

表面上は「動かない、またはページ途中に遷移しない」だけですが、jQuery依存のスクリプトが共倒れする可能性があります。

対策込みのソースはこちらで。

改めて遷移先の記述方法について

このスクリプト前提で、ページ内遷移の書き方をまとめると、

  • 同一ページ内遷移限定なら、「a href=”#content”」
  • 他ページのページ内遷移ならば「a href=”ページURL?id=content”」

以上に絞られます。

ページの読み込みが発生しても良ければ「a href=”ページURL?id=content”」のみでOK、ということになります。

ページ先頭へ戻る

スムーススクロールついでに。

//HTML
<div id="page-top">
	<p class="totop"><a href="#page"><img src="<?php bloginfo('stylesheet_directory') ;?>/images/totop.png" alt="ページトップへ戻る" /></a></p>
</div>

//CSS
#page-top {
	position: fixed;
	right: 0.5rem;
	bottom: 0.5rem;
}

「無くてもいい」という考え方もありますが、個人的には無いとイラっとするので必ずつけてます。

ソースも要らないような内容ですが、補足。

  • リンク先は、先頭にさえ戻ってくれればなんでも。
  • 表示位置はよくあるパターン。
    フッター内にrelative/staticで表示しているサイトもありますが、使い勝手が落ちるのと、表示/非表示を制御する都合上、ブラウザ右下に固定しています。
  • 前述のスクリプトを読み込んでいると、スムースにスクロールして先頭に戻ります。

スクロール状況で表示/非表示をスイッチ

jQuery(function(jQuery){
jQuery("#page-top").hide();
    jQuery('body').append(
        jQuery('<div id="page-top">')
        .append(
            jQuery('<a href="#page"> </a>')
            .click(function(){jQuery('html,body').animate({ scrollTop:0}, 'fast'); return false})
            )
        );
    jQuery(window).scroll(function () {
        if (jQuery(this).scrollTop() > 200) {
            jQuery('#page-top').fadeIn();
        } else {
            jQuery('#page-top').fadeOut();
        }
    });
});

ページ先頭位置では「ページトップに戻る」を非表示に、スクロールしていくと表示する、という内容。

HTMLのid = page-topだけ合わせればOK。