« WordPressのSyntaxHighlighterプラグインをカスタマイズする
CSSだけで作る伸縮ボタン »


jQueryでページ内リンクをスムーズスクロールする

WordPress:2.5.1
jQuery:1.2.3-1.2.6
ScrollTo:1.3.3
Browser:FF3,IE6,Safari3,Opera9
 
Add this:

ページ内へのアンカーリンク <a href=”#hoge”> をクリックすると、通常は一瞬で移動するため、ページのどの辺りにいるのかわからなくなり、閲覧者を混乱させることがあるかもしれません。これを改善した、良くあるわかりやすいナビゲーションは、移動をスムースなスクロールで行うものです。スムーススクロールを簡単に実現するなら jQuery のみでもできますし、スクロール用のプラグインを使っても良いです。ここではその両方を紹介し、WordPressプラグインとして利用できるようにします。

WordPressプラグインの作成

# で始まるページ内リンクはリンク先へスムーススクロールし、リンク先が #_top となっているリンクは body タグへスムーススクロールさせます。 #_top を id に持つタグを XHTML に記述しておく必要はありません。プラグインファイルは以下のようになります。jquery.js は必須です。ScrollTo プラグインを使うなら jquery.scrollTo.js も必要です。このように、WordPressプラグインが他のライブラリに依存する場合は、通常はプラグインのフォルダを作成し、そこに関連ファイルをまとめます。プラグイン公開・配布の予定が無い場合で、共通に使うライブラリファイルがプラグインごとに重複して存在するのを避けたいなら、/wp-includes/js/jquery/ 以下や独自の js フォルダ以下にアップロードして参照すると良いでしょう。

<?php
/*
Plugin Name: XXX Smooth Scroll to Anchor
Plugin URI: http://triplexxx.jp/
Description: Smooth Scroll to Anchor
Author: xxx
Author URI: http://triplexxx.jp/
Version: 1.0
*/

function xxx_scroll_init()
{
	//  JavaScriptファイルの場所を指定します
	$url = get_bloginfo('wpurl');

	//  インクルードフォルダ以下の場合
	$url .= '/wp-includes/js/jquery/';
	//  プラグインフォルダの場合
	//$url .= '/wp-content/plugins/xxx_scroll/';

	wp_enqueue_script('jquery');

	//  jQuery ScrollToプラグインを使う場合
	//wp_enqueue_script(
	//	'jquery_scrollTo'
	//	, $url . 'jquery.scrollTo.js'
	//	, array('jquery'), '1.3.3'
	//);
}

function xxx_scroll()
{
?>
<script type="text/javascript">
	var j$ = jQuery;

	j$(function(){
		j$('a[href^=#]').click(function() {
			var href= this.hash;
			var $target = j$(href == '#_top' ? 'body' : href);

			if($target.size()) {
				//  jQuery のみの場合
				var top = $target.offset().top;
				j$(j$.browser.safari ? 'body' : 'html')
					.animate({scrollTop:top}, 800, 'swing');
				//  jQuery ScrollToプラグインを使う場合
				//j$.scrollTo($target, 800, {easing:'swing'});
			}
			return false;
		});
	});
</script>
<?php
}

add_action('wp_print_scripts', 'xxx_scroll_init');
add_action('wp_head', 'xxx_scroll');
?>

プラグインの要点を順に説明します。

function xxx_scroll_init()

スクリプトのインクルード用関数です。

$url .= '/wp-includes/js/jquery/';

js ファイルを共通に使用します。WordPress の jQuery 関連フォルダにアップロードした場合です。

$url .= '/wp-content/plugins/xxx_scroll/';

js ファイルをプラグイン専用に用意する場合は、こちらを使います。xxx_scroll プラグインフォルダ以下にアップロードした場合です。

wp_enqueue_script('jquery');

WordPress で 定義されている jQuery をインクルードします。wp_enqueue_script を使うと重複せずにインクルードできます。

wp_enqueue_script('jquery.scrollTo', $url . 'jquery.scrollTo.js', array('jquery'), '1.3.3');

ScrollTo プラグインをインクルードします。ファイルのパスと jquery に依存していることを指定しています。これだけでインクルード順序や重複の管理は WordPress が自動で行ってくれます。

function xxx_scroll()

スクロール処理を定義します。

var j$ = jQuery;

jQuery のままでも良いです。jQuery が長くて嫌、という場合にお好みの変数に代入しましょう。$ という表記もできますが prototype.js でも同じ表記を使用しているため名前が衝突します。jQuery では以下のようにしてこれを回避できます。

jQuery.noConflict();
var j$ = jQuery;

noConflict() で $ を他のライブラリに戻し、他の変数(例: j$)に置き換えます。面倒な場合は初めから jQuery の表記を使えば何も問題ありません。

j$(function(){

DOM の構築後に実行される関数です。いくつ定義しても上書きされず、すべて実行されるので便利です。j$(document).ready(function(){ と記述しても同じです。

j$('a[href^=#]').click(function() { 

リンク先が # から始まる a タグを対象にして、click イベント時の処理を定義します。

var href= this.hash;

href の # 以降の文字列を取得します。

var $target = j$(href == '#_top' ? 'body' : href);

#_top なら body 要素、それ以外は href の値を id に持つ DOM 要素を取得します。

if($target.size()) { 

DOM 要素が存在する場合のみ、以降を実行します。

var top = $target.offset().top;

DOM 要素のページ内での top 位置を取得します。この位置までスクロールさせます。余分にスクロールさせたい場合は、必要なピクセル数を引きます。例: var top = $target.offset().top - 50;

j$(j$.browser.safari ? 'body' : 'html')
	.animate({scrollTop:top}, 800, 'swing');

html は FF3,IE6,Opera9、body は Safari3 でそれぞれページ全体を対象として正しく動作させるための指定です。animate で 800ms で top へスムーズに移動します。第3引数の easing には swing または linear を指定できますが、省略しても構いません。様々な easing 動作をさせる easing プラグインもありますので、お好みで利用すると良いでしょう。

j$.scrollTo( $target, 800, {easing:'swing'});

ScrollTo プラグインを使う場合は、このように記述します。

add_action( 'wp_print_scripts', 'xxx_scroll_init' );

xxx_scroll_init 関数を wp_print_scripts フックに追加します。wp_print_scripts は <head> 内にスクリプトをインクルードするタグを挿入します。

add_action('wp_head', xxx_scroll);

xxx_scroll 関数を wp_head フックに追加します。wp_head フックは通常、WordPressテーマの ヘッダテンプレート header.php 内 </head> 終了タグの直前に記述されています。

<?php wp_head(); ?>
</head>

ご使用のテーマのヘッダテンプレートにこの記述がない場合は追加してください。

XHTML の記述

以下のように、ページ内アンカーは通常通り、ページトップへのアンカーは #_top を指定します。

<a href="#h3-1">「WordPressプラグインの作成」へ移動</a>
<a href="#_top">ページの先頭へ移動</a>

リンクの例:

“ページの先頭へ移動”を自動で追加

エントリの最後には”ページの先頭へ移動”のリンクがあると親切です。これを自動で追加するプラグインを作成します。WordPress のエントリは、おおよそ以下のような構造になっています。

<div id="content">
  :
  <div class="post">
    :
    <div class="entry">
      エントリ本文
    </div>
    エントリ関連情報
  </div>
  :
</div>

テーマによっては、構造が異なりますので、ご利用のテーマについて予め調べておいてください。ここでは post の最後にリンクを作成することにします。

post の最後にリンクを追加:

$post = j$('.post');
if($post.size())
	$post.append('<div class="block"><a href="#_top">ページの先頭へ</a></div>');

append は、対象の DOM 要素の子要素の末尾に XHTML文字列や DOM 要素を追加します。この例では、post クラスを持つ div の終了タグ直前にアンカーリンクを追加しています。これを先ほどのプラグインの初めに記述します。

j$(function(){
 ここに記述します

a タグの click イベント定義後に a タグを追加しても、リンク動作をしないので注意してください。a タグ作成後に click イベント定義、の順です。

IEでは動作しない

スクリプトで動的に a タグを追加すると IE では href に http から始まるホスト名が付加されるため、# から始まるリンク先を選択するセレクタ [href^=#] では対象外になってしまいます。そのため、以下のようにセレクタを追加する必要があります。

'a[href^=#], a[href$=#_top]'

これで #_top で終わっている a タグも選択されます。ただし、ほとんどないとは思いますが、別ページや外部リンクに #_top が付加されていると正しく動作しません。その場合は、自動で追加する a タグの id 名を #_top から他のものに変更してください。

Trackback

Comments

  1. [...] ■jQueryでページ内リンクをスムーズスクロールする ⇒http://triplexxx.jp/archives/116 [...]

  2. [...] jQueryでページ内リンクをスムーズスクロールする | TRIPLEXXX (tags: jQuery) [...]

  3. [...] jQueryでページ内リンクをスムーズスクロールする | TRIPLEXXX (tags: jQuery) [...]

  4. [...] ページをスム~ズ移動 ※バッキングするため停止中 参照:jQueryでページ内リンクをスムーズスクロールする [...]

Leave a Comment

« WordPressのSyntaxHighlighterプラグインをカスタマイズする
CSSだけで作る伸縮ボタン »