Javascript演習用頁【1】通常配置要素の高さ取得

通常配置要素の属性情報を取得する

絶対配置要素の属性情報を取得する

絶対配置要素を表示する前に、その要素高さを取得する

このテストに使用したブラウザは、Sleipnir2.5.13(buildNo.2513400:IE7インストール済み)とFF2.0.0.4である。

通常配置要素の属性情報を取得する

ここで言う要素の属性情報とは?

それは、HTML内の各種要素の諸情報───色、文字サイズ、位置、幅、高さ等々であり、今特に関心がある要素の情報とは、その高さである。

画像の高さは簡単に取得できる。それがブラウザで描画される前にも画像のプロパティ情報から取得できるし、描画後に高さをスクリプトによって取得することも出来るだろう。しかし、文字ノードを内包するブロック要素の高さを描画前に取得することは容易ではない。

offsetHeightによる、位置指定されていない通常要素の高さ取得

位置指定されていない通常のHTML文内のテキストノードを含む要素の2つの高さ(パディング内の内寸高さとマージン内縁までの外枠高さ)は、それがブラウザによって描画されている限り、スクリプトで容易に取得できる。それはスタイルオブジェクトのheightプロパティと、マイクロソフト社が最初に使い始め、Mozilla系もそれに追随した DOM のプロパティ:offsetHeight を使えばよい。

例えば次の文章要素の2つの高さ(内寸と外寸)を取得してみる。

div(margin:10px;)

p(margin:0 auto 0 auto; padding:5px; border:10px solid blue;width:450px;text-align:left)
【テスト1】これは、この文章部分の要素の高さをその内寸と外寸共に取得するテストである。文章部分の高さはその文字数やフォントの種類、フォントサイズ、行高さなどによって内寸が定められ、これにパディング値とボーダー幅が加算されて外枠の高さとなる。文章要素の場合、スクロールバー等を使って部分的に隠したりせず、一度でその全文を表示しようとする限り、画像を配置する場合のように前もってその高さを設定することは出来ない。

スクリプトによる高さ取得値1

 

ここに外寸高さは offsetHeight で簡単に取得できる。

それは document.getElementById("testP").offsetHeight 一行で済んでしまう。( testP は目的のタグに設置された id ネーム)

ところが、内寸高さは簡単ではない。文章ノードの場合特別な意図がない限り、一般にはその要素の高さは指定しない。そんな指定をしなくても、ブラウザが自動的に高さを決めてくれるからだ。しかし、ブラウザが自動的に算出して描画した、前もって高さが指定されていない文字要素の内寸を、スクリプトで取得することは単純にはできない。

targetElement.style.height では取得できないことはもちろん、IEのcurrentStyleオブジェクトや、Mozilla系ブラウザの getComputedStyle(targetElement,"").getPropertyValue(CSSStyleProperty) オブジェクトでも、取得できないのだ。

では、どうやって内寸高さを取得するか?

それは容易に取得可能な外寸高さから、上下のボーダーやパディングの値を差し引いて算出することが出来るし、そうするしか方法はないだろう。

▲ToTop

行間が変わっても同じ方法で要素の内外高さを取得できるか?

以上のことは行高さが変わっても全く支障なく通用するはずだ。次のテスト要素には、スタイル設定で行間=2 を設定したが、高さを取得する上記の方法で同様に内外の高さを取得することが出来る。

div(margin:4px;)
div(line-height:2;)

p(margin:0 auto 0 auto; padding:5px; border:10px solid lime;width:500px;text-align:left;)
【テスト2】これは、この文章部分の要素の高さをその内寸と外寸共に取得するテストである。文章部分の高さはその文字数やフォントの種類、フォントサイズ、行高さなどによって内寸が定められ、これにパディング値とボーダー幅が加算されて外枠の高さとなる。文章要素の場合、スクロールバー等を使って部分的に隠したりせず、一度でその全文を表示しようとする限り、画像を配置する場合のように前もってその高さを設定することは出来ない。

スクリプトによる高さ取得値2

 
 

上記2つの高さ取得値を比較すれば、行間を50%増しした要素の方が、そうでない要素よりも内外の要素高さが大きな値となっていることに気がつくだろう。

こうして結論として次のことが言える。

位置指定されていない要素の内外の要素高さは、まず外縁の高さを取得したその後に、その値からボーダー幅とパディング値を差し引いて内縁高さを算出すればよい。

▲ToTop

絶対配置要素の属性情報を取得する

次に位置指定された要素、つまり絶対配置、相対配置及び固定配置された要素の場合、その内外の高さはどの様に取得するのだろうか?

位置指定された要素にもoffsetHeight プロパティは通用するのか?

早速テストしてみよう。次のテストで絶対配置要素の内外の高さを取得してみる。

なお、このテスト結果を得るには下の紫ボーダー内にマウスカーソルをoverする必要がある。このmouseoverによってイベントハンドラー関数が起動し、絶対配置要素を表示し、かつその内外高さを結果枠内に表示するように設定してあるためだ。

div(margin:4px;)
div(line-height:1.3;)

p要素
【テスト3】この文字部分にマウスカーソルを重ねるとある要素がポップアップされる。そのポップアップ要素こそposition:absoluteに設定されている絶対配置要素である。

スクリプトによる高さ取得値3

 
 

以上の結果3を検証してみると下図の通りだ。

絶対配置要素の高さをoffsetHeightで取得してみたら・・・

なおブラウザの種類とフォントサイズ設定等により高さと幅は当然固有に変わりうるので、全てのブラウザ、いかなる設定においても高さが62pxになる訳ではない。

位置指定された要素にもoffsetHeight プロパティは通用する───但し表示後に!

上の図で明らかなとおり、絶対配置要素であっても offsetHeight で内外高さを取得することが出来る。勿論、絶対配置要素内の文字列の行高さは自由に設定して良い。但し、ここでのポイントはまず絶対配置要素を表示し、しかる後に、その高さを取得しているということにある。ミネルバの梟は夜啼く、というわけだ。

かねてより絶対配置要素を特定の位置に配置したい場合、当該要素の高さを配置する前に取得するために、文字数と行間値から要素の内部高さをスクリプトで設定していた。

しかし、上記の方法を敷衍して、もし配置する前にoffsetHeightで高さを取得できるとすれば、本体の絶対配置要素を思いの位置に配置することが出来るようになる。これは大きな福音となるので、次に絶対配置要素の配置前サイズ取得を試みてみたい。

▲ToTop

絶対配置要素を表示する前に、その要素高さを取得する

先述のように、テスト3では絶対配置要素をディスプレイ上に表示してから、その後にoffsetHeightを取得た。しかし、Homepageデザイン上で良く遭遇するケースは、ある要素の直上に絶対配置要素を配置するために、配置する前に当該絶対配置要素の高さを知りたい、という状況だ。配置したからこそブラウザは高さを認識するのだが、文字数やフォントサイズ、行間等によって高さが随時変動する要素を実際に配置する前に、その高さを取得することはHomepageデザイン上必須要件だろう。

そこでスクリプト内で<事前に>高さを取得できないかどうか、offsetHeightで取得できるか試してみる。梟を朝でも啼かしてみたいから。

div(background-color:wheat;;margin:10px 4px 4px 4px; border:1px solid black;)
div(text-align:center;line-height:1.3;border:1px solid black;)

p(margin:10px auto 0 auto; padding:5px; border:10px solid purple;width:500px;text-align:left;)
【テスト4】 この枠内部分にマウスカーソルを重ねると、ある要素がマウスカーソルの横方向位置から少し右側で、かつ上部のボーダー沿いにポップアップされる。かつ、その上にも同じ内容のポップアップが表示され、しかしそれはマウスアウトすると、次第にフェイドアウトしていく。

 
 

上では、次のようなことをしている。

  1. まず、本来表示したい絶対配置とは別に、それと全く同じ内容(CSS的にも)で、しかし異なるidをもつ絶対配置要素を作成する。つまりダミー要素を作成する。(但しcloneNodeではなくHTML内の実体のある要素である。cloneNode のままではメモリ上にあるだけなので、高さなどの属性は設定しない限り取得できない。)
  2. 次に、これを表示してその高さを取得する。
  3. 最後に取得された高さを本来配置したい絶対配置要素の配置に利用する。

このようにして「前もって高さが与えられていない絶対配置要素の高さ」を<事前に>取得しているのだ。

実際に使う時にはダミー要素は完全に透明化して(ユーザーに見えないように)配置すればよい。

テスト4においては、ここで行っていることを分かりやすくするために、複写先の「ダミー要素」を敢えてフェイドアウトするように表示した(最初の表示は透明度20%=不透明度80%に設定してある)。序でに、フェードアウトの練習も兼ねた、とも言える(苦笑)。しかし、実際にこの方法を使って絶対配置要素を自在に配置する場合には、このダミー要素を「表示しつつ見せない」ようにすればよい。つまり object.style.visibility='hidden' や object.style.display='none' では高さを計測出来ないから、あくまでもブラウザに描画させる。しかしそれを見えないようにするのだ。つまりダミー要素を完全に透明化にして配置するのである。

なお当然のことであるが、ダミー要素は敢えて異なるidの別要素にしなくても良いだろう。つまり、本来配置すべき絶対配置要素を、まず完全透明化して表示して高さを取得した後に、それを消して同一の要素を本来配置したい位置に、今度は不透明にして見えるように配置すればよいだろう。

▲ToTop

要素の透明化スクリプト

CSSでもJavascriptでもどちらでも良いが、ここでは後者を使った。

ここで目的とする作業を行うにはCSSでも良いのだが、最終的には同一の要素を事前に透明化して高さを取得し、次にそれを隠蔽してから取得した高さ情報を元に、自在に配置したいので、その過程の可視性を考慮して、Javascriptにて作業した。

ところで、要素の透明化は初めての試みなので、位置から学習した。サイト上の諸情報から直ぐに欲しい情報は得られたので、余り苦労することはなかったが、それでも結構時間を要したことは言うまでもない。

さて。

そのスクリプト文はあちこちに掲載されているので、屋上屋を重ねる迄もないのだが、後々の自分のためにも、ここに掲載して記録しておくことにする。

上記スクリプトは、IEとOpera、safari及び最近のMozilla系にしか対応してないが、おそらくそれで十分ではないか、と勝手に理解している。そんな言い訳よりも、古いブラウザへの対応方法は分からないのである(苦笑)。

なお、この関数は num にゼロを設定して起動すれば、要素 opacityElm を完全に透明化する。

▲ToTop