ビューポート(表示域)のキャンバス座標系における位置

ブラウザで、ビューポート(表示域)のキャンバス座標系における位置、平たくいうと画面のスクロールの状態はどう取れるだろうか?

基本的には、scrollTop scrollLeft - ブラウザのスクロール状態を取得する の通りである。つまり、次のようにすればいい。

var left = document.documentElement.scrollLeft || document.body.scrollLeft;
var top = document.documentElement.scrollTop || document.body.scrollTop;

なぜこれでいいのか、私の実験の結果を踏まえて簡単に説明しよう。scrollLeft を例に取る。
document.documentElement(A) を見るべきなのは、ブラウザが標準モードのとき、そして document.body(B) は、互換(quirk)モードのときになる。で、おもしろいのは、A.scrollLeft と B.scrollLeft で使えないほうは必ず0になっているみたいなのだ。

var left = document.documentElement.scrollLeft || document.body.scrollLeft;

で、document.documentElement.scrollLeft が 0 になるのは、

  1. 互換モードで document.documentElement が使えないとき
  2. 標準モードでスクロールがなくて実際に 0 のとき

のいずれかになる。いずれも、|| の後ろ側の body がらみの式が評価されてしまうが、

  1. のときは、document.body が使われるから OK
  2. のときは、document.body を使うのは本来正しくないが、document.body.scrollLeft はそれゆえ必ず 0 を返す。この場合のスクロールがなくて正しい値は 0 であり、たまたま一致するので結果オーライ。

となる。なかなか巧妙なやり方だ。