2012/07/03

"header"や"footer"を再利用する方法|jQuery Mobile

ヘッダーとかフッターをjQuery Mobile利用のサイト内で再利用する方法。


jQuery Mobile(jqm)ではAjaxを利用したページ遷移が基準となっている。

さらに、スマートフォン向けにUIを最適化までしてくれるため、
単純に外部ページの要素を読込むだけでは表示が上手くいかない。

ページ遷移については初期設定により通常リンクに変更することができるけれど、
UI最適化まで無効にしてしまったらjqmを使う意味がなくなってしまう。


そこでjqmの機能を最大限に活かしつつ部品(フッターなど)を外部ページから取り込む方法を考えてみた。


"部品"を集めたページを用意する|module.html

とりあえず読込まれる側のページを用意する。

このページから必要な部品を取り出して、jQueryのprepend()append()を利用して必要なページに埋め込む。

<!DOCTYPE html>
<html lang="ja">
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <section data-role="page">
   <header data-role="header">
    <h1>module header</h1>
   </header>
   <footer data-role="footer" data-theme="e" class="ui-bar">
    <h3>module footer</h3>
   </footer>
  </section>
 </body>
</html>

上記の例ではリンクを含んでないけれど、メニュー表示などの<a href="***"></a>を含む場合は、絶対URLで指定する。


"部品"を読込むためのスクリプト|module.js

スクリプトでしたいことは3つ。

  • 外部ページから"部品"を読込むこと
  • 読込んだ"部品"を埋め込んだ後にUI最適化すること(ランディング時や更新時用)
  • 最適化された"部品"を次のページに埋め込むこと(ページ遷移時用)
function module() {
 var head = $('#module :jqmData(role="header")').clone();
 var foot = $('#module :jqmData(role="footer")').clone();
 $(':jqmData(role="header"),:jqmData(role="footer")').remove();
 $(':jqmData(role="page")').prepend(head).append(foot).page().trigger('pagecreate');
}

$(function(){
 $('body').append('
'); $('#module').load('module.html div:jqmData(role="page")',function(){ $($(this).html()).replaceAll(this).attr('id','module'); module(); }); $(':jqmData(role="page")').live('pageinit',module); });

jqmは新たなページを読込むときに、だいたい次のようにページ遷移を表現する。

  1. 次のページを読込む(pageloadイベント)
  2. 次のページの表示を最適化する(pagecreatepageinitializeイベント)
  3. 前のページを隠す(pagehideイベント)
  4. 次のページを表示する(pageshowイベント)

例えば、2.の後に"部品"を埋め込んでもキレイには表示されない。

とはいっても、javascriptについてはjQueryとjqmが少し扱える程度の理解しかないので、
試行錯誤を繰り返した結果、たまたま上手くいったスクリプト。

ちゃんと理解している人が作ったらもっとスマートなものになるんだろう。


ちなみに

この方法を使うと、階層化リストの2階層以降で表示されるリストにもヘッダーとフッターを埋め込むことができる。

階層化リストではフッターを表示や指定することが出来ないので、フッターのモジュール化は応用ができそう。

ただ、ヘッダーに関してはモジュール化する必要性はあまり感じない。


あ、ダイアログへの埋め込みはについては考えてなかった。。。
$(':jqmData(role="dialog")')とかを上手に使えば上手くいくのかな?