車輪の再発明どころか、発明という言葉を用いるのもおこがましい作業ですが、ともあれこのウェブログのサイドバーの表示・非表示を切り替える(トグルする)機能を追加しました。検索ボックス近傍サイドバー上部にある「段組非表示」「段組表示」という箇所が切り替えの引き金です。通常は二段組みの割り付けですが、サイドバーを非表示にすると本文部のみを表示させることが出来ます。
やっていることは極めて単純です。
- サイドバーのスタイルをJavaScriptで切り替える。
document.getElementById('komplemento').style.visibility = 'visible';するか、或いは'hidden';する。厳密にはdisplay = 'none';かdisplay = 'block';を切り替えても良い。サイドバーという用語自体、GUIなユーザエージェントを念頭としたもので気にくわないので、内部的には補足(komplemento)というid属性を与えているのですが、それはさて措いて。 - 本文部の左余白をJavaScriptで切り替える。
document.getElementById('universala').style.marginLeft = '1em';するか、或いは'14em';する。 - 表示・非表示の切り替えリンクも同様に表示・非表示を切り替える。
- 上記をCookieに保存する。
委細はソースのstandardo.jsをそのままご覧いただくとして、ここでは意外にも蹴っ躓いた点を備忘録的に記述しておきます。
for … inの罠
JavaScriptではまったのは、クッキー(Kuketo; 英Cookie)の扱いについてです。Perlなら明らかにハッシュを使うべき場面であり、JavaScriptでも同様に連想配列(辞書配列)であるハッシュを使っているのですが、for in構文に思わぬ罠があったという次第です。
予め文字列を’; ‘という区切り文字(デリミタ)で配列化し、それぞれの配列スライスについてさらに’='を区切り記号(デリミタ)にしてキー=値というように代入する、という処理は、例えばPerlなら以下のように書くところです(論点を絞るため、クッキーがない場合の処理等は省いています)。
my %agordo;
foreach my $vico_de_kuketo (split '; ', $ENV{'HTTP_Cookie'}) {
my ($klavo, $valoro) = split '=', $vico_de_kuketo;
$agordo{$klavo} = $valoro;
}
単純にJavaScriptに移植すると、以下のようなコードになるでしょう。
var agordo = new Array;
for (var vico_de_kuketo in (document.cookie).split('; ')) {
var klavo_kaj_valoro = vico_de_kuketo.split('=');
agordo[klavo_kaj_valoro[0]] = klavo_kaj_valoro[1];
}
ところが、IE等でどうにも謎の挙動(キーと値が逆)を起こすのでGoogleにお伺いを立てたところ、ウェブログiandeth.の配列を for .. in でまわすワナという記事等々が見つかりました。
言語仕様と実装が違うなら違うで統一されていればまだ可愛げがあるのですが、ユーザエージェント(ブラウザ)毎の非互換性までがあげつらわれているとなると、流石に君子ならずとも危うきに近寄らずということで、foreach的に楽をすることを諦め、素直に添え字をforで回して処理をすることにした次第です。
XSS(クロスサイトスクリプティング)の防止
これは今回判明・対応したものではないのですが、関連するネタなのでここで併せて書いておきます。
このウェブサイトでは、独自ドメインであることをいいことに、好き勝手にサブドメインを立てています。さてここで、Perlのライブラリやらフォーチュンクッキーのスクリプトやらは、XREAから割り当てられた公開領域(/virtual/ermitejo/public_html/)の直下のディレクトリbibliotekoというディレクトリに保存しています。今回の外部jsファイルもこのディレクトリに置きたいのですが、このblogoサブドメイン配下のファイルからtttというデフォルトのサブドメイン配下のURI(http://ttt.ermitejo.com/biblioteko/…)を指定すると、XSS(cross site scripting; skribado inter kruca retejo; クロスサイトスクリプティング)としてセキュリティ的に好ましからざる状況が生起してしまいます。
かといってblogo.ermitejo.com用の直下にbibliotekoを作ってコピー運用で同期管理をするのもあほらしい話です。
これは単純で、(XREAの場合にはSSHで)telnetして、ln -sでシンボリックリンクを張れば解決します。実は最初から怪しいと思って、敢えてblogoサブドメインからtttサブドメイン配下のJavaScriptを呼んでいないので、実際にXSSを行ってみた訳ではありません。もしかしたらサブドメイン間でも何とかなるのかも知れません。
なお、こうしたXSSの問題がないCSS等のファイルはstiloサブドメイン用のディレクトリに、画像はbildoサブドメイン用のディレクトリに、それぞれ置いてサブドメイン間をまたがって呼んでいます。
その他諸々
その他、末梢的な事柄として、以下のようなことを気にしましたので列挙してみます。
- トグルの引き金となる箇所(「非表示」「表示」)は、リンク(a要素)ではなく単純なspan要素とした。a要素のhref属性にスクリプトを書くのはXHTML的に正しくないし、onclick属性でスクリプトを書く場合にはhref属性の値は’#”とする必要があるので、審美眼に適わない。rel=”nofollow”すればSEO的に問題がないのかも知れないが、あれこれ考えるのも無駄なので素直にa要素は諦めた。
- a要素でなくても、ユーザにとってあたかもa要素であるかの如く捉えていただくため、引き金となる文字列の色やポインタはリンクと同じものとした。
- 引き金となる文字列にサイドバーは意地でも使わないと決めたのだが、かといえ段組という語もGUIユーザエージェントが前提なので如何な物か……。
- やっぱり変数名・関数名はエスペラント書きだよね。
- 表示・非表示はJavaScriptによって制御しているので、この機能を切っているユーザは引き金となる文字列が見えないようにした。
- 添付ファイル用ページ(attachment.php)では最初からサイドバーを表示していないので、引き金箇所を表示しないようにした。具体的には、header.phpにて
<? php if (is_attachment()) : ?>などとして限定した。 - いざ非表示にしてみた場合、各ページがどれも同じように見えてしまうことに今更ながらに気付かされた。WordPressのテーマを工夫し、インデックス的ページ・カテゴリ別ページ・日付別ページ・記事パーマリンクといったそれぞれの表現を改める必要がありそう。
まとめ ~ 携帯端末に優しい対応
そもそも何でまたこのような処理を思い立ったかというと、Advanced W-ZERO3[es]で本サイトを閲覧した場合、縦画面だと横方向が480pxしか存在しないため、サイドバーがあるばっかりに文章の折り返し幅が極めて狭くなってしまう問題に日頃悩ましく思っていたという事情があります。
W-ZERO3は3系統全て(WS003SH, WS007SH, WS011SH)を持っているのですが、代を追う毎にDPIが増しているので、精細な画面という言葉の裏側には文字の絶対的な小ささという罠が存在します。とすると両眼の視力が1.5以上とはいえシステム屋ですと眼精疲労も激しいために、最小文字サイズをWS003SHの時よりも大きめに設定するしかなく、そうすると画面に表示される文字数が減るという二律背反にあります。
こうした煩悶を打開することが出来て少しだけ幸せな気分になれました。辞書引き機能のカスタマイズ(ユーザ毎に設定を変更・保存可能にするもの)へ向けたプロトタイプとして作ってみたのですが、実りの少なくない体験を行うことが出来たように思います。
やっぱりエスペラント書きだよね。の文でほほえみました。いろいろ考えておられるのですね。
Comment by Enkampo — 2007/10/04 木曜日 @ 02:02:19