2006年10月12日

表示領域の取得2

表示領域を取得するクロスな関数です。
今までは何とか回避してきたんですが・・・
x Library(cross-browser.com)で十分だったし。

クロスな検査をしたあとに、関数を上書きするようにしているので、一旦確定したあとは「多少」軽くなるかと。試してないのでなんとも・・・^^;

■ 動作確認

IE 4.0/5.0/5.5/6.0
FF 1.0/1.5
NS 6.2/7.1
OP 7.02/8.53/9.01
Sleipnir 2.30



function getClientSize(){
  var
    w = window,
    b = document.body,
    e = document.documentElement,
    fg =
      document.compatMode == "CSS1Compat" &&
      !window.opera;
  // opera, netscape を除く標準モードの場合
  if(fg && !window.opera && e && e.clientHeight && e.clientWidth)
    getClientSize = function (){
      return {'width':e.clientWidth, 'height':e.clientHeight};
    }
  // opera, netscape と、互換モードの場合
  else if(b && b.clientHeight && b.clientWidth)
    getClientSize = function (){
      return {'width':b.clientWidth, 'height':b.clientHeight};
    }
  // その他
  else if(w.innerHeight && w.innerWidth){
    // inner??? と offset??? がある場合
    if(e && e.offsetHeight && e.offsetWidth)
      getClientSize = function (){
        return {
          'width' :(w.innerHeight < e.offsetHeight) ? w.innerWidth - 14 : w.innerWidth,
          'height' :(w.innerWidth < e.offsetWidth ) ? w.innerHeight - 14 : w.innerHeight
        };
      }
    // inner??? がある場合
    else
      getClientSize = function (){
        return {'width':w.innerWidth, 'height':w.innerHeight};
      }
  // どうにもならない場合
  }else getClientSize = function (){return {'width':0, 'height':0};}
  return getClientSize();
}


何が悪いって netscape 6 が悪い!
x Library でもうまくいきません。なぜって document.height が取得できないから!


コメント「// inner??? と offset??? がある場合」以下って・・・
って実は ns6 のためと言っても過言じゃありません。
x Library に準ずるならば offsetなんたらではなく、document.なんたら(width とか height ね)で検査になります。・・・この項目増やしてもいいかも。

■ 用法

形式: ret = getClientSize();

戻り値:ret


ハッシュで返ってきます。
ret.width に表示領域の幅、ret.height に高さを保持しています。
準?未対応ブラウザでは、スクロールバーの領域まで含まれるかも知れません。
document.innerHeight, document.innerWidth の取得でも失敗すると表示領域のサイズに関わらず ret.width, ret.height ともに 0 を返します。



■ ソースの説明


は、いっか・・・。
ソースコードに突っ込んだコメントで全てですw

あえて補足すると、前回の「閑話休題 表示領域の取得」に貼ったリンク先には netscape はありませんが、ns 7 は opera と同様の挙動をします。
document.documentElement.clientHeight/.width
が 0 になるので、一回目の if ではじかれます。

ns 7 は、次の else if(// opera, netscape と、互換モードの場合)で引っかかるのですが、ns 6 だと引っかかりません。
document.body.clientHeight
が 0 になるので、はじかれます。width はあるんすよ。
ちなみに document.width は使えるのに document.height は 0 ^^;

で、結局 ns6 の場合は、offsetHeight/offsetWidth と比較することで、スクロールバーの存在を確認して、スクロールバーがあればその分(標準として 14 pixel)を減算した値を表示領域とみなしています。


上でも書きましたが、さらにより広範囲に対応するのであれば、document.height/document.width との検査でスクロールバーの存在を確認して見込み分引くような場合も追加する方がいいかも知れません。

んが。
IE5.0/5.5/6.0, FF1.0/1.5, OP7/8/9, NS7 であれば下記で十分だったりします。
function getClientSize(){
  if(document.compatMode == "CSS1Compat" && !window.opera && document.documentElement && document.documentElement.clientHeight && document.documentElement.clientWidth)
    getClientSize = function (){
      return {'width':document.documentElement.clientWidth, 'height':document.documentElement.clientHeight};
    }
  else
    getClientSize = function (){
      return {'width':document.body.clientWidth, 'height':document.body.clientHeight};
    }
  return getClientSize();
}


上、2つのコードでは width と height ともに確認していますが、これは片方があって片方がない(0になる)なんてことがあるためです。ま、無いのは、height ですけど。


推敲してみて、ちょっと補足。
「結局 ns6 の場合は、offsetHeight/offsetWidth と比較することで、スクロールバーの存在を確認して」
と書いていますが、確認というより推測です。
表示領域のサイズよりドキュメントのサイズの方が大きければ、おそらくスクロールバーがあるだろうということです。

より確実にするなら、何も書き出されていない状況で、レイヤーでも配置して、レイヤーのサイズを少しずつ変えて、表示領域と思われるプロパティを監視して・・・と。

一応、やってみましたが、利用先が限定される上に、たったこれだけのことで、html も script も複雑になってしまう。どうも本末転倒なのでやめました。w


ヤバイ。最近、javascript ばっかだ。どんどん忘れてゆく・・・
posted by HiFa at 02:43 | 🌁 | Comment(1) | TrackBack(1) | JavaScript雑感 | このブログの読者になる | 更新情報をチェックする
>>> スパムコメントは消してますよん。 お互い無駄な労力は避けましょう。 <<<

この記事へのコメント

1つめのソースコードコメントに「 // opera, netscape と、標準モードの場合」とありましたが、間違いです。
「 // opera, netscape と、互換モードの場合」
に訂正しました。
Posted by Hifa at 2006年10月12日 09:40
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック

閑話休題 表示領域の取得
Excerpt: ブラウザごとの表示領域の取得
Weblog: Script雑感
Tracked: 2006-10-12 02:50
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。