FlickrBadgeを別ウィンドウで開く。


Flickrの写真をブログに表示できるFlickrBadge。

Flickr: Make a badge

便利なのでこのサイトでもTOPページに貼り付けています。
何か脈絡無い並び方がそれはそれで味が。


で、それは良いんですが、1つだけ気になったこと。
画像をクリックしたときに同じウィンドウで画像のページに遷移するんですね。

アクセシビリティとしてはその動作は正しくて、
別ウィンドウで開きたかったらユーザ側がshiftを押しながらクリックすれば良いだけ。
別ページで開かせたいってのは制作者の主観的な思いこみユーザビリティ…
そうなんだけど、Flickrのページは大体重くて開くのに時間が掛かるし、
出来たら別ページで開けたらなぁと思って。

FlickrBadgeはJavaScriptで記述されていて、
そのHTMLを変えるのは難しいんだけど何とか実装してみた。

以下、まとめ。


参考にしたのは以下のエントリ。

cl.pocari.org – target=”_blank” を使わないで新しいウィンドウでリンクを開く方法

このエントリでは、prototype.jsをベースにして、
特定のクラス内にあるリンクを別ウィンドウで開く…というようなことをしている。みたい。

Prototype JavaScript framework: Easy Ajax and DOM manipulation for dynamic web applications


これを、targetが指定されていなくても別ウィンドウで開くことが出来ると読み替えてみると、
FlickrBadgeの構造からして、クラス名に『flickr_badge_image』を、
割り当ててやれば行けるんじゃないかと推測。

FlickrBadgeのHTML構造(抜粋)
<div id="flickr_badge_image1" class="flickr_badge_image">
<a href="画像のURL">
<img width="75" height="75" title="画像タイトル" alt="A photo on Flickr" src="サムネイルURL"/>
</a>
</div>

で、その下にあるhrefを持って来て…いるはずが、
なぜか持ってくるのは一番下の要素のsrc(サムネイルURL)。
これはgetAttribute()の仕様が、

getAttribute()

指定した属性の値を読み出す。
複数の同じ名前の属性がある場合は最後の属性が適用される。

となっているため、一番奥の要素(つまりimg)を引っ張ってくるということらしい。
なぜhrefとsrcを一緒に扱うかはよく分からないけど。


美しい方法が思い浮かばなかったので、取得することになるimg要素の、
親要素のhrefを取得するとか言うことをでっち上げて、何とか実装。



PopupWindow 12行目
var link = element.getAttribute('href');
↓
var link = element.parentNode.getAttribute('href');


FlickrBadge以外に応用が利かない、残念なプログラムだけど、動くと言うことで…


popup.js(FlickrBadge専用)

var PopupWindow = Class.create();
PopupWindow.prototype = {
initialize: function(className, parentElement) {
var elements = document.getElementsByClassName(className, parentElement);
for (var i = 0, len = elements.length; i < len; i++) {
Event.observe(elements[i], 'click', this.addPopupEvent.bindAsEventListener(this));
Event.observe(elements[i], 'keypress', this.addPopupEvent.bindAsEventListener(this));
}
},
addPopupEvent: function(event) {
var element = Event.element(event);
var link = element.parentNode.getAttribute('href');
window.open(link);
Event.stop(event);
}
};


HEADへの記述

<script type="text/javascript" src="/js/prototype.js"></script>
<script type="text/javascript" src="/js/popup.js"></script>
<script type="text/javascript">Event.observe(window, 'load', function(){new PopupWindow('flickr_badge_image');});</script>