search phpbb-phpbb-FC2BLOG-Info-Edit Template-Post-Edit-Upload-LogOut
通常配置要素の絶対座標上の位置を取得するJavascriptコードは、ウエブ上や書籍でかなり流布されている。しかし、それらは正しく絶対座標を提供しないものが多い。
だから仕方なく、コードの進行過程をチェックし、ブラウザ毎に必要となる補正を行うコードを追加し、確実に正しい座標値を得る方法を確立した。そのコードはこのエントリイの末尾に掲載し、検討経過を克明に下記にまとめた。
なお、改訂したコードが対応するブラウザはIE7、FF2及びOpera9であり、safariは検証する術がなかった。
それは位置と大きさを与えてくれる。それはマイクロソフトが定義し、Mozzillla系も随随した便利この上ない属性だ。
さて、これらの4つのプロパティは片や位置を、片や大きさを取得する。異なる属性取得を同じoffsetで行うのだ。しかも嫌がらせとしか言いようがないが、<例によって>IEとMozilla系においては、位置属性に係るoffsetLeftとoffsetTopが異なる定義値となっている。
更に、位置とサイズという異なる性格の属性を同一のoffsetなる言葉で包含し、定義してしまったことから、それらは大変混乱しやすい属性となっている。
よく知られているような定義は次のようになっている。(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においてさえ間違いであることが後に分かるだろう。

よく知られているように、位置を設定する場合、相対配置要素か絶対配置要素かにより起点が変わってくる。CSS上でそれを確認しておく。
前者の場合にはそれが通常配置上あるべき位置からの相対的な移動距離として、、絶対配置の場合には包含する絶対配置ブロックのpadding辺(borderの内側)からの距離としてカウントする。更に、そもそも静的要素の場合にはLeftやTopは定義出来ない。
| 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つの位置属性の仕様が、少なくとも静的要素に関して明らかに異なっているのだ。そこでテストを行って正確な位置取得を行う道を探ることとした。
以下のテストは位置指定されていない通常配置要素について、そのoffset値がブラウザによってどう算出されるのか、試したものである。これらの実験を通じて大変興味深いことが判明した。
結論から言えば、IEとFFにおいて通常配置の位置に関するoffset値は異なる計算をしているということであり、ここでも「ブラウザ別にスクリプトを書かざるを得ない」ことを思い知らされたのである。

但し一部日本語化して、margin辺、border辺、padding辺、内容辺と呼ぶこととした。
上の例1はbody部のmargin、border及びpaddingを全てゼロとした場合の計測値だ。この結果はIEでもFFでも一点を除いて同一であった。異なったのはHeightである。FFの方がIEよりも1pxだけ小さかった。
ブラウザの個性と言って良い、さしたる問題ではないこの相違点はさておき、ここで言えることは位置のoffset値として、対象要素(id:div1)のmargin値が出力されたことである。言い換えればこの場合、bodyから対象要素のborder辺までがオフセット位置ということになる。但し、margin=border=padding=0としたので、body部のどの部分から計測されているのかは、この例では皆目分からない。
次の例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部の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は、以上のことを確認するためにmargin値とborder値を変えてみたものだ。上記の通り、IEはbody部のborderを無視して、2つのmargin値を加算(10+44)してoffset値=54とし、FFはmargin値を加算(54)した上でbody部のborder値をマイナス(-38)して、offset16pxとしている。
以上から通常配置要素のoffset位置の算出方法を、さしあたり次のようにまとめることが出来る。
更に確認するために、今度は測定対象を深い階層の孫要素としてみる。推測できることはIEはbodyと途中の各親要素のborder幅を無視するであろうこと、FFはbody部のborderをマイナスするが、途中の各親要素のそれはマイナスしないかもしれない、ということだ。この推測が当たるかどうかお楽しみ!
margin:8px; border:10px 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だけはマイナスした。
上記の深い階層にある位置測定要素の計算過程とそれを後述するコードによって補正した値は以下の通りである。これらは皆、ブラウザが表示する過程において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値=補正後の正しい位置となる。
以下は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にも適用できる。これで最終的な目的を達したものと確信している。
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で簡単に取得できるだろう。
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が開きます。