2011年6月12日日曜日

ブログ画像のポップアップ表示を簡単に導入する方法③ 問題解決編

前回記事で ポップアップ・ライブラリを導入した場合の問題点の分析を行いました(ポップアップ・ライブラリ問題点の比較)。ブログにポップアップ・ライブラリの導入を試したときの問題としては2点ありました。

  • 直リンクでない画像は表示できない
  • IE でエラーが発生する
これらについての解決方法を、今回考えていきます。まず比較的簡単に解決する IE の問題から書いていきます。

IEでのエラーとその解決法
IE では次のエラーメッセージが表示される(左および下)。
Message: Object doesn't support this property or method
Line: 8159
Char: 6
Code: 0
URI: http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.js
IE 日本語版のメッセージ
オブジェクトでサポートされていないプロパティまたはメソッドです。

私の環境と併せてエラーをネットで検索すると、どうも SyntaxHighlighterZenbackコンフリクトしているのが原因らしい。そこで SyntaxHighlighter を一時的に無効にしてみると、問題なく表示するようになった。

SyntaxHighlighter は、よく使っているので恒常的には外すことはできない。SyntaxHighlighter に的を絞って、さらに検索すると・・・・あった。

参考: bitbucket alexg syntaxhighlighter #220 IE-only conflict with jQuery animate() method

SyntaxHighlighter のバグ?らしい。原因は XRegExp.js にあるようだ。XRegExp.js は JavaScript の正規表現を拡張するライブラリのようだ。親切な人が XRegExp の問題箇所を修正し、さらに SyntaxHighlighter の shCore.js をコンパイルして 貼り付け てくれている。

このファイルをダウンロードし、元の shCore.js と入れ替えて、動かしてみる・・・動いた。あまり納得できないが、これでエラーは発生しなくなるようだ。Zenback に関しては、私の環境では特に問題はなかった。

直リンクではない画像をポップアップ表示する方法

次に直リンクでない画像をポップアップ表示する方法を考えたい。まず直リンクでない画像URLは問題があるため、直リンク画像URLに変換できないだろうか?。

Picasaウェブアルバムの「画像を埋め込み」から貼りつけた画像リンクの html は、次のようになっている。

<a href="https://picasaweb.google.com/lh/
photo/Q4YLiCjVmC-EYphLaZRfGcsKua9avpxkz29wiKETsMI
?feat=embedwebsite">
<img src="https://lh3.googleusercontent.com/
-ydgqX89an8c/Te1i4f2Uv_I/AAAAAAAABPU/3-WtNiYXosw/
s144/sky_beiz.jp_S32572.jpg" height="96" 
width="144" />
</a>

前々回の記事の 当ブログでの画像の取扱い方法について でも解説したが、アンカータグの href 属性の URL は画像の直リンクではない。では img タグの src 属性の URL はどうかというと、直リンクになる。この src属性の URL をよく見てみる。

https://lh3.googleusercontent.com/-ydgqX89an8c/Te1i4f2Uv_I/AAAAAAAABPU/3-WtNiYXosw/s144/sky_beiz.jp_S32572.jpg
赤字の部分 /s144 は、画像サムネイルの大きさを定義している箇所だ。この数値を次の数値に変えることにより、画像の大きさを変更できる。
72 144 200 288 320 400 512 576 640 720 800 912 1024 1152 1280 1440 1600
画像の大きさというのは横幅のピクセル値のことである。上記欄の数字以外は受け付けない。なぜなら Picasaウェブアルバムにアップロードした時点で、これらの大きさの画像を生成する仕組みだからである。また、元の画像より大きな数字を指定しても拡大はしない。それでは、/s144 の部分を削除したらどうなるだろうか?。それは元の画像への直リンクになる。

参考: WebTipsBox - Picasaで自動的に作成されるリサイズされた写真の指定方法

「画像の直リンクが判明しましたね」
「あとは JavaScript でアンカータグの href 属性を書き換えればいいのですね・・・・・」

などと思うかもしれない。それもでよいのだが、このために便利な機能を持っているポップアップ・ライブラリがあるのだ。

SlimBox のダウンロードファイルの中に、extra というフォルダがある。さらにこのフォルダに picasaweb.js ファイルがあるので中身を見てみる。

if (!/android|iphone|ipod|series60|symbian|windows ce|blackberry/i.test(navigator.userAgent)) {
    jQuery(function($) {
        $("a[href^='http://picasaweb.google.'] > img:first-child[src]").parent().slimbox({}, function(el) {
            return [el.firstChild.src.replace(/\/s\d+(?:\-c)?\/([^\/]+)$/, "/s512/$1"),
                (el.title || el.firstChild.alt) + '<br /><a href="' + el.href + '">Picasa Web Albums page</a>'];
        });
    });
}

上のコードは SlimBox の linkMapper という機能を使用している。

'http://picasaweb.google.' が含まれるアンカーリンクの子要素 img に src 属性が存在した場合に、linkMapper を利用して画像直リンクに切り替えている。
同じように、直リンクに切り替えたい URL の一部をセレクタで指定してあげればよい。picasaweb.jsでは画像の大きさを /s512 で指定しているがこれも変更してもよい。

他のライブラリにも同様の機能はないだろうか?・・・。FancyBox も同じような機能を持っている。FancyBox はオプションの形で指定する。

直リンクではない画像をポップアップ表示する設定例

SlimBox2 と FancyBox の直リンクの設定方法と設定例を示していく。

SlimBox2

設置に関しては、前記事 SlimBox2 も参照して欲しい。

linkMapperは SlimBox の第二パラメータとして設定する。

jQuery(expression).slimbox(options, linkMapper, linksFilter);
また linkMapper のパラメータは次のフォマットで渡す。
jQuery(expression).slimbox({}, 
  function(el) {
    return [el.href, el.title];  // el.href  : 画像URL
  }                              // el.title : 画像タイトル
);

つまりセレクタが選択したエレメントからの、画像URLと画像タイトルの取得方法を記述するということのようだ。

参考: SlimBox2 - Enabling HTML DOM elements (such as links) to launch Slimbox when clicking

それではサンプルコードを示してみたい。次のコードは html の head タグ内に追加するものだ(xxxxxはアップロード先サーバなどのパス)。

 
<link href='http://xxxxx/css/slimbox2.css' media='screen' rel='stylesheet' type='text/css'/>
<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js' type='text/javascript'/>
<script src='http://xxxxx/js/slimbox2.js' type='text/javascript'/>
<script type='text/javascript'>
if (!/android|iphone|ipod|series60|symbian|windows ce|blackberry/i.test(navigator.userAgent)) {
  jQuery(function($) {
    $("a[href*='picasaweb.google.com']:has(img)").slimbox({}, function(el) {
      return [el.firstChild.src.replace(/\/s\d+(?:\-c)?\/([^\/]+)$/, '/s640/$1'),
      (el.title || el.firstChild.alt)];
    });
    $("a[href*='bp.blogspot.com']:has(img)").slimbox();
    $("a[href*='up.seesaa.net']:has(img)").slimbox();
  });
}
</script>
今回、セレクタによる SlimBox の設定が3つある。
  • 7行目は、Picasaウェブアルバムの直リンクでない画像 URL を直リンク画像 URL に切り替えている。この時、画像の大きさを横幅 640 ピクセルに変更している。もう少し細かく解説すると、
    • アンカータグのhref属性値に'picasaweb.google.com'が含まれるエレメントの中で、imgタグが含まれるを SlimBox の処理対象とする
    • この時の画像URLは最初の子要素のsrc属性の値を使う
    • 画像URLに含まれる/sxxxの値は/s640に変換する
  • 11行目は、blogger画面からアップロードしたファイルのポップアップを定義している。このアンカーリンクの URL は直リンクのため、通常の方法で割り当てている。
  • 12行目は、外部サーバに保存している画像の処理を定義している。過去記事はリンクを直していないため、画像リンクが以前使用していたブログサービスを指している。これらの画像もポップアップできるように定義している。

このように自分の環境にあわせて、セレクタの定義を行えばよい。


 
FancyBox

設置に関しては、前記事 FancyBox 1.3 も参照して欲しい。

FancyBox はオプションの一つとして、href の値を渡してあげればよい。

jQuery(expression).fancybox({'href':xxxxx});

xxxxx に画像URLを設定する。

参考: fancybox - api & options

それではサンプルコードを示してみたい。次のコードは html の head タグ内に追加するものだ(xxxxxはアップロード先サーバなどのパス)。

 
<link href='http://xxxxx/fancybox/jquery.fancybox-1.3.4.css' media='screen' rel='stylesheet' type='text/css'/>
<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.js' type='text/javascript'></script>
<script src='http://xxxxx/fancybox/jquery.fancybox-1.3.4.pack.js' type='text/javascript'></script>
<script type='text/javascript'>
jQuery(function($){
    $("a[href*='picasaweb.google.com']:has(img)").each(function(){
      $(this).fancybox({'href': this.firstChild.src.replace(/\/s\d+(?:\-c)?\/([^\/]+)$/, '/s1024/$1')});
    });
    $("a[href*='bp.blogspot.com']:has(img)").fancybox();
    $("a[href*='up.seesaa.net']:has(img)").fancybox();
});
</script>
FancyBox のセレクタ設定も3つある。
  • 6行目は SlimBox 7行目とほとんど同じだが、(画像の大きさは調整せず)元の画像の直リンクに変更している (訂正 2012/10/19)画像の大きを 1024ピクセルに変更している(→ これは大きな画像をポップアップした場合、逆に小さく表示される問題の解決のためです。FancyBox には自動リサイズ機能があるため、画面状況に応じてポップアップ画像の大きさを調整します。)。
  • 9行目は SlimBox 11行目とほぼ同じ。
  • 10行目は SlimBox 12行目とほぼ同じ。

FancyBox の設定例は SlimBox 設定例とほとんど同じだが、SlimBox は画像URLを割り当てるときは関数パラメータとして渡すのに対して、SlimBox はオプション href の値として渡すという違いがある。


 
この他、注意点など

セレクタで、次のように画像を一気に割り当てることも可能だ。

$("a:has(img)").slimbox();
しかしブログ画面上のアイコンなど、予期しない画像まで選択する可能性がある。

SlimBox には画像のサイズ制限がなく、ポップアップに表示する画像の大きさを考慮する必要がある。このため、s640 のようにサイズを変更している。FancyBox はポップアップで表示する画像の大きさを自動的に制限するため、元の画像の URL を渡している。SlimBox の設定でも、Picasa ように画像の大きさを選択できるのなら問題はない。しかし選択できない場合などは、画面一杯に画像が表示されてしまう可能性もある。

以上 Bloggerと絡めて説明をしてきましたが、他のブログサービスでも同様に設定が可能だと思います。ブログの環境にあわせて設定を変更してください。また Blogger でも URL などは違う可能性があるので、調整してください。

次のページも参照してください。
ブログ画像のポップアップ表示を簡単に導入する方法④ AutoPager / AutoPagerize に対応させる