05 | 2007/06 |  07

  1. 無料サーバー

User forum-FC2BLOG-Info-Edit Template-Post-Edit-Upload-LogOut

CSSやJavascript自習の苦闘史を綴っていきたい。恐縮ですがJavascriptを有効にしてご覧ください。
2005年12月から社会問題も掲載!


画像の立体化:aqua化粧をJavascriptで!

それはJavascriptなどに関する海外サイトを紹介するWebsite:youmosで知った。

画像のaqua化粧を画像処理ソフトを使って作成するのは結構大変な手間だ。

それをJavascriptで簡単に実現するJavascript Toolsが<youmos - 新しいWebビジネスや技術アイデアを活性化するWebマガジンに紹介されている。

その簡単ツールを提供しているサイトは、Glossy.js (now with IE 6/7 support)だ。

早速Glossy.jsをダウンロードし使ってみたが、なるほど簡単に画像の立体化が可能となる。それは大いに利用価値があると思われた。

サンプル画像
aqua加工例(本家サイトから複写)

但し、作成される画像は元画像をscriptで加工しブラウザ上で表示しているだけなので、ブラウザ上で簡単に画像ファイル化出来ないのが難点だ。

つまり、画像キャプチャソフトなどを活用してファイル化する手間が生じる。

それでも、このscriptは簡単に綺麗なaqua画像が作成できる点で秀逸であり、手持ち画像をaqua加工する楽しみを容易に提供してくれる点で素晴らしい。

offsetLeft,offsetTop,offsetWidthそしてoffsetHeight──静的配置要素の絶対位置を確実に取得する方法について

結論概要

通常配置要素の絶対座標上の位置を取得するJavascriptコードは、ウエブ上や書籍でかなり流布されている。しかし、それらは正しく絶対座標を提供しないものが多い。

だから仕方なく、コードの進行過程をチェックし、ブラウザ毎に必要となる補正を行うコードを追加し、確実に正しい座標値を得る方法を確立した。そのコードはこのエントリイの末尾に掲載し、検討経過を克明に下記にまとめた。

なお、改訂したコードが対応するブラウザはIE7、FF2及びOpera9であり、safariは検証する術がなかった。

object.offset○○は大変便利なプロパティ

それは位置と大きさを与えてくれる。それはマイクロソフトが定義し、Mozzillla系も随随した便利この上ない属性だ。

さて、これらの4つのプロパティは片や位置を、片や大きさを取得する。異なる属性取得を同じoffsetで行うのだ。しかも嫌がらせとしか言いようがないが、<例によって>IEとMozilla系においては、位置属性に係るoffsetLeftとoffsetTopが異なる定義値となっている。

更に、位置とサイズという異なる性格の属性を同一のoffsetなる言葉で包含し、定義してしまったことから、それらは大変混乱しやすい属性となっている。

offsetLeft と offsetTop の定義は?

よく知られているような定義は次のようになっている。(DOM Element リファレンス

offsetHeight
offsetHeightは親要素内で占めている(訳注追加:高さの)ピクセル数を収得します。
offsetLeft
offsetLeftは親要素内での(訳注:オフセット対象要素内での)左からのオフセットのピクセル数を収得・設定します。
offsetParent
offsetParentは当要素がオフセット対象としているオブジェクトの参照を返します(例えば、親要素)。
offsetTop
offsetTopは当要素の親要素からの(訳注:オフセット対象要素からの)上からの相対位置を返します。
offsetWidth
offsetWidthは当要素の親要素での(訳注:オフセット対象要素での)占めている(訳注追加:幅の)ピクセル数を収得します。

しかし、これらの直訳的文章には、margin、border、padding、内容本体のどこまでの位置や幅を指しているのか、全く書かれてない。位置や幅と言えばどこからどこまでを指すのかが重要な要素だが、そのことは当たり前の前提として省略されているか、あるいは余りに複雑なために省略したとしか考えられない訳文である。(原典を調べたら位置の起点と終点については明示されてた。例えばoffsetLeftについては「The distance from this element's left border to its offsetParent's left border.」──つまりborder間の距離である。しかし、border間の距離と言ってもborder自身に幅があるのだから、外辺か内辺かこの文章では分からない。更に幅と高さについては「要素の」としかなく、要素の内側なのか、外側なのかは明示されていない。)

一方、msdnに次のような位置と幅を示す分かりやすい図があり、これを見て初めて上記の文章の具体的な意味が判然とする。(出典はこちら:Welcome to MSDN Library

しかし致命的なことに、これらの説明の一部は間違っている。例えばoffsetLeftが親要素のborder内辺(=padding辺)から当該要素のborder内辺(padding辺)迄となっているが、これは静的要素でも位置指定要素でも共に、IEにおいてさえ間違いであることが後に分かるだろう。

エレメントの位置と大きさ説明図 by Micorosoft

サイズは横方向又は縦方向のborder辺間距離で統一されているが、位置に関しては・・・

よく知られているように、位置を設定する場合、相対配置要素か絶対配置要素かにより起点が変わってくる。CSS上でそれを確認しておく。

前者の場合にはそれが通常配置上あるべき位置からの相対的な移動距離として、、絶対配置の場合には包含する絶対配置ブロックのpadding辺(borderの内側)からの距離としてカウントする。更に、そもそも静的要素の場合にはLeftやTopは定義出来ない。

CSS2.1(仮)- ポジショニングと重ね合わせ http://www.kanzaki.com/book/css/3-3.html から引用
position: static relative absolute fixed
配置別名 (通常配置) 相対配置 絶対配置 固定配置
本章のボックスタイプ名 - 布置ボックス
位置決めスキーム 通常フロー 絶対位置決め
包含ブロック 直近ブロックボックスの内辺 直近布置ボックスのパディング辺 表示域
top、leftなど 適用しない 通常配置からのオフセット 包含ブロックからのオフセット
ブロック整形コンテクスト 形成しない 新たに形成
浮動化 可能 不可

CSS上は上のように静的要素に対するLeftもTopも存在しない。しかし、多くの書籍やサイトに要素の位置を取得するJavascriptが例示されていて、それによればparent要素のoffset値の累積値によって、当該要素のx,y位置を算出している。つまり、CSS上は静的要素のオフセット値は未定義かも知れないが、DOMにおいて、offsetLeftとoffsetHeightが定義されているようだ。しかし、DOMの仕様書をあれこれと検索してみたが、適切な説明は見いだせなかった。例えばDOM Element リファレンスの説明は既に見たとおり、同語反復的説明に過ぎない。

さて、或るエレメントの上下左右に別のエレメントを配置したい場合、以上のようにoffsetLeftやoffsetHeightの定義がはっきり分からないので、ピッタリ配置することは大変難しい。

以下に見るように、IEとFFではこれらの2つの位置属性の仕様が、少なくとも静的要素に関して明らかに異なっているのだ。そこでテストを行って正確な位置取得を行う道を探ることとした。

offsetLeft等に関するテスティング

以下のテストは位置指定されていない通常配置要素について、そのoffset値がブラウザによってどう算出されるのか、試したものである。これらの実験を通じて大変興味深いことが判明した。

結論から言えば、IEとFFにおいて通常配置の位置に関するoffset値は異なる計算をしているということであり、ここでも「ブラウザ別にスクリプトを書かざるを得ない」ことを思い知らされたのである。

テストの方法
  • ブログとは異なるHTML、CSSを適用した殆ど粉飾のないWebページ上において、通常配置のdiv要素を複数配置し、それらを計測対象とした。
  • それらのdiv要素は兄弟関係または子孫関係に配置した。
  • テストに使用したブラウザはsleipnir2.5.13(on IE7)、FF2.0.0.4及びOpera9.21である。
  • 計測に使ったJavascript文は以下のものである。
  • 例5における計測時のsleipnir2のwindowの内幅は983pxであり、この条件下でoffsetLeft値の測定を行った。なおFFとOperaについてもそれぞれ確認したが、このエントリイ内にその結果確認情報は挿入していない。
  • ボックスに関する名称は下図に従った。

    ボックスモデルの寸法説明図

    但し一部日本語化して、margin辺、border辺、padding辺、内容辺と呼ぶこととした。

例1 ───body部のmargin、border、paddingは全てゼロに
offset値測定結果1

上の例1はbody部のmargin、border及びpaddingを全てゼロとした場合の計測値だ。この結果はIEでもFFでも一点を除いて同一であった。異なったのはHeightである。FFの方がIEよりも1pxだけ小さかった。

ブラウザの個性と言って良い、さしたる問題ではないこの相違点はさておき、ここで言えることは位置のoffset値として、対象要素(id:div1)のmargin値が出力されたことである。言い換えればこの場合、bodyから対象要素のborder辺までがオフセット位置ということになる。但し、margin=border=padding=0としたので、body部のどの部分から計測されているのかは、この例では皆目分からない。

例2 ───body部のborderを整数値に(上がIE、下がFireFox)
offset値測定結果2

次の例2は、測定対象(div1)の属性は何も変えず、body部のborderを15pxと変更し、marginとpaddingをゼロとした場合の計測値だ。この結果は早くもIEとFFで異なる様相を呈した。IEはborder幅を加算せず恰もoffset値の起点としてborder内辺=padding辺を採用しているかのように振る舞い、一方のFFは何とbody部のborder幅をマイナスした。この結果FFにおいてはoffset値はLeftもTopもマイナス値となった。

かくして早くもFFのoffsetはそのままでは使いようがないことが暴露された、と言える。

例3 ───body部のmargin及びborderを整数値に(上がIE、下がFireFox)
offset値測定結果3

例3は、測定対象の属性は何も変えずに、body部のborderを15px、marginを13pxとし、paddingをゼロとした場合の計測値だ。この結果混乱はますます加速し、IEとFFで更に異なる様相を呈した。

IEは相変わらずborder幅を加算せず、しかしbodyのmargin値をoffset値に加算して、何とdiv1のmargin+bodyのmarginの値をoffset値とした。borderを飛び越してmargin値を足しているのだ。ここではまた早くも起点としてborder内辺=padding辺を採用している訳ではないことが明かとなった。

一方FFはといえば、今度もまたbody部のborder幅をマイナスしただけではなく、IE同様に、測定対象のbodyに対するoffset値として、測定対象要素のmarginとbodyのmarginを加算している。この結果FFにおいてはoffset値はmargin合計値マイナスbodyのborder値という、何とも理解しがたい幅となった。

上の例3にbody部padding値を適当に与えて計測してみると、位置のoffset値として、IEでは対象要素(id:div1)のmargin値+bodyのmargin値+bodyのpadding値が出力され、FFではこのIEの取得値から何と、body部のborder幅を減じた。こうしてbodyのborder部の扱いが焦点であることが分かる。それにしても加算してないborder値を引いてしまうFFの計測方法は合点がいかない。bodyのborder値を2回引いているとも言えるのであって、これでは何のための計測か分からなくなる。

例4 ───例3の整数値をもっと大きくしてみた(上がIE、下がFireFox)
offset値測定結果4

例4は、以上のことを確認するためにmargin値とborder値を変えてみたものだ。上記の通り、IEはbody部のborderを無視して、2つのmargin値を加算(10+44)してoffset値=54とし、FFはmargin値を加算(54)した上でbody部のborder値をマイナス(-38)して、offset16pxとしている。

以上から通常配置要素のoffset位置の算出方法を、さしあたり次のようにまとめることが出来る。

  • IEもFFも、offset値として、対象要素のmargin値と親要素のmargin値を加算する。
  • IEにおいては親要素のborder値をoffset値の対象としない(無視する)。
  • FFにおいては親要素のborder値をoffset値から除外する(マイナスする)。

孫要素においても上記の結論は適用できるか?

更に確認するために、今度は測定対象を深い階層の孫要素としてみる。推測できることはIEはbodyと途中の各親要素のborder幅を無視するであろうこと、FFはbody部のborderをマイナスするが、途中の各親要素のそれはマイナスしないかもしれない、ということだ。この推測が当たるかどうかお楽しみ!

例5 ───深い階層内にある計測対象で検証
<div id="div5">

margin:8px; border:10px forestgreen solid; padding:6px;background:plum;color:black;line-height:1.1em;

margin:9px; border:11px forestgreen solid; padding:6px;background:plum;color:black;line-height:1.1em;

margin:14px; border:17px springgreen solid; padding:21px;background:powderblue;

margin:6px; border:8px darkgreen solid; padding:6px;background:#dfdfdf;>例7 測定対象要素はこの <div id="div7">この要素は、このエントリイ内におけるdiv要素の四層目に該当する。

さて予測は見事に裏切られた。IEはいくつかのborderを無視し、FFは連なる親要素のmarginもborderもpaddingも全てoffset値にカウントするものの、body部のborderだけはマイナスした。

  • IEでは予想通りbody部のMをカウントし、そのBを無視した。但し途中の親要素のborderは、DOMが親要素としてカウントしたものについてのみ無視している。つまり一部の親要素borderはoffset値にカウントされ、一部のそれは無視された。
  • FFではoffset値をカウントする場合の親要素は仕様上常にbody部しかない。このため結果として途中の親要素のM、B、Pは全てカウントされ、body部のMを加算した上で、body部のBを減算している。
  • 他方、Operaのみが正しく計測した。

結果や如何に?

上記の深い階層にある位置測定要素の計算過程とそれを後述するコードによって補正した値は以下の通りである。これらは皆、ブラウザが表示する過程においてJavascript、関数内で取得した値をdocument.write()で出力した。なおここに過程を説明したブラウザはsleipnir2 onIE7である。

<上記の計算過程出力内容の説明>

「parent-chain」とはこの場での説明上の造語で、offset値算出コードにおいて親要素として把握された要素のリストである。左端は計測対象要素であり、右に順にparentNodeを辿っている。FFとOperaにおいては任意のあらゆる通常要素の親要素は常にBODYであるが、IEの場合には複雑に途中要素のいくつかを親要素とする。

「各offset値」とは、offset値算出コードにおいて、offset値を加算する過程を取りだしたもの。上の数字の意味は下で述べる。IE以外は常に1つの値しかないが、IEは複数の場合がある。

「補正後の正しい位置」とは、無視されたりマイナスされてしまったborder幅をブラウザ毎に適切に加算して得られた、window左辺またはwindow上辺から、対象とする要素のborder辺までの正しいピクセル値である。IEの場合、上の計算においてはoffset値が共に1pxだけ加算されているが、これはコンテナとなっているエントリイ部のborder幅である。他方、FFの場合、BODY部にborder幅を設定してないため、不当に減算されることなく(苦笑)、ここでは、「offsetLeft値=補正後の正しい位置」となり、最後にOperaにおいては、どの様な条件下であっても常にoffsetLeft値=補正後の正しい位置となる。

offset値計算過程を辿って計算内容を解明する(IE限定の記述)

以下はIEの場合に限った内容である。FFやOperaではこのような複雑なことにはならない。

やはりIEでは「こと」は単純ではない。1.body - 2.contaner - 3.column1_block - 4.div - 5.div - 6.div - 7.div(target)という深い階層のターゲットを計測対象にしたのだが、offsetLeft の算出過程を振り返ると、次のようになっている。

まず計測対象とした親要素は、6.5.4.と順番に包含要素を辿るのではなく、いきなり「3.column1_block」を「7.div」のparentNodeとして選択し、これとの距離【Left値:135px】を測っている。

次に3.と2.の距離を測定し【Left値:0px】、最後に2.と1.の距離を測定している【Left値:】。

ここで問題となるのは 3.column1_block に設定されているborderが無視されていることである。勿論body部のBorderも無視されているのだが、このブログのbody部にはmargin:0;border:0;と設定されているので、ここでは問題とならない。

こうしてIEについて言えることは、途中のborderは、計測対象となるものもあれば、そうでないものもある、ということだ。このブログでは時計やカレンダー等の特別なもの以外は配置に当たって「位置指定」を使っていない。特にエントリイ部分は通常配置だけで通している。それでもDOMが親要素として把握するものとそうでない親要素があるわけだ。

そこで、IEの場合にはoffset値計算上の親要素に限って、そのborder幅を無視しないようにコードを修正すれば良いことになる。しかし、ややこしいのは、FFの場合にはIEのような途中の要素のborderを無視するようなことはなく、あくまでも最終の親要素=body要素をoffset値算出対象とする時だけ、そのborderを計算もしてないのに減算するということだ。そして、Operaだけは単純なoffset値の加算だけで正確な絶対位置を知ることが出来る。かくしてブラウザ毎にoffset値を算出(IEとFFは固有の補正が必要)しなければならなくなる。

この時の各ブラウザの計算内容を説明すると下図のようになる。

測定内容説明図

かくして、offset値から正しい絶対位置を知ろうとすれば、IEとFFのそれぞれに対応して適切にborder値を加算する必要がある。それを考慮したJavascriptは以下の通りであり、これはそのままOperaにも適用できる。これで最終的な目的を達したものと確信している。

通常配置要素のoffsetLeftとoffsetHeight値から、window内における当該要素の絶対位置を正確にゲットする方法(IE、FF及びOpera対応。MacPCはないのでsafariは調査できない。)

IE、FF及びOperaにおいて、次のコードによって、対象要素の位置(bodyのmargin辺から対象要素のborder辺までの距離)を算出することが出来る。なお、ここで得られる値は、決してmargin辺やpadding辺までの距離ではないことに留意する必要がある。勿論、もしmargin辺やpadding辺までの距離を知りたければ、得られた値にそれらを減算・加算すれば良いだけだ。一般に絶対配置要素を配置する際にイメージするのはmargin辺やpadding辺の位置ではなくborder辺だと思うので、まずborder辺までの距離を算出することが意味があると思う。

一般に流布しているJavascriptによるoffset値算出方法に変えて、以下のコードを利用すれば、初めて通常配置要素の正確な絶対座標を取得することが出来るだろう。

蛇足

当然のことながら、位置指定された要素(absolute、relative 及び fixed)の位置を、上記の方法で取得してはならないし、する必要もない。元々位置をしているのだから配置する前に作者は位置を知っているのであって、それをscriptで取得するのは余りに馬鹿げている(苦笑)。しかし強いて行うならばobject.style.leftやobject.style.topで簡単に取得できるだろう。

Javascript Tips・・・サイト:youmosについて

要素透明化について検索していてyoumosに遭遇した

偶々その存在を知ったが、そのコンテンツは主に海外サイトのスクリプト Tips 紹介で、中でもJavascriptやAjax関連の紹介情報が満載されている大変有り難いサイトだ。

それは2006年11月にオープンし、当初は情報ブログとして出発らしいが、その後掲載情報を技術関連にシフトしたとのこと。(サイト説明から引用)実はまだ出来たてほやほやのサイトだったのだ。

サイト内検索フォームが設置されていない、サイト全体の構成を一覧できない、等のブラウジング上の欠点はあるが、情報量の豊富さと紹介されているサイトの質は、絶賛に値すると思う。

紹介されているのは、flash、Javascript、Ajax、php等々の各種言語とツールを活用するサイトの特徴とサイト画像で、私の場合、スクリプトを自作していて不明な点が生じた場合に、参考にすることが出来るサイトが複数存在していたことが嬉しい。

紹介されているJavascript関連サイトは、かなり高度なものもあり難儀すると思うが、それを理解する喜びもまた一入である。

要素高さの取得について(2)

高さが意識的に設定されていない要素の高さを取得する。

それは一般にobject.offsetHeightで取得するようだ。しかし、ブラウザで当該要素を描画しない限りoffsetHeightは機能しない。例えば mouseover で起動するポップアップ説明を設置する場合、それは絶対配置要素として設計する。ここに、当該ポップアップの高さはそれを表示する前に取得する必要がある場合が多いが、その中の文字列は表示するポップアップ毎に異なるし、フォント種類、フォントサイズ、行高さなどによって変動するので、容易に取得することは出来ない。

つい一昨日までは、次のように、描画されているフォントサイズと行間を測定し、ポップアップする文字数から要素の内寸高さを計算して設定していた。

var blnHeight = Math.ceil(txt.length * 14 /blnWidth) * 18

しかしこの方法は、大きな欠点がある。それは文字には漢字、かなもあればアルファベットも混じるのが普通であり、それらは1文字当たりの横幅が異なるため、要素内寸高さは上の計算式では正しく計算されないことである。

これまではやむを得ず上の計算式を3年以上使い続けてきたが、どうしても思い通りに高さを設定できない場合が、多々発生していたため、3年の間ずっと適切な解決方法を思いつかず、人知れず悶々としてきたのだった(苦笑)。

しかし苦節三年! ついにそれが解決できたことを自画自賛したくて、ここに記録しておきたい。

その方法は?

まず考え方は次のとおりだ。

  1. まず、本来表示したい絶対配置を適当な位置に完全に透明化して表示する。(※ cloneNode のままではメモリ上にあるだけなので、高さなどの属性は設定しない限り取得できない。)
  2. 次に、これを表示してその高さを取得し、直後にそれを非表示にする。
  3. 最後に取得された高さを利用して、本来配置したい絶対配置要素を配置する。

スクリプトは以下の通りである。

上のスクリプトの適用事例

勿論、上記の「要素高取得スクリプト」はこのブログのテンプレートに全面採用しているが、こちらに要素高取得に関する独自フォーマットのページを作ったので、興味があればご覧いただきたい。

表示された要素コンテンツの透明化について

CSSでもJavascriptでも、それは簡単にできること

このブログではこれまでドラッグ可能コンテンツは全く作っていないし、画像の透明化、Cursorの動きに追随するマウスカーソル表示などなどのコンテンツの動的な表示もしてこなかった。そうしたことに殆ど関心がないからであるし、このブログが目指している内容から、これまではそうした要請は生じてこなかった。

しかし、そのコンテンツ高さが事前に設定されていない要素の外枠高さ(=ブロック内高さ+パディング幅+ボーダー幅)を取得することを検討している中で、要素の透明化にチャレンジしてみたくなった。

なお、「要素の透明化」は入門的な書籍に触れられることが多い一般的な手法だから、今更、こうして独立したエントリイを作成する程の価値があるとは思えないが、そこはブログならではの独り言として許されるだろう。

さて、まずはそれを実現するスクリプトを転載しておこう。
【出典:opacity - 半透明を操るJavaScript - youmos】(youmosはJavascriptの様々なツールを紹介してる大変有り難いwebsiteで、これまでその存在を知らなかった。)

なお、以下に掲載したスクリプトは使いやすいように一部を改ざんしている。

上記の透明化を実際に使ったページは次のとおり

HTML、CSS及びJavascriptのいずれによっても高さが指定されてない要素の、その高さをJavascriptで取得する演習を行ってみたが、透明化はその結果をまとめた独自スタイルのwebページに適用例がある。→ 透明化を使った例

初めて試みた透明化であったが、やってみるとそれなりに面白く、今後は画像表示に使ってみようか、等と色気を出し始めている(苦笑)。

なお、上記の独自スタイルページはブログエントリイとは別のHTML及びCSSを設定したオリジナルHTMLであり、HTML文書がアップロードできるFc2ブログならではの利便性に改めて感謝したい。

事前に高さが指定されていない要素の高さ取得方法について

要素の高さについて

CSSにおいて、あるいはHTML内のスタイル属性において position 属性に abusolute、relative あるいは fixed を指定していない通常の要素の場合、文字を書き込む要素には一般にその高さを指定しない。ブラウザがHTML描画時に自動的に高さを設定してくれるからである。

また、何らかのposition指定を行う場合であっても画像や動画ではなく、その要素内のコンテンツが文字列の場合には、一般に要素の高さは指定しない。ここでもブラウザが自動的に高さを設定してくれる。

しかし、絶対配置要素を自在に配置しようと思ったら、その高さ、特に外縁部における高さを配置する前に知っておきたい。

高さの取得

ということで、独自スタイルのテンプレート上において、Javascriptによってどのように要素の高さを取得するのか、その学習結果をまとめてみた。それは通常配置要素及び位置指定された要素のそれぞれについて、CSSやタグ属性において高さが指定されていない要素の高さを Javascript で取得する演習である。もっと具体的に言えば<要素外高>取得プロパティである offsetHeight をどう活用するか、を中心とした演習である。

更にそこではまた、副産物として絶対配置要素のフェイドアウトも初めて試みてみた。

ここをクリックすると別窓でそれを表示する。

ブラウジングメニューの改正作業について

わがブラウジングメニュー = 階層メニュー+パンくずリスト のこれまでの問題点

このブログにおいては、各エントリイ閲覧、月別表示、検索結果表示などの各モードの時、マイブログ・エントリイ表示部の最上部にブラウジングメニューを表示している。(下図参照)

ブラウジングメニュー縮小画像

このブラウジングメニューは複合的な機能を有しており。左端部は「階層メニュー」、|| の右側は「パン屑リスト」となっている。

さて、これまで階層メニューの表示/非表示において、2つの大きな問題があった。最初にその内容をまとめておきたい。

文字列「▼Browsing MENU」には、沢山のイベントハンドラーが設置されている。まず、mouseover 時には直下に階層メニューを表示するハンドラーがあり、同時に当該メニューの使い方を説明するpopupを直上に表示するハンドラーも起動する。1のイベントに2つのイベントハンドラーがあるのだ。また当該要素からの mouseout イベント発生時には、これらの2つの表示結果を非表示するイベントハンドラーが設置されている。

更に、文字列「▼Browsing MENU」に設置されたmouseoverイベントハンドラーにより階層メニュー表示されるが、この階層メニューブロックにも、mouseover 時と mouseout 時にそれぞれ機能する別の2つのイベントハンドラーが設置されている。

これらのmouseover、mouseout時に動作する各種のイベントハンドラー関数によって、階層メニューの表示と隠蔽をコントロールしている訳だが、これまでは次の2つの問題を抱えていた。第一に、文字列「▼Browsing MENU」から階層メニュー部分以外にmouseoutした時に、既に表示されている階層メニューを非表示にすることが出来なかった。第二に、階層メニュー部分から文字列「▼Browsing MENU」にマウスカーソルが戻った時には、階層メニュー表示が消えてしまっていた。

そしてここ数年───。これらの不具合をどの様にすれば解消出来るのか、その方法が分からず、ずっと心の片隅に引っ掛かっていた。

ブラウジングメニューの改正点

さてこの度、上記の問題点の解消に多大な時間を費やし、やっと成功したので、ここに記録をまとめておきたい。

ブラウジングメニューが上記のような問題を抱えたまま巧く作動しないのは、Javascriptイベントハンドラー関数に問題があることは確実だった。しかし、果たしてどの部分が災いしているのか、それを判別し改正するのに多くの時間を割かざるを得なかった。

色々試行錯誤を重ねた結果、複数の様々な問題点が明らかになったが、その要点はイベントハンドラー関数の設定内容にあった。

第一の問題は、文字列「▼Browsing MENU」へのmouseoverイベントにより起動するイベントハンドラー関数=階層メニュー表示関数(showCloneMenu())内に、これまでに設置してあった当該階層メニューからのmouseoutイベントハンドラーの他に、新たに文字列「▼Browsing MENU」からのmouseoutイベントハンドラーを追加設置することにより解決した。

第二の問題の要点は、マウスカーソルを階層メニュー部分から文字列「▼Browsing MENU」の上に移動する際、連続して発生する複数のイベントのコントロールがうまく出来ていないことにあった。

その時にはmouseoutとmouseoverがほぼ同時に発生する。階層メニューからのmouseoutイベントの直後には、文字列「▼Browsing MENU」へのmouseoverイベントが起こる。

mouseoutイベントにより階層メニューは消えようとするが、直後に発生する文字列「▼Browsing MENU」へのmouseoverイベントにより、階層メニューは表示されようとする。しかし、直前に発生したmouseoutイベントの直後のmouseoverイベントによるハンドラーが起動しないのだ。

この瞬時に連続するイベントハンドラー起動は、そもそも仕様として機能しないものなのか、その点は明確ではないが、次のような設定を行えばよいと思いついた。それは階層メニューからのmouseout時に、通常は階層メニューを非表示にするのだが、マウスカーソルの行き先が文字列「▼Browsing MENU」の場合に限り、階層メニューを非表示にする関数を起動しないようにすれば良い、ということだ。

こうしてイベント発生時におけるマウスカーソルの移動元と移動先をスクリプト内で補足する必要に迫られた。

イベントターゲット:移動元要素と移動先要素

これらのアイテムは存在は知っていたが、これまで全く使用してこなかった。しかし、今回の問題を解決するに当たりどうしても使用せざるを得なくなった訳だ。

そこでIEの場合とMozilla系の場合に限って対応を調べた。IEの場合にはsrcElementとtoElementに分れているが、Mozilla系の場合にはmouseoverとmouseoutのそれぞれに応じて、移動元要素と移動先要素は異なる指定で行うことを初めて知った。その使い分けは以下の表の通りだそうだ。

Event type DOM:event.target DOM:event.relatedTarget
mouseover the EventTarget which the pointing device entered the EventTarget which the pointing device exited
mouseout the EventTarget which the pointing device exited the EventTarget which the pointing device entered

(上表は、DOM:event:Comparison of Event Targets - MDCから取得した。)

これらの調査の後に、階層メニューブロックからの移動先が、文字列「▼Browsing MENU」の場合に限って階層メニュを隠蔽しないように、スクリプトを改訂したのである。

以上により、ずっと懸案となっていた、我がブログ内の「バグ」退治を完了したのである。

 90%近いシェアを握っているインターネットエクスプローラの描画エンジンを利用したタブbrowser。沢山のタブbrowserがあるが、多機能、カスタマイズフリー、スクリプト利用等で一日の長がある。Gekkoエンジンへの対応も行われ、IEからの自立独立の方向に向かっている。2005年7月にはIE7が登場する見通しの中で、今後の発展が望まれる。

 多様なCSS作成支援機能を備えた、タグ入力式 HTML&CSS作成支援エディタ。スキンデザインもすっきりしている。テキストエディター上で作成するよりも確実で安全にタグ打ちが出来る。
文字コードを選べないのが欠点。

 StyleNote同様のタグ入力式 HTML&CSS 作成支援エディタ。長年使用してきたが現在StyleNoteに乗り換えつつある。

 クリップボード履歴情報を活用する為のソフト。画像まで履歴を取ってくれるのが嬉しい。このソフトを使わない日は絶対ない程に重宝し、愛用している。

 起動中のウィンドウの「コピーできない」説明文などの文字列を取得し、コピー可能な文字データにするツール。何かと便利。

 ストリーミングデータを保存することが出来るソフト。動画利用には不可欠なソフトだ。

 無料ながらレイヤー機能を有し、スクリプトによる拡張も可能な、sleipnir作者が提供している優れもの画像編集ソフト。

 画面キャプチャソフトと言えばこれに勝るものなし、ではないだろうか? 様々な取得方法を有しており、ブログ作成にもHomepage作成に不可欠だ。Jtrimと並んでWoodyBellsの作品。

 複数ファイルの同時編集は出来ないが、透過pngも作れる画像編集ソフト。
(以下当該サイトから抜粋)初心者にも簡単に操作が出来るフォトレタッチソフトです。多くの加工機能で画像に様々な効果を与えることができます。非常に軽快に動作するため、ストレスなく操作できます。

 Animation Gifファイルを作れる無料ソフト。

 キャプチャソフト。画面内にサイト全体が表示しきれない場合でも、これを使えば全体をキャプチャすることが出来る。

 画像処理。画像のフォーマット変換のみならず、色数やサイズ、圧縮率の変更まで一括処理できてしまう『BatchGOO!』は、大量の画像をまとめて処理したいときに大変便利なソフト。BMP, TIFF, JPEG, PCX, PNG の相互変換をはじめ、色数・サイズ・解像度の統一、JPEG圧縮率の調節など、ホームページ用の画像や携帯電話用の壁紙を揃えるのに抜群の相性を見せる。(Vectorの当該ソフト紹介頁より抜粋引用)

 名前から直ぐに想像が付くように画像のサイズを測るためのソフトだ。Homepage作成には欠かせない。2カラム、3カラムのレイアウトを行う場合に大変重宝する。

 ランチャーソフトは沢山あるが、中でもこれが一押しだ。2年以上使ってきたがその操作性には毎日満足している。これを使い始めてからデスクトップには一切のアイコンを表示することをやめてしまった。

 AdobeReader7によって、起動時間が長すぎるという長年のユーザーの不満はある程度解消した。そのためこの高速化ソフトは存在価値が低下してしまったかもしれない。AdobeReader6迄はこのソフトによる起動高速化で恩恵を受けてきた。

 IE専用が難点だが、様々なサイト内でIDやパスワードを入力するのに重宝するソフト。コンテキストメニューから簡単に起動できるのがGood! sleipnir等のIEの描画エンジンを利用しているブラウザでも使える。

 利用しているパソコンの諸元値を取得するには、このソフトがベストだ。インストール済みソフトの一覧が取得できるのも嬉しい。

 WMPは機能が豊富なだけ重い。RealPlayerも同様だ。そこでMedia Player Classicを使いたい。動作が軽快なだけではなく、対応しているファイル形式もすこぶる多く、これひとつで、wmvもrmも表示できてしまうのだから凄い! 数多あるMedia Playerの王様と言えるだろう。

 自宅でPCを起動しているときには必ず起動しているメディアプレーヤー。何かと過剰なWinampよりも、起動も速くスキンはシンプルだ。

 DivX, Xvid, Mov, Vob, Mpeg, Mpeg4, avi, wmv, dv, などの動画をDVD-Video形式に変換できるフリーソフト。クリックするとDVD関連ソフト紹介サイト=「DVDなToolたち」なるHomepageが開きます。