プラグインを使いたくない時はポップアップウィジェットを活用
一般にjQueryプラグインを使う場合は、プラグインの対応状況(ブラウザやOS)が重要になります。プラグイン自体に自分で手を入れる覚悟がない限り、プラグインが特定環境でうまく動かない時には利用を諦めて別の方法を探す必要があります。上で紹介したPhotoSwipeはiOSのSafariやAndroidのChromeブラウザでよく動作しますが、端末やブラウザの種類によっては画像が表示されなかったり、フリック時に画像がちらつくなどの事象が発生します。
そこで代替案としてリスト1を少々変更し、jQuery Mobile 1.2.0から導入された「ポップアップウィジェット」を用いて画像を表示する方法を紹介します。ポップアップウィジェットについては第14回の連載でも紹介していますので、参照してください。
最初にWebページの全コードをリスト2に示します。
<!DOCTYPE html>
<html>
<head>
<!-- 文字コード、viewportの設定 -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no" />
<!-- jQuery、jQuery Mobileの導入 -->
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.css" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.js"></script>
<script>
/**
* jQuery Mobileの初期化処理
*/
$(document).on("pageinit", function(event) {
// リストタップのハンドラ ......(1)
$(".gallery a").on("click", function(event){
// 本来のリンク処理を打ち消す
event.preventDefault();
// aタグのhref属性から画像URLを取得
var imgURL = $(this).attr("href");
// ロード中表示
$.mobile.showPageLoadingMsg();
// 画像を再ロード
$("#popup1 img").attr("src", null).attr("src", imgURL);
// リストの選択状態を解除
setTimeout(function(){
$("ul.gallery li").removeClass("ui-btn-active");
}, 100);
});
// 画像ロード完了時のイベント ......(2)
$("#popup1 img").on("load", function(event){
// ロード中表示を隠す
$.mobile.hidePageLoadingMsg();
// 画像をロード完了してからポップアップを表示する
$("#popup1").popup("open");
});
// 写真ポップアップの制御 ......(3)
$(".photopopup").on({
popupbeforeposition: function() {
// 写真ポップアップの最大高さを画面高さに合わせて制御
var maxHeight = $(window).height() - 100 + "px";
$(".photopopup img").css("max-height", maxHeight);
}
});
});
</script>
<title>ポップアップによる写真表示</title>
</head>
<body>
<!-- ページ -->
<div data-role="page">
<!-- ポップアップ ......(4) -->
<div data-role="popup" id="popup1" class="photopopup">
<a href="#" data-theme="a" data-rel="back" data-role="button"
data-icon="delete" data-iconpos="notext" class="ui-btn-right">閉じる</a>
<img src="" />
</div>
<!-- ヘッダー -->
<header data-role="header" data-position="fixed">
<h1>ポップアップ</h1>
</header>
<!-- コンテンツ本体 -->
<div data-role="content">
<ul data-role="listview" class="gallery">
<li>
<a href="img/001.jpg" rel="external">
<img alt="ヤギ" src="img/001_thumb.jpg"/>
<h1>ヤギ</h1>
<p>ヤギです...よね...多分...。</p>
</a>
</li>
<li>
<a href="img/002.jpg" rel="external">
<img alt="Xperia" src="img/002_thumb.jpg"/>
<h1>Xperia</h1>
<p>Android 4.2アップデート記念。</p>
</a>
</li>
<!-- 以下リストが続くが省略 -->
</ul>
</div>
</div>
</body>
</html>
リストを選択した時に表示するポップアップウィジェットを、(4)で記述します。ポップアップウィジェットのdivタグにphotopopupクラスを設定することで、写真の表示に最適化された表示になります。また、閉じるボタンも用意します。
リストを選択した時にポップアップウィジェットを表示する処理は、PhotoSwipeプラグインの時と同じようにpageinitイベントにおいて実行します。処理はリスト選択後に画像ロードを開始する処理(1)と、画像ロード後にポップアップウィジェットを表示する処理(2)、ポップアップウィジェットのサイズを調整する処理(3)に分かれます。処理が分かれているのは、画像のロード開始→完了後ポップアップウィジェットを表示開始→表示直前にサイズ調整→表示完了という処理の順番を保証するためです。
まず(1)では、aタグ本来のリンク先へ遷移する処理をpreventDefaultメソッドで打ち消した後、aタグのhref属性から画像URLを取得してポップアップウィジェット内に存在するimgタグのsrc属性に設定します。いったんnullを設定するのは、同一画像が複数選択された時にも画像ロードが行われて(2)の処理が確実に実行されるようにするためです。PhotoSwipeのときと同様、押下状態を強制的に解除する処理を追加しています。
(2)では画像ロード完了のイベント発生を受けて、ロード中表示を消してポップアップウィジェット表示を行います。(3)ではポップアップのサイズを調整しています。popupbeforepositionはポップアップウィジェットの表示準備が完了後、実際に表示される直前に発生するイベントで、このタイミングでポップアップ内の画像高さを調整しています。
リスト2をスマートフォンブラウザで表示すると、リストで選択した画像をポップアップで大きく表示できます。PhotoSwipeのように画像を切り替えることはできませんが、画像を大きく表示するという最低限の機能は実現が可能です。
まとめ
本記事では、jQuery Mobileで構築したスマートフォンWebページで画像をクールに表示するための手法を2種類紹介しました。PhotoSwipeプラグインを用いた方法は、よりスマートフォン的な操作性、jQuery Mobileのポップアップウィジェットを用いた方法は、jQuery Mobile自身の機能を利用することに由来する汎用性の高さが利点です。要件やサポートすべき端末の数によって、利用する手法を選択することになるかと思います。

