JavaScriptでスタイルとクラスを扱う方法を習得する前に、 – ここには重要なルールがあります。うまくいけばそれは十分明らかですが、それでも言及する必要があります。

一般的には要素をスタイルする2つの方法があります:

  1. CSS でクラスを生成し、それを追加します: <div class="...">
  2. style に直接プロパティを書きます: <div style="...">.

CSS は常に好まれる方法です – HTML に対してだけではなく JavaScript でも同様です。

クラスが “処理することが出来ない” 場合にのみ、style プロパティを操作するべきです。

例えば、要素の座標を動的に計算し、JavaScriptからそれを設定する場合には style は受け入れられます。:

let top = /* 複雑な計算 */;
let left = /* 複雑な計算 */;
elem.style.left = left; // e.g '123px'
elem.style.top = top; // e.g '456px'

テキストを赤にしたり、背景アイコンを追加するような他のケースの場合 – CSS でそれを記述した後にそのクラスを適用します。それはより柔軟でサポートしやすくなります。

className と classList

クラスを変更することは、スクリプトで最も頻繁に行われる操作の1つです。

ずっと昔、JavaScript には制限がありました: "class" のような予約語はオブジェクトプロパティにはできませんでした。その制限は今は存在しませんが、その当時は elem.class にように "class" プロパティを持つことは不可能でした。

したがって、クラスに対しては類似したプロパティ名 "className" が導入されました: elem.className"class" 属性に対応します。

例:

<body class="main page">
  <script>
    alert(document.body.className); // main page
  </script>
</body>

もし何かを elem.className に割り当てた場合、クラスの文字列全体を置き換えます。それが必要なときもありますが、多くの場合は1つのクラスの追加/削除がしたいです。

そのための別のプロパティもあります: elem.classList です。

elem.classList はクラスを 追加/削除/切り替える ためのメソッドを持つ特別なオブジェクトです。

例:

<body class="main page">
  <script>
    // クラスを追加します
    document.body.classList.add('article');

    alert(document.body.className); // main page article
  </script>
</body>

したがって、className を使って完全なクラス文字列操作したり、classList を使って個々のクラスを操作することができます。私たちが選ぶものは、私たちのニーズに応じたものになります。

classList のメソッド:

  • elem.classList.add/remove("class") – クラスの追加/削除をします。
  • elem.classList.toggle("class") – もしクラスが存在する場合は削除します。そうでなければ追加します。
  • elem.classList.contains("class") – 指定されたクラスをチェックし、 true/false を返します。

それに加え、classList は反復可能です。なので、このようにすべてのクラスを列挙する事ができます:

<body class="main page">
  <script>
    for(let name of document.body.classList) {
      alert(name); // main, and then page
    }
  </script>
</body>

要素のスタイル

プロパティ elem.style"style" 属性に書かれたものに対応するオブジェクトです。elem.style.width="100px" の設定は、属性 style="width:100px" を持っているかのように機能します。

複数語のプロパティは、キャメルケースが使われます:

background-color  => elem.style.backgroundColor
z-index           => elem.style.zIndex
border-left-width => elem.style.borderLeftWidth

例:

document.body.style.backgroundColor = prompt('background color?', 'green');
プレフィックス付きのプロパティ

-moz-border-radius-webkit-border-radius のようなブラウザプレフィックスが付いたプロパティもまた同じルールに従います。例えば:

button.style.MozBorderRadius = '5px';
button.style.WebkitBorderRadius = '5px';

つまり: ダッシュ "-" は大文字になります。

スタイルプロパティのリセット

時々、スタイルプロパティを割り当て、後ほどそれを削除したい場合があります。

例えば、要素を隠すために elem.style.display = "none" と設定できます。

そして、後でそれがセットされていなかったかのように、 style.display を削除したいかもしれません。delete elem.style.display の代わりに空行を割り当てるべきです: elem.style.display = "".

// このコードを実行すると、<body> が "点滅" します
document.body.style.display = "none"; // 隠します

setTimeout(() => document.body.style.display = "", 1000); // 通常に戻ります

display を空文字列に設定した場合、ブラウザは通常 CSS クラスと組み込みのスタイルを適用します。まるで style プロパティが全くないかのように振る舞います。

style.cssText で完全に書き直す

通常、個々のスタイルプロパティを割り当てるために style.* を使います。div.style はオブジェクトであり、読み取り専用であるため、div.style="color: red; width: 100px" のような完全なスタイルを設定することはできません。

文字列で完全なスタイルを設定するための特別なプロパティstyle.cssText があります:

<div id="div">Button</div>

<script>
  // ここで "important" のような特別なスタイルのフラグを設定することも出来ます
  div.style.cssText=`color: red !important;
    background-color: yellow;
    width: 100px;
    text-align: center;
  `;

  alert(div.style.cssText);
</script>

このような代入は既存のすべてのスタイルを削除するので、めったに使われません。: それは追加ではなく置換です。場合によっては必要なものを削除する可能性があります。しかし、私たちが重要なものを削除しないことを知っているとき、新しい要素に対しては行う事ができます。

属性を設定することで同じことを達成することが出来ます。: div.setAttribute('style', 'color: red...').

単位を気にする

CSS の単位はスタイルの値の中で指定する必要があります。

例えば、elem.style.top10 ではなくむしろ 10px とする必要があります。そうれなければ動作しません:

<body>
  <script>
    // 動作しません!
    document.body.style.margin = 20;
    alert(document.body.style.margin); // '' (空文字列、この代入は無視されます)

    // 今 CSS の単位(px) を追加 -- これは動作します
    document.body.style.margin = '20px';
    alert(document.body.style.margin); // 20px

    alert(document.body.style.marginTop); // 20px
    alert(document.body.style.marginLeft); // 20px
  </script>
</body>

ブラウザが最後の行で style.margin を “アンパック” し、style.marginLeftstyle.marginTop(および他の部分的なマージン)をどのように推測するか注意してください。

算出スタイル: getComputedStyle

スタイルを変更するのは簡単です。しかしどうやってそれを 読み ますか?

例えば、要素のサイズ、マージン、色が知りたいです。どうやりますか?

style プロパティは CSS カスケードなしで、その "style" 属性の値だけを操作します。

なので、elem.style を使って CSS クラスから来たものを読むことは出来ません。

例えば、ここでは style はマージンを見ません:

<head>
  <style> body { color: red; margin: 5px } </style>
</head>
<body>

  The red text
  <script>
    alert(document.body.style.color); // 空
    alert(document.body.style.marginTop); // 空
  </script>
</body>

…しかし仮にマージンを 20px に増加する必要がある場合はどうすればよいでしょう?そのために現在の値がほしいです。

そのための別のメソッドがあります: getComputedStyle.

構文は次の通りです:

getComputedStyle(element[, pseudo])
element
値を読み取る要素
pseudo
疑似要素(必要な場合)。例えば ::before。空文字列または引数なしは要素自身を意味します。

結果は、elem.style のようにスタイルプロパティを持つオブジェクトですが、今はすべての CSS クラスに関してのものです。

例:

<head>
  <style> body { color: red; margin: 5px } </style>
</head>
<body>

  <script>
    let computedStyle = getComputedStyle(document.body);

    // 今やそこからマージンや色を読み取る事ができます

    alert( computedStyle.marginTop ); // 5px
    alert( computedStyle.color ); // rgb(255, 0, 0)
  </script>

</body>
算出(comupted)と解析(resolved)値

CSS には2つのコンセプトがあります:

  1. 算出 スタイル値(computed style value)は、CSS カスケードの結果として、すべての CSS ルールと CSS 継承が適用された後の値です。height:1em または font-size:125% のように見えます。

  2. 解析 スタイル値(resolved style value)は要素に最終的に適用される値です。1em or 125% のような値は相対的なものです。ブラウザは計算された値を取り、height: 20pxfont-size: 16px のようにすべての単位を固定し絶対的にします。 幾何学プロパティの場合、解析された値は width:50.5pxのような浮動小数点を持ちます。

ずっと以前に、getComputedStyle は計算された値を取得するために作られましたが、解析された値がはるかに便利であることが分かり、標準が変更されました。

したがって、最近では getComputedStyle は実際にはプロパティの解析された値を返します。

getComputedStyle には完全なプロパティ名が必要です

paddingLeftmarginTopborderTopWidth のように、常に正確なプロパティを求めてください。 そうしないと、正しい結果が保証されません。

例えば、paddingLeft/paddingTop プロパティがある場合、getComputedStyle(elem).padding のためにどうすればよいでしょうか?何もない、または知られているパディングから"生成された" 値があるでしょうか?そこに標準的なルールはありません。

他にも矛盾があります。 たとえば、一部のブラウザ(Chrome)では下記のドキュメントに"10px" と表示されていますが、他の一部のブラウザ(Firefox)では – そうではありません:

<style>
  body {
    margin: 10px;
  }
</style>
<script>
  let style = getComputedStyle(document.body);
  alert(style.margin); // Firefox では空文字です
</script>
“訪問された” リンクのスタイルは表示されません!

訪問されたリンクは :visited CSS 疑似クラスを使って色付けされるかもしれません。

しかし、getComputedStyle はその色へのアクセスを提供しません。なぜなら、そうでなければ、任意のページが、ページ上でそれを作りスタイルをチェックすることによって、ユーザがリンクを訪れたかどうかを知ることができるためです。

JavaScriptでは、 :visited によって適用されたスタイルは見えません。また、:visited にジオメトリの変更スタイルを適用することを禁止するという制限が CSS にはあります。それは、リンクが訪問された場合に悪意のあるページがテストしてプライバシーを破る方法がないことを保証するためです。

サマリ

クラスを管理するために、2つのDOMプロパティがあります:

  • className – 文字列値で、クラスのセット全体を管理するのに良いです。
  • classList – メソッド add/remove/toggle/contains を持つオブジェクトで, 個々のクラスを管理するのに良いです。

スタイルを変更するために:

  • style プロパティはキャメルケース化されたスタイルを持つオブジェクトです。それへの読み書きは、 "style" 属性の個々のプロパティを変更するのと同じ意味を持ちます。important や他の珍しいものを適用する方法を知るには – MDN にメソッドのリストがあります。

  • style.cssText プロパティは "style" 属性全体に対応し、スタイルの完全な文字列です。

解析されたスタイル(すべてのクラスに関して、すべてのCSSが適用され、最終的な値が計算された後)を読むために:

  • getComputedStyle(elem[, pseudo]) はそれらのスタイルライクなオブジェクトを返します。読み取り専用です。

タスク

重要性: 5

通知を作成する関数 showNotification(options) を書いてください。通知は <div class="notification"> という要素にしてください。通知の内容などはオプションで指定できるようにしてください。通知は1.5秒後に自動的に消えるようにしてください。

オプションは次の通りです:

// ウィンドウの右上近くに "Hello" というテキストを持つ要素を表示します
showNotification({
  top: 10, // ウィンドウのトップから 10px (デフォルトは 0px)
  right: 10, // ウィンドウの右端から 10px (デフォルトは 0px)
  html: "Hello!", // 通知として表示する HTML
  className: "welcome" // div への追加クラス (任意)
});

新しいウィンドウでデモ

指定された top/right 座標へ要素を表示するために、 CSS の配置を使用してください。ソースのドキュメントは必要なスタイルを持っています。

タスクのためのサンドボックスを開く

チュートリアルマップ

コメント

コメントをする前に読んでください…
  • 自由に記事への追加や質問を投稿をしたり、それらに回答してください。
  • 数語のコードを挿入するには、<code> タグを使ってください。複数行の場合は <pre> を、10行を超える場合にはサンドボックスを使ってください(plnkr, JSBin, codepen…)。
  • 記事の中で理解できないことがあれば、詳しく説明してください。