特定のrel属性を持つアンカーにclassを付与する(JavaScript)

rel属性は持っているけれどもclassは持っていないアンカー…
このサイトでわかりやすく言うと、liteboxが設定されているアンカーに対して、
後からまとめてclassを付けてしまおう、というお話です。


なぜそんなことを?というのはあとで書くとして、
実行部分のスクリプトはこんな感じ。

var anchors = document.getElementsByTagName("a");
var isIE = (navigator.appName.indexOf("Microsoft") != -1) ? true : false;
for (var i=0; i<anchors.length; i++){
var anchor = anchors[i];
var relAttribute = String(anchor.getAttribute('rel'));
if (anchor.getAttribute('href') && (relAttribute.toLowerCase().match('lightbox'))){
(isIE) ? anchor.setAttribute('className', 'test') : anchor.setAttribute('class', 'test');
}
}
ページ読み込み後に実行することで、アンカータグにtestというclassを付与できます。

実はこれ、litebox用ライブラリから持ってきたコードが元ネタです。
最初はライブラリを書き換えたんですが、バージョンアップしたときのことも考えて、
独立させておきました。

処理自体は、まずアンカータグを列挙し、それぞれについてrel属性の有無をチェック。
rel属性があったらそれがlightboxであるかをチェックするという感じの手順。
わかりやすい。



IEとその他のブラウザとで処理を分けているのは、
どうも、setAttribute()の挙動がIEとFireFoxとでは違うらしい…ということから。
詳しくはこちら。

IE の getAttribute / setAttribute: Days on the Moon

簡単に書くと、FireFoxは素直にclassというキーを渡すことでclassが追加できるのだけど、
IEの場合はそれだと追加できないので、
代わりにclassNameというキーを渡して上げる必要があるということみたい。



で、コレをonloadのタイミングで動かしてやれば問題なく動く、と。

onloadについては、同じタイミングで結構沢山の処理がなされてるので、
その整理のためということも含めて、こちらを参考に適当に設定。

thinkのScrapBook: addEventListener(), attachEvent() を使ってaddLoadEvent()




なぜコレが必要になったか?

このサイトでは、アンカータグに破線の下線が引かれています。

リンク
リンク

これはリンク内容が画像の場合でも同じです。


画像にリンクしたときの枠線を消す方法としては、
通常、画像にborder:none;を指定してやれば実現できますが、


一方でエントリ内の画像には1pxの枠線が引かれているのです。
それが一緒に消えちゃうって言う(しかもアンカー部分は残る)。
そう言うわけで、その手法はとれません。

代わりにアンカーにclassを付けてやれば、問題は回避できますが、


a.NoBorder {
border: none;
}

これだと、投稿時にclass名を付けていかないといけない…結構コレが面倒で。



もし、『ある子要素を持つ親要素』という形でCSSを適用できるともっと楽なんですが、
あいにくそういう適用のさせ方は出来ないようなので…
では、class名を自動的に挿入するしかないなってことで。



…あ、もちろん、class名ではなく直接CSSを設定しても良いと思います。

var anchors = document.getElementsByTagName("a");
var isIE = (navigator.appName.indexOf("Microsoft") != -1) ? true : false;
for (var i=0; i<anchors.length; i++){
var anchor = anchors[i];
var relAttribute = String(anchor.getAttribute('rel'));
if (anchor.getAttribute('href') && (relAttribute.toLowerCase().match('lightbox'))){
(isIE) ? anchor.style.cssText='border: none;' : anchor.setAttribute('style', 'border: none;');
}
}

この方が汎用性はあるかもしれませんね。