ヘッダやメニューなど共通部分を外部ファイルに - 応用編
公開:2015-07-26
更新:
ブログやホームページのヘッダやメニューなど共通部分を外部ファイル1つにし、各ページから読み込む方法です。変更が1ファイルで済みメンテナンス性が向上します。
前回基本編のまとめにもなっており、制約や条件、デメリットとメリット、注意点です。基本編で正常にできなかった場合の対処にもなると思います。
制約や動作条件
条件として以下が必要です。
- 共通部分の別ファイルもUTF-8で保存。
- 見る側のJavaScriptが有効であること。無効だと全く表示しません。
- 読み込む共通部分の別ファイルは同一ドメイン(サイト)。(別ドメインから読み込む方法もあるようですがここでは触れません。)
通常さほど問題ないかと思います。
デメリットとメリット
デメリット
- jQuery本体や共通部分を読み込む分、速度が遅くなります。変更のあるメニューなどはともかく、変更のない部分で行う効果があるかどうかです。
- 共通部分のHTMLがユーザーのキャッシュに残る場合があり、その場合更新してもしばらく古い情報のままになってしまいます。ページは新しいのにメニューは古いなどとズレる可能性もあります。cache:falseや.htaccessでキャッシュ制御するなどの対処が必要になってくるかもしれません。
メリット
- メンテナンス性。これが目的と言っていいでしょう。
- CSSの変更不要。
- $(this)も使用可能。
- 読み込みエラーの対処もできます。ご自分のサイト内でその可能性が低い場合はそこまでの記述はなくてもいいと思います。
注意点
読み込まれる場所
読み込まれる場所にあった要素は全て削除されます。この例では#navi自体は残り、その中に各要素があったとしても置き換えられます。
URL
aやimgタグなど、URLは読み込まれた後の状態が有効になります。共通部分を既存のHTMLから抜き出す場合はそのままで問題ありません。相対URLで可能です。
jQueryのバージョン
load()は、ローカルではjQueryのバージョンで動作が異なります。
- 1.x の場合:ローカルでもサーバーでも読み込む。
- 2.x の場合:ローカルでは読み込まず、サーバーでは読み込む。
制作の容易な1.xか、パフォーマンスのいい2.xか、どちらを選ぶかです。
共通ファイルのHTML構文
前回基本編で共通部分を抜き出したmenu.htmlは以下のように、取り込む必要部分のみで<!DOCTYPE html> <html> <head> <body>
などのHTMLとしての構造なしで行いました。
<ul> <li>メニュー1</li> <li>メニュー2</li> <li>メニュー3</li> <li>メニュー4</li> </ul>
これで問題なくできればいいのですが、あるサーバーでは読み込みできませんでした。そこで最低限HTMLとして成り立つ(単独で表示できる)構造にし、その一部のみを読み込んだらできました。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> </head> <body> <ul> <li>メニュー1</li> <li>メニュー2</li> <li>メニュー3</li> <li>メニュー4</li> </ul> </body> </html>
$('#navi').load('menu.html ul');
loadの' '内をスペースで区切ることで読み込まれた後そのセレクタ(ここではul)のみが挿入されます。共通部分にIDセレクタが指定してあれば#~でもできます。
動的要素としての対処
これも注意点の1つですが特に別項目としました。読み込まれた共通部分は従来通りjQueryで、セレクタ・メソッド・要素(DOM)・イベントとして操作可能ですが、そのままだと動作しない場合があります。
コールバック
読み込まれた共通部分にjQueryで処理する場合はコールバック関数にします。
動作しません
$('#navi').load('menu.html'); $('li').addClass('hoge');
動作します
$('#navi').load('menu.html',function(){ $('li').addClass('hoge'); });
(試す場合はCSSで.hogeに何かクラスを与えてください。)
イベント
読み込まれた共通部分にjQueryでイベント処理する場合、動的要素に対応した書式にします。
動作しません
$('#navi').load('menu.html');
$('li').click(function(){
$(this).append($('!'));
});
動作しません
$('#navi').load('menu.html');
$('li').on('click',function(){
$(this).append($('!'));
});
動作します
$('#navi').load('menu.html');
$('#navi').on('click','li',function(){
$(this).append($('!'));
});
またはコールバックで動作します。
$('#navi').load('menu.html',function(){
$('li').click(function(){
$(this).append($('!'));
});
});
このコールバックで書かれたデモが以下です。クリックされたメニュー(li)の末尾に"!"を追加していきます。