トップページ

2006年02月17日

続・ジオシティーズ広告スクリプトの不具合

Mozilla/Firefoxをご利用の皆さまにおかれましては、geocities.jpのページを表示したとき、縦長の広告バナーの表示される位置が、画面の右端だったり左端だったりする現象をご覧になったことがあるかもしれません。これは、この現象が、またしてもジオシティーズ謹製のJavaScriptの不具合によるものでしたよ、というハナシ。

事の発端は、およそ1年半ぶりに行った、geocities.jpに置いてあるラ・コルーニャへの道の手直し。と言っても新しい内容を加えたわけではなく、目的のひとつは古くなっていたリンクなどの修正で、特にCRTVGのウェブサイトのリニューアルに伴い、動作しなくなっていた「ガリシアヲチ」ツールバーの修正とか。まあ、このあたりは本題とは関係なく。

で、もうひとつがHTML(の構造)とスタイルシートの書き直し。
これはなにかと言うと、これを作った当時、ジオシティーズの広告スクリプトはドキュメントの先頭(つまりDOCTYPE宣言より先)にインクルードされる場合があり、このためHTML/CSSの記述は、Quirksモードで描画されることを前提にしなければならなかったわけです(この当時のハナシはこちらにありますが、この記事は、ジオシティーズの広告スクリプトの変更に伴い無意味なものになっているため、このサイトには移してません。なお、「DOCTYPE宣言とかQuirksモードってナニ?」というかたは、例えばこちらとかをどーぞ)。
で、しかし確か昨年の夏頃に、ジオシティーズの広告スクリプトが全面的に変更され、少なくとも自分の知る限り、ドキュメントの先頭にインクルードされるということはなくなっていたので、ならばHTML/CSSをStandards Compliantモード向けに作り直そうか、と。

てなことで、手直しを施したファイルをアップロードしてFirefoxで表示してみると、広告バナーが左端に表示される。IE6では右端に表示される。これは、「Firefoxは左」という仕様なのか?と思ったのですが、確かFirefoxでも右端に表示されるページを見た覚えがあるので調べてみたらば、またしてもジオシティーズのJavaScriptの不具合が原因だということが判明したという次第。

さて、今回問題を起こしているのは、インクルードされるSCRIPT要素で読み込まれるJSファイルのうち、div.jsの、以下の部分。

function auPos(divId) {
  posL = findX() -177;
  if (ns4) {
    posL='1';
    document.layers[divId].visibility = "show";
    document.layers[divId].left = posL;
  } else if (ie5 || ns6) {
    document.getElementById(divId).style.visibility = "visible";
    document.getElementById(divId).style.left = posL;
  } else if (ie4) {
    document.all[divId].style.visibility = "visible";
    document.all[divId].style.left = posL;
  }
}

このファンクションauPos()は、広告バナー部分の各DIV要素について、ウィンドウの左端からの位置を設定するもので、各DIVのstyle.leftを、(変数posLに格納された)ファンクションfindX()が返すウィンドウの内側の幅から、177(広告バナー部分の横幅)を引いた数値に設定しようとします。
で、問題は、style.leftに設定されるのが数値であるために起こります。スキモノの皆さまはお気付きかと存じますが、本来CSSでは、この手の類には単位指定が必須なわけで。しかし、ここでは単位が省略されてしまっているため、Standardsモードで動作しているGeckoエンジンでは、この設定は不正だとして無視され、結果、広告バナー部分の左端の位置は設定されずじまいとなります。
一方、ウンコな仕様でお馴染みのInternet Explorerは、描画モードに関わらず、単位が省略されていると、単位はピクセルだと勝手に解釈しやがるので、このスクリプトは、その作者の本来の意図通りに動作し、またGeckoエンジンも、Quirksモードでは同様の動作となるため、Mozilla/Firefoxでは、Quirksモードで描画されるHTMLに限っては、やはり作者の本来の意図通りに動作してしまうのでした。

ちなみに、この広告バナー用のスタイルシートであるdiv.cssを見ると、ご丁寧なことに、数値がゼロの場合のみ単位が指定されていて、それ以外は省略されてたりします。逆だっつうの。

さて、しからばもう一度Quirksモード向けにHTML/CSSを作り直すかというと、それはメンドくさい、というかいい加減にしてくれ。
てなことで、またぞろ修正用のスクリプトを用意してみたあるよ。各HTMLファイルに以下のスクリプトを書いたJSファイルを読み込むscriptタグを追加し、そのbodyタグに「onload="fixGeocitiesBug()"」を追加。

function fixedAuPos(arg) {
  document.getElementById(arg).style.left = document.body.offsetWidth?
    (document.body.offsetWidth -177) + 'px': (findX() -177) + 'px';
}
function fixedRlPg() {
  fixedAuPos('y_gc_div_adcntr');
  fixedAuPos('y_gc_div_au1');
  fixedAuPos('y_gc_div_mast');
}
function fixGeocitiesBug() {
  if (document.getElementById
    && document.getElementById('y_gc_div_adcntr')
    && !document.getElementById('y_gc_div_adcntr').style.left) {
    fixedRlPg();
    onresize = fixedRlPg;
  }
}

onloadでの処理なので、ドキュメントの読み込みが完了するまで、広告バナーはウィンドウの左端に居座ってしまいますが、それはしょうがない(なにかいい対策をご存知のかたは教えてくださいな)。

なお、ファンクションfindX()を使用した元々のスクリプトが返す左端の位置をそのまま適用すると、Mozilla/Firefoxでは広告バナーの右端がウィンドウの右端から若干はみ出る(横スクロールバーが表示される)ため、ここではdocument.body.offsetWidthを使用しています。これはもちろん、ウィンドウの幅ではなくBODY要素の幅なわけで、(広告バナー部分の横幅である177を差し引いている)上のスクリプトでは、BODYのmargin値がゼロの場合に、ウィンドウの丁度右端に広告バナーは位置することになるわけですが、このように、BODYのmargin値に応じて、差し引く値を調整する必要があるです。

Category: ウェブ制作
Posted 2006年02月17日 23:30

トラックバック

このエントリーのトラックバックURL:
http://www.rcdtokyo.com/mt/mt-rcdtokyo5428-tb.cgi/708

コメント

コメントをどうぞ



保存しますか?


Aoaka Style Valid Aoaka