uhyohyo.net

JavaScript初級者から中級者になろう

五章第一回 計算済みスタイル

このページの最終更新日:

五章では、DOMの話に戻ってCSSの操作について詳しく解説していきます。CSSについては二章十一回で少し触れましたが、これはまだまだ序の口です。五章ではもっと詳しい中身についてやっていきます。

今回は、まずその初めとして、計算済みスタイルというものを取得することについて解説します。

まずは次のサンプルを見てみましょう。


<!doctype html>
<html>
  <head>
    <title>test</title>
    <style type="text/css">
      p { background-color: yellow; }
    </style>
  </head>
  <body>
    <p>testtest</p>

  </body>
</html>

このサンプルで、p要素の背景は黄色です。それは当然、スタイルシートでp要素のbackground-colorを黄色に設定しているからです。

ここで、pタグにはstyle属性はなく、特に何も書かれていません。しかしp要素には背景が黄色だというスタイルがちゃんと適用されています。このように、ある要素に実際に適用されるスタイルが、計算済みスタイルです。

二章十一回で解説した方法はstyle属性に書かれたスタイルを取得したり書き換えたりする方法ですから、今回のような場合に計算済みスタイルは以前の方法では取得できません。

計算済みスタイルは、次のように取得します。


<!doctype html>
<html>
  <head>
    <title>test</title>
    <style type="text/css">
      p { background-color: yellow; }
    </style>
  </head>
  <body>
    <p>testtest</p>

    <script type="text/javascript">
      var p = document.getElementsByTagName('p').item(0);

      var style = document.defaultView.getComputedStyle(p, null);
      console.log(style.backgroundColor);
    </script>
  </body>
</html>

このサンプルでは、document.defaultViewが持つメソッドgetComputedStyleを呼び出していることが分かります。第1引数に計算済みスタイルを取得したい要素を渡せばいいことが分かります。第2引数はnullとなっていますが、これの意味はあとで解説します。

まずdocument.defaultViewは、見ての通り、documentが持つdefaultViewプロパティです。これは、現在のドキュメントに対応するWindowオブジェクトというものを取得します。

Windowオブジェクトについては深入りしませんが、Documentに対して対応するWindowというのが存在します。イメージとしては、表示などに関するものはDocumentではなくWindowの領分です。今回は、Windowオブジェクトが持つメソッドgetComputedStyleを利用します。

getComputedStyleは、計算済みスタイルを表すオブジェクトを返します。このオブジェクトはCSSStyleDeclarationというオブジェクトで、この種類のオブジェクトは、具体的にひとつひとつのプロパティを参照したりするのに使うものです。実は、第二章第十一回で紹介した、HTMLElementが持つstyleプロパティもこのCSSStyleDeclarationの一種です。

すなわち、HTMLElementのstyleプロパティと同じように扱うことができます。だから、このサンプルでは、そのCSSStyleDeclarationが持つbackgroundColorプロパティを表示しています。

ちなみに、スタイル指定は「yellow」となっていますが、スタイル指定で表示されるのは"yellow"ではないと思います。ブラウザによって差異はありますが、"#ffff00"とか"rgb(255,255,0)"とか表示されるのではないでしょうか。このように、ソースに書いた値は、ブラウザによって解釈されてブラウザにとって扱い易い形になってブラウザに記憶されています。それを参照したとき、ブラウザは改めて文字列を作っているため、このようにもとの形と違うようになるのです。

ただ、注意する必要があるのが、getComputedStyleによって取得したスタイルは、HTMLElementのstyleとは違い、書き換えできません。あくまで見るだけです。

擬似要素

では、getComputedStyleの第2引数について説明します。実は、第2引数は擬似要素を指定します。擬似要素はCSSの用語で、例えば::first-letterのようなものです。これはセレクタにおいて使われるもので、HTML要素によらずにある部分を指定するためのものです。例えば、この::first-letterは次のように使います。


p::first-letter{
    font-size: 2em;
}

::first-letterは「最初の文字」を意味します。上の例では、p要素中の最初の文字だけ文字サイズが違うということになります。

ということは、p要素の中でも最初の文字とそれ以外とで計算済みスタイルが異なるということです。となると、ある擬似要素に該当する部分の計算済みスタイルを取得するということがやりたくなります。これを実現するのがgetComputedStyleの第二引数です。取得したい擬似要素を文字列で指定します。前に見たように、擬似要素を指定しない場合はnullです。


<!doctype html>
<html>
  <head>
    <title>test</title>
    <style type="text/css">
      p { background-color: yellow; }
      p:first-letter{
        font-size:2em;
        background-color: aqua;
      }
    </style>
  </head>
  <body>
    <p>testtest</p>

    <script type="text/javascript">
      var p = document.getElementsByTagName('p').item(0);

      var style = document.defaultView.getComputedStyle(p, "::first-letter");
      console.log(style.backgroundColor);
    </script>
  </body>
</html>

ちなみに、似た形でも、:hover:visitedなどは擬似クラスと呼ばれ、擬似要素ではないのでこの方法は使えません。擬似クラスはコロンが1つ、擬似要素はコロンが2つという違いがありますので気をつけましょう。ただし、歴史的経緯により、擬似要素でもコロン1つで書かれることがあります(:first-letterなど)。

次回から、CSSの構造などについて詳しく説明していきます。

window

現在の文書のDocumentオブジェクトを表すものとしてdocumentという変数がもともと存在していることは昔解説した通りです。

実は、もうひとつDOMにもともと存在している変数としてwindowがあります。名前から想像がつくと思いますが、documentに対応するWindowオブジェクトが入っているのがwindow変数です。つまり、上でdocument.defaultViewと書いていたのはwindowと書いても構いません。

さらに、windowは実はグローバルオブジェクトです。グローバルオブジェクトというのは特殊なオブジェクトで、グローバル変数は実はグローバルオブジェクトのプロパティであるということです。そのため、次のようなことが起こります。


var str = "foo";
console.log(window.str); // "foo"

逆に考えると、windowのプロパティはグローバル変数です。なので、実はwindow.getComputedStyleは単にgetComputedStyleのようにグローバル変数として扱っても利用できます。結局のところ、document.defaultView.getComputedStyleは単にgetComputedStyleと書くことができます。ただ、windowをグローバル変数として扱うのは分かりにくいしバグの元なので、なるべくやらないようにしましょう。