onunload でハマりました

JavaScript の onunload でハマりました。

やりたかった事は、編集時のレコード単位のロックです。
編集画面を表示する際にロックして、編集画面を抜ける際にロックを解除しようとしました。

しかし、ブラウザの再読み込みをしてみると、ロックが解除されていました。

プログラムレベルでデバッグしましたが、問題はありませんでした。
どうも想定した動作順序になっていないようです。

普通に、表示中の画面のonunload > 次の画面の表示、と想定していました。
しかし、次の画面の表示 > 表示中の画面のonunload、の順に処理がされています。

まあ、次の画面を早く表示するための仕様と考えれば納得できますが、回避策となるとonbeforeunloadを使うぐらいでしょうか。
しかし、onbeforeunloadは更新の保存確認用に使用しており、ページの移動をキャンセル出来るようにしています。
onbeforeunloadイベントではページの移動がキャンセルされたかどうかは検出できません。

結局、各ページを表示する際にロックの制御をするようにしました。

JavaScriptではイベントの発生順序を考慮して処理を設計する必要があります。

PHPのswitch文を使いたおす

PHP言語の条件分岐には if文と switch文がありますが、あきらは比較的 switch文を使います。
if文だとごちゃごちゃする条件をすっきり書く事ができます。

こんな if文が

if ( ( n == a ) or ( n == b ) ) then {
X1 ;
} elseif ( n == c ) {
X2 ;
} else {
X3 ;
}

switch文だとこうなります。

switch ( n ) {
case a :
case b :
X1 ;
break ;
case c :
X2 ;
break ;
default :
X3 ;
}

条件が複雑な場合を考えてみます。
n == a などで統一されていない場合です。

こんな if文も

if ( ( a ) or ( b ) ) {
X1 ;
} elseif ( c ) {
X2 ;
} else {
X3 ;
}

こう書くことができます。

switch ( true ) {
case a :
case b :
X1 ;
break ;
case c :
X2 ;
break ;
default :
X3 ;
}

switch ( true ) として論理式を比較するのがミソですね。

画像関連プラグインのデバッグ

FCKeditor では、FLASH リンクなどについては編集領域でダミーの img タグを作成しています。
それをソースに変換する際に embed タグなどに変換しています。

このため、ImageAdjustor、Lightbox と Lighitbox_Plus プラグインでダミーの img タグかどうか判定する必要がありました。

また、Lightbox と Lighitbox_Plus プラグインで画像の再読み込みが必要な際に、 IE ではスクリプトバグとなり処理が中断されるバグがありました。

修正版を公開いたします。

ダウンロード

ImageAdjustor.zip
Lightbox.zip
Lightbox_Plus.zip

For FCKeditor 2.3.x
ImageAdjustor.zip
Lightbox.zip
Lightbox_Plus.zip

IE用デバッグプラグイン

FCKeditor を IE7 で使っていて、こんな現象が起こって困っていました。

画像(180x147)

編集領域に画像を貼り付けます。

画像(180x147)

この状態で編集領域をスクロールします。
すると、ツールバーのボタンがクリック出来ません。
右側のヘルプボタンなどはクリック出来ます。

画像(180x147)

どうやら選択した画像が邪魔をしているようです。
赤い線の内側のボタンがクリックできません。

IEの仕様と言われてしまうとそれまでですが、お客様にどう説明すれば良いのでしょうか。

2か月以上、あれやこれや解決策を検討して、実用上問題が無い方法が見つかりました。
このプラグインを使うと、上記現象を回避できます。

ダウンロード

debug_ie.zip

使用方法

1. ダウンロードしたファイルを解凍して出来たディレクトリ debug_ie を、FCKeditor のプラグインディレクトリにコピーします。

2. fckconfig.js に以下の行を追加します。

FCKConfig.Plugins.Add( 'debug_ie', null ) ;

ソースを読む方への参考

このプラグインは、以下のように動作します。

1. ツールバー領域にマウスが入った時、現在の選択領域が画像であれば選択領域を保存し、選択を解除します。

2. ツールバー領域からマウスが出た時、選択領域が保存されていれば復帰します。

3. ツールバーボタンがクリックされた時、選択領域が保存されていれば復帰してからツールバーのコマンドを実行します。

4. IE 特有のイベントである onmouseenter と onmouseleave を使っています。

onmouseenter と onmouseleave はかなり便利なので、早く Firefox でも実装されると良いのですが。
今回は IE 対策なので、都合が良かったと思います。

なんちゃってSSDの実験!(まとめ)

CF-IDE、SDHC-IDE と実験を行いました。ここで分析を行いたいと思います。

CrystalDiskMark 2.2 を使ってアクセス速度を計測しました。

画像(180x152)

FUJITSU MHK2120AT (2000/12製)
12GB/キャッシュ2M/4200rpm

当時では、まあこんなもんでしょうか。

画像(180x152)

CF-IDE変換アダプタ : AR-IDE2CF442
CF : Team Japan CF 16G/Multiword DMA 2

ランダム書き込みの性能がHDDの約 1/20 です。
しかし、ランダム読み込みはかなり早いです。

画像(180x152)

SDHC-CF変換アダプタ : MM-ADIDE2SD
SDHC : maxell 4GB SDHC Class6

ランダム書き込みの性能がHDDの 1/10 です。
4Kのランダム読み込み以外はHDDより遅いです。

画像(180x156)

(参考)
VAIO VGN-G2AAPS 内臓ディスク
SATA 1.8Inch

結構速いです。

結論です。

・CF-IDE、SDHC-IDE のメリットは、静音性・省電力。
・性能面ではあまりメリットがない。
・CF-IDE で若干起動時間が短縮される。
・今時のHDD(UrtraDMA/キャッシュ8M)を購入するのが妥当。

SSD を購入すればすべてクリアかもしれませんが、現在 32GB で 15,000円程度であり、個人で購入するには現実的では無いと思います。

で、後日 HDD を買ってしまいました。

画像(180x152)

HTS541680J9AT00
80GB/キャッシュ8MB/5400rpm

パソコン工房松江店で一番安かったものです。
ほとんど音がしないくらい静かです。

いろいろやってみた結果ですが、起動ディスクの性能は、直接体感速度として感じられるようです。
ディスクの選択方法としては、キャッシュが多いもの、回転数が大きいもの、平均シークタイムが短いものを基準に選ぶと良さそうです。

メモリを追加すると、メモリスワップが発生しにくくなるため、複数のタスクを実行した場合には体感速度として現れます。
しかし、ノートパソコンなどでは最大搭載可能メモリに制限があります。
ちょっと古いパソコンだとなおさらです。
ディスクを高速のものに変更すると、メモリスワップが発生した場合も反応がよくなります。
結局、パソコンの一番の弱点であるディスクに頼らざるを得ないわけです。

今回実験したパソコンは UrtraDMA 2 までしか i440BX チップが対応していません。
それでもかなりの性能アップになります。

OS の再インストールなど少し面倒ですが、1日かける価値は十分にあります。
DVDをスムーズに再生とは行きませんが、押し入れで眠らせているちょっと古いパソコンの HDD を交換して再利用するのも手です。

なんちゃってSSDの実験!(SDHC-IDE編)

なんちゃってSSDの実験!(CF-IDE編) に続いて、SDHC-IDE編です。

さて、パソコン工房には SDHC-IDE 変換アダプタの在庫が無かったので、通販で購入することにしました。

ハニーポッド
2.5inch IDE HDD変換カード MM-ADIDE2SD(バルク)2,480円

到着してさっそく Windows 2000 をインストールしてみました。
インストールに要した時間は、CF-IDE の時の約半分です。
「これは使い物になるかも」
と、思ったのですが、落とし穴がありました。

Windows Update をしようとするとエラーが…

ネットで調べてみると、リムーバブルディスクにインストールした場合、Windows Update はできないようです。
確認すると、確かに C ドライブがリムーバブルディスクと表示されています。
ちなみに、XP、Vista の場合は、インストール時にリムーバブルディスクにはインストールできないとはねられるようになっています。
試しに Vista を USB 接続のハードディスクにインストールしてみようとした時に、実際に体験しました。

なんとか回避できないかとネットで調べてみると、リムーバブルディスクを固定ディスクとして認識させるドライバーがあることがわかりました。

Windows XPをSDカード(SDHCカード)にインストールする

この記事では XP について解説しているため、一旦固定ディスク(eeePCでは内臓SSD)にインストールするようにしています。
前述したように XP、Vista はリムーバブルディスクにはインストールできないためです。
Windows 2000 の場合にはインストール自体は出来ているので、ハードディスクのドライバのみ更新すればよさそうです。

実際にドライバを更新してみると、ちゃんと固定ディスクとして認識されました。
Windows Update も正常に実行できました。

さて、実際の体感速度ですが…
やっぱり遅いですね…

CF-IDE では起動時間は速くなったと体感しましたが、SDHC-IDE では起動時間もさほど改善されたようには感じません。

うーん。

体感速度だけで判断するのも乱暴なので、ちゃんと分析してみることにします。

(まとめへ続く)

なんちゃってSSDの実験!(CF-IDE編)

ジャンクノートパソコンが 4?5台 あったのですが、整理することにしました。

使えそうな NEC VersaPro VA70H/WX は、以下のように整備して、ゆうのお兄ちゃん(小6)にあげました。

・CPU Celeron 700MHz (変更なし)
・メモリ PC100 128MB X 2 (最大)
・キーボードをヤフオクで落札したパーツに交換
・HDD IDE 80GB 5200rpm キャッシュ 8MB
・OS Windows XP Home Edition (バンドル正規版)

HDDを最近のものに交換したら、思いの外スムーズに動くようになりました。

あと、ジャンクを組み合わせて動作するようにした FMV-650NU7C/L が余りました。
一時期は Vine Linux をインストールして、検証用サーバーとしていましたが、お客様で検証用サーバーを用意されたので余っていました。

残っているパーツを使うと、以下のような構成になります。

・CPU Celeron 500MHz
・メモリ PC100 128MB + 64MB
・HDD IDE 12GB 4800rpm キャッシュ 2MB
・OS Windows 2000 Professional / xbuntu / その他

CPU が低性能なので、他で補うしかありません。VersaPro での経験から、HDDを最近のものに変えるのが効果的と思われます。

ここであきらの実験魂に火がつきました。
「どうせHDを買うんだったら、シリコンメモリにしてみたい!」
しかし、SSDは高価です。IDEタイプは需要が少ないせいか、さらに高価です。
「この前、SDHC+USBカードリーダーで結構速かったし、SDHCをIDEに変換するアダプタがあるんじゃないか?」
と考え、ネットを検索する事数時間。

無性に試してみたくなり、託児所に嫁さんとゆうを迎えに行ったその足で、松江のパソコン工房へ。

目的の SDHC to IDE 変換アダプタは見当たりません。
しかし、CF to IDE 変換アダプタがあったので、試しに購入してみました。2,500円くらいだったと思う。

CFは結構高価なため、購入は検討後にしました。

数日後、実家にゆうを連れていったついでに、鳥取のパソコン工房で16GのCFを購入しました。5,000円くらいだったと思います。

帰宅後、さっそく Windows 2000 をインストールしてみましたが、がっくりしました。
インストールに4時間かかり、Windows Update の途中でしびれを切らして強制終了してしまいました。

まあ、起動はけっこう速かったんですが。

CF to IDE 変換アダプタは UltraDMA に対応していたのですが、肝心の CF が対応していなかったことが、極端に遅い原因のようです。

しかし、本当に静かなのです。あまり熱が発生しないため、冷却ファンもほとんど動きません。
また、読み込みは HDD より速いぐらいです。

あと書き込み速度が実用範囲なら…

「よし、こんどは SDHC to IDE 変換アダプタを通販で購入して…」
と、たくらむあきらだったのでした。

(SDHC-IDE編へ続く)

4Desk でデスクトップアイコンがきちんと並ばない事の対策

なんだかんだ言っても Vista では Aero を有効にした方が軽いらしい。
しかし、仮想デスクトップの Dexpot では、Aero を有効にすると不具合が発生する。
仮想デスクトップを切り替えると、重なって下になっているウィンドウの重なっている部分が真っ白になってしまう。

なので、最近は 4Desk を使っている。

画像(177x180)

設定の Tray Icon Option を Show all に設定して、通知領域に各デスクトップのアイコンを表示させている。
各デスクトップのアイコンをクリックすると、すぐさまそのデスクトップに切り替えてくれる。
現在のデスクトップのアイコンは色を変えて表示してくれるので、とてもわかりやすい。

しかし、ちょっとした問題が。

Windowsの通知領域への登録は、各アプリケーションが好きなタイミングで登録する。
このため、各デスクトップのアイコンの間に他のアプリケーションのアイコンが挟まってしまうことがたまに発生する。
Dexpotの場合は、ご丁寧にデスクトップアイコンを並べ直してくれている。

結局、タスクのスケジュールで対応した。

タスクのスケジュールでは、ログイン時に実行するプログラムを登録でき、遅延時間を設定できる。
遅延時間に20秒を設定すると、スタートアップに登録しているFirefox が立ち上がった後に 4Desk のアイコンが表示され、いい感じになった。

遅延時間はご自分の環境に合わせて調整していただきたい。

ひさびさ IE6 でハマりました

ほぼ開発が完了しているシステムですが、アンケート登録機能があります。
各質問で、回答のタイプ・選択値(選択する回答のタイプの場合)・必須かどうかを登録できます。

開発完了と思っていたのですが、担当者の方からバグ報告がありました。
回答のタイプで「チェック」を選択すると、変な所にプルダウンメニューが表示されるとの事。

画像(180x165)

バグ

さっそく再現しようとしましたが、IE7・Firefox 共に何どやっても再現しません。
どんなバグかも確認しようがないので、スクリーンショットを取ってメールしてもらいました。
スクリーンショットを確認すると、たしかにテキストボックスの上に、プルダウンメニューが重なって表示されています。

スクリーンショットを見てもしやと思い、Windows 2000 + IE6 でテストしてみると、やっと再現する事が出来ました。
担当者の環境を確認すると、 Windows XP + IE6 との事でしたので、IE6 固有の問題と特定する事が出来ました。

まだ IE6 での検証が必要なんですね…
とにかく、プロとしては対応しなければなりません。

まず、この問題以外の動作自体は大丈夫か確認しました。
JavaScript 自体は IE6 でも正常に動いているようです。

つぎは回避方法を模索しました。めずらしい現象なので、ネットを検索しても情報は見当たりません。
何度も試行錯誤して対応しました。

さらに IE6 で動作検証を行った所、ラジオボタンなどで使用しているlabelタグが機能していないことが判明しました。
この対応もかなりの時間がかかりましたが、なんとか対応しました。

基本的には自分のメモですが、誰かの役に立つかも知れませんので公開します。

selectタグに optionタグを追加すると、親要素(tr)に style=”display: none;” と指定されているにも関わらず select要素が表示されてしまう

今回のシステムでは、回答のタイプ別に初期値を登録する行を準備しており、回答のタイプにより表示・非表示を行うようにしています。
回答タイプがプルダウンリストまたはラジオボタンの場合は初期値をプルダウンリストで選択可能にしています。
回答タイプがプルダウンリストの時に選択値を追加した場合、初期値選択用のプルダウンリストに optionタグを追加して作業を継続できるようにしています。
このとき、回答タイプがラジオボタンの場合の初期値選択用のプルダウンリストにも optionタグを追加する必要があります。
この動作を行った時にこの不具合が発生します。

以下の方法回避できました。

(1) 親要素(tr).style.display を保存
(2) 親要素(tr).style.display に ” を設定(表示させる)
(3) optionを追加
(4) 親要素(tr).style.display に(1)で保存した値を設定

(1),(2),(4) の処理を追加する必要がありました。

IE6 では labelタグは <input id=”id” … /><label for=”id”>テキスト</label> の形式にする

IE6 では以下の形式のみサポートしています。

<input id="id" ... /><label for="id">テキスト</label>

IE7, Firefox では上記形式に加え、以下の形式もサポートしています。

<label><input ... />テキスト</label>

じつはPHPでの表示部分の修正は大したことではないのですが、JavaScriptの修正が大変でした。
今回のアンケート登録機能には回答タイプに「チェック」があり、複数回答可能とする仕様です。
当然初期値の設定も複数可能とする必要があります。
フォームが送信された時に、どの選択値が初期値としてチェックされているかわかるようにするには、チェックボックス別に初期値の順番を含んだ名前を付ける必要があります。
前述したように初期値の設定部分は選択値の追加・移動・削除に連動しています。
このため、選択値が変更された場合には、チェックボックスの name属性と id属性、labelタグの for属性を変更する必要がありました。

JavaScript で labelタグの for属性にアクセスするには htmlFor とする

labelタグ.for としてアクセスしようとしても、for は JScript のキーワードなので構文エラーとなります。
Firefox では labelタグ.getAttribute( ‘for’ ) や labelタグ.setAttribute( ‘for’, 値 ) で対処できるのですが、IE6・IE7 では対処できません。
ネットを調べても labelタグの for属性の情報なんて、なかなか引っ掛かりません。

なので、奥の手をつかいました。labelタグのキーを全て表示させます。
JavaScript の該当部分に以下の行を追加しました。

for ( var key in labaelタグ ) alert( key ) ;

ひたすらエンターを押しながら確認しました。
どうやら htmlFor という見慣れない属性がある様です。

さっきの行を修正して再度確認します。

alert( labelタグ.htmlFor ) ;

やっと labelタグの for属性にアクセスできました。

IE6対応は、本当に無駄な時間がかかってしょうがないのです。