当ブログではヘッダーバーを固定しており、左上のロゴをクリックするとトップページに戻るようにしています。レスポンシブデザインによるスマートフォン対応を行いました。PCブラウザでのデザインが、そのままスマホでのデザインに反映されるようになったことで、スマホにおいては状況により、このロゴは「戻る」ボタンとしてクリックされるようになるんじゃないかと思い、記事のページが表示された時のみ、前のページに戻るような機能を実装することにしました。特にindexの2ページ目以降から記事ページに飛んだ時とかに威力を発揮するのではと思っています。

今回の機能実装のポイント
固定でトップページのURLを指定していたロゴのリンクに対して、以下を実行しました。
- 「表示されているページが記事ページ」かつ「リンク元が当ブログのページ」かつ「リンク元が記事ページ以外のページ」であった場合 → 「リンク元のURL」を指定
- 上記以外の場合 → 「トップページのURL」を指定
技術的なポイントとしては、以下の通りです。
- 表示されているページのURLの取得
- 参照元のページのURLの取得
- URLを比較するための正規表現
現在表示されているページのURLを取得する
JavaScriptで「現在表示されているページのURL」を取得する方法は以下の通りです。
location.href
今回は「ホストネイム(ドメイン)」や開発環境にも対応させるべく「ポート番号」なども取得するようにしました。
ホストネームの取得
location.hostname
ポート番号の取得
location.port
以下のようにすると、上記のホストネームとポート番号を同時に取得することも可能です。
location.host
参照元(リファラー)のURLを取得する
JavaScriptで「参照元ページのURL」を取得する方法は以下の通りです。
document.referrer
※直接URLを指定したり、ブックマークなどから訪問してきたりして、参照元がない場合、戻り値は空文字となります。
正規表現でURLを評価する
上記の通り「現在表示されているページのURL」と「参照元のページのURL」を取得したら、次は正規表現を使って以下を調べます。
- 「現在表示されているページ」が記事ページかどうか
- 「参照元のページ」が同一のホスト内のページかどうか
- 「参照元のページ」が記事ページ以外のページかどうか
「現在表示されているページ」が記事ページかどうか調べる
当ブログの記事ページのURLは以下のような形式となっています。(WordPressのパーマリンク設定「数字ベース」)
http://mae.chab.in/archives/123
このURLを正規表現で表すと以下のようになります。
/^https?:\/\/mae.chab.in\/archives\/[0-9]+$/i
正規表現を使って実装すると以下のようになります。
// 現在表示されているページのURLを取得
var url = location.href;
// 記事ページの正規表現
var regexp1 = /^https?:\/\/mae.chab.in\/archives\/[0-9]+$/i;
// matchメソッドを使って評価
console.log(url.match(regexp1));
// urlが「http://mae.chab.in/archives/123」であった場合
// => ["http://mae.chab.in/archives/123",
// index: 0,
// input: "http://mae.chab.in/archives/123"]
//
// urlが「http://mae.chab.in/archives/123」でなかった場合
// => null
ちなみに、WordPressの記事ページの他のタイプのパーマリンクを正規表現で書くと以下のようになります。
// デフォルト
// http://mae.chab.in/?p=123
/^https?:\/\/mae.chab.in\/\?p=[0-9]+$/i
// 日付と投稿名
// http://mae.chab.in/2015/02/04/sample-post/
/^https?:\/\/mae.chab.in\/[0-9]{4}\/[0-9]{2}\/[0-9]{2}\/[^\/]+\/$/i
// 月と投稿名
// http://mae.chab.in/2015/02/sample-post/
/^https?:\/\/mae.chab.in\/[0-9]{4}\/[0-9]{2}\/[^\/]+\/$/i
// 投稿名
// http://mae.chab.in/sample-post/
/^https?:\/\/mae.chab.in\/[^\/]+\/$/i
「参照元のページ」が同一のホスト内のページかどうか調べる
参照元のページのURLに自分のサイトの「プロトコル + ドメイン(ホスト名)」が含まれているかどうか調べます。当ブログの「プロトコル + ドメイン」は以下の通りとなっています。
http://mae.chab.in
これを正規表現で表すと以下のようになります。
/^https?:\/\/mae.chab.in/i
正規表現を使って実装すると以下のようになります。
// 参照元のページのURLを取得
var referrer = document.referrer;
// ドメイン(ホストネーム)の正規表現
var regexp2 = /^https?:\/\/mae.chab.in/i;
// matchメソッドを使って評価
console.log(url.match(regexp2));
// 参照元のドメインが「mae.chab.in」であった場合
// => ["http://mae.chab.in",
// index: 0, input: "http://mae.chab.in/page/2"]
//
// 参照元のドメインが「mae.chab.in」でなかった場合
// => null
「参照元のページ」が記事ページ以外のページかどうか調べる
上記の2つを合わせた形となりますね。正規表現を使って実装すると以下のようになります。
// 参照元のページのURLを取得
var referrer = document.referrer;
// 記事ページの正規表現
var regexp3 = /^https?:\/\/mae.chab.in\/archives\/[0-9]+$/i;
// matchメソッドを使って評価
console.log(!url.match(regexp3));
// 参照元のURLが「http://mae.chab.in/archives/123」でなかった場合
// => true
//
// 参照元のURLが「http://mae.chab.in/archives/123」であった場合
// => false
正規表現オブジェクト(RegExp)を使って実装する
本番環境と開発環境でホスト名(ドメイン)が異なる場合もあるので、正規表現内に変数を使いたくなります。この場合、RegExpオブジェクトを使って以下のように正規表現を書くことができます。上記の「現在表示されているページ」が記事ページかどうか調べる方法を書き換えてみます。
// 現在表示されているページのURLを取得
var url = location.href;
// ホストネームとポート番号を同時に取得
var domain = location.host;
// 記事ページの正規表現
var regexp1 = new RegExp("^https?:\/\/" + domain + "\/archives\/[0-9]+$", "i");
// URLの評価
console.log(url.match(regexp1));
[参考サイト]
JavaScriptで機能を実装する
上記の方法を用いて、「表示ページごとにロゴのリンクを変更する機能」を実装すると以下のようになります。
HTMLは以下の通りとなります。リンクのURL(トップページのURL)やアンカーテキスト(ブログタイトル)はWordPressの関数を使って表示させています。またFont Awesomeを使ってアイコンを切り替えるようにするので、空のi要素を配置しています。
<h1 id="blog-title">
<a href="<?php get_option('home'); ?>"><i></i><?php bloginfo('name'); ?></a>
</h1>
次にJavaScriptの実装は以下の通りとなります。コメントアウトで説明をつけておきます。
// backLink関数を定義
function backLink() {
// 現在表示されているページのURLを取得
var url = location.href;
// ホストネームとポート番号を同時に取得
var domain = location.hostname;
// 参照元のページのURLを取得
var referrer = document.referrer;
// 記事ページのURLの正規表現
var regexp1 = new RegExp("^https?:\/\/" + domain + "\/archives\/[0-9]+$", "i");
// 現在表示されているページのホストネームの正規表現
var regexp2 = new RegExp("^https?:\/\/" + domain, "i");
// #blog-titleをjQueryのオブジェクトとして取得
var blog_title = $("#blog-title");
// #blog-title内のa要素を取得
var blog_title_link = blog_title.find("a");
// #blog-title内のi要素を取得
var blog_title_icon = blog_title.find("i");
// 「表示されているページが記事ページにマッチ」
// かつ「リンク元が当ブログのページにマッチ」
// かつ「リンク元が記事ページにアンマッチ」であった場合
if (url.match(regexp1) && referrer.match(regexp2) && !referrer.match(regexp1)) {
// i要素のclass属性に「fa fa-arrow-circle-left」を指定
// =>アイコンを「矢印」マークに変更
blog_title_icon.attr("class", "fa fa-arrow-circle-left");
// a要素のhref属性(リンク)を参照元のURLに変更
blog_title_link.attr("href", referrer);
// if文内の条件でなかった場合
} else {
// i要素のclass属性に「fa fa-home」を指定
// =>アイコンを「ホーム」マークに変更
blog_title_icon.attr("class", "fa fa-home");
// a要素のhref属性(リンク)をトップページに変更
blog_title_link.attr("href", "/");
}
}
// ページの読み込みが終わったらbackLink関数を実行
$(document).ready(function () {
backLink();
});
機能の実装は以上となります。挙動に関しては、実際にこちらのブログ内を遷移してお確かめください。
コメント