スタイルとクラスを扱うためのJavaScriptの方法に入る前に、重要なルールがあります。当然のことかもしれませんが、言及しておく必要があります。
要素をスタイルする方法は一般的に2つあります
- CSSでクラスを作成して追加する:
<div class="...">
- プロパティを直接
style
に書き込む:<div style="...">
JavaScriptはクラスとstyle
プロパティの両方を変更できます。
常にstyle
よりもCSSクラスを優先する必要があります。後者はクラスで「処理できない」場合にのみ使用する必要があります。
たとえば、要素の座標を動的に計算し、JavaScriptから設定したい場合は、style
が許容されます。例:
let top = /* complex calculations */;
let left = /* complex calculations */;
elem.style.left = left; // e.g '123px', calculated at run-time
elem.style.top = top; // e.g '456px'
テキストを赤くしたり、背景アイコンを追加したりするなどの他のケースでは、それをCSSで記述してからクラスを追加します(JavaScriptで実行できます)。その方が柔軟性があり、サポートが簡単です。
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
に何かを代入すると、クラスの文字列全体が置き換えられます。必要な場合もありますが、単一のクラスを追加/削除したい場合もよくあります。
そのためには別のプロパティがあります: elem.classList
。
elem.classList
は、単一のクラスをadd/remove/toggle
するためのメソッドを持つ特別なオブジェクトです。
例えば:
<body class="main page">
<script>
// add a class
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
はiterableなので、次のようにfor..of
ですべてのクラスをリストできます。
<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 = ""
。
// if we run this code, the <body> will blink
document.body.style.display = "none"; // hide
setTimeout(() => document.body.style.display = "", 1000); // back to normal
style.display
を空の文字列に設定すると、ブラウザはCSSクラスとその組み込みスタイルを、そのようなstyle.display
プロパティがまったくないかのように通常どおりに適用します。
また、それを行うための特別なメソッドelem.style.removeProperty('スタイルプロパティ')
もあります。したがって、次のようにプロパティを削除できます。
document.body.style.background = 'red'; //set background to red
setTimeout(() => document.body.style.removeProperty('background'), 1000); // remove background after 1 second
style.cssText
による完全な書き換え通常、個々のスタイルプロパティを割り当てるにはstyle.*
を使用します。div.style="color: red; width: 100px"
のように完全なスタイルを設定することはできません。なぜならdiv.style
はオブジェクトであり、読み取り専用だからです。
完全なスタイルを文字列として設定するには、特別なプロパティstyle.cssText
があります。
<div id="div">Button</div>
<script>
// we can set special style flags like "important" here
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.top
を10
に設定するのではなく、10px
に設定する必要があります。そうしないと機能しません。
<body>
<script>
// doesn't work!
document.body.style.margin = 20;
alert(document.body.style.margin); // '' (empty string, the assignment is ignored)
// now add the CSS unit (px) - and it works
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.marginLeft
とstyle.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); // empty
alert(document.body.style.marginTop); // empty
</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);
// now we can read the margin and the color from it
alert( computedStyle.marginTop ); // 5px
alert( computedStyle.color ); // rgb(255, 0, 0)
</script>
</body>
CSSには2つの概念があります。
- 計算されたスタイル値は、すべてのCSSルールとCSS継承が適用された後の、CSSカスケードの結果としての値です。
height:1em
またはfont-size:125%
のようになります。 - 解決されたスタイル値は、最終的に要素に適用される値です。
1em
や125%
のような値は相対的です。ブラウザは計算された値を取得し、すべての単位を固定および絶対にします。例:height:20px
またはfont-size:16px
。幾何学的プロパティの場合、解決された値はwidth:50.5px
のような浮動小数点を持つ場合があります。
昔、getComputedStyle
は計算された値を取得するために作成されましたが、解決された値の方がはるかに便利であることがわかり、標準が変更されました。
したがって、今日では、getComputedStyle
は実際にはプロパティの解決された値を返し、通常は幾何学の場合はpx
で返します。
getComputedStyle
には完全なプロパティ名が必要ですpaddingLeft
、marginTop
、borderTopWidth
のように、必要な正確なプロパティを常に要求する必要があります。そうしないと、正しい結果が保証されません。
たとえば、プロパティpaddingLeft/paddingTop
がある場合、getComputedStyle(elem).padding
で何を取得する必要があるでしょうか?何も取得しないか、既知のパディングから「生成された」値を取得するでしょうか?ここには標準ルールはありません。
:visited
リンクに適用されたスタイルは非表示になっています!訪問済みのリンクは、:visited
CSS擬似クラスを使用して色付けされる場合があります。
ただし、getComputedStyle
はその色へのアクセスを提供しません。そうしないと、任意のページが、ページ上にリンクを作成してスタイルを確認することにより、ユーザーがリンクにアクセスしたかどうかを知ることができてしまうためです。
JavaScriptは、:visited
によって適用されたスタイルを確認できない場合があります。また、CSSには、:visited
で幾何学的な変更を伴うスタイルを適用することを禁じる制限があります。これは、悪意のあるページがリンクが訪問されたかどうかをテストし、したがってプライバシーを侵害するための抜け道がないことを保証するためです。
まとめ
クラスを管理するには、2つのDOMプロパティがあります
className
– 文字列値。クラスのセット全体を管理するのに適しています。classList
–add/remove/toggle/contains
メソッドを備えたオブジェクト。個々のクラスに適しています。
スタイルを変更するには
-
style
プロパティは、キャメルケースのスタイルを持つオブジェクトです。読み書きすることは、"style"
属性の個々のプロパティを変更することと同じ意味を持ちます。important
やその他のまれなものを適用する方法については、MDNにメソッドのリストがあります。 -
style.cssText
プロパティは、"style"
属性全体、つまりスタイルの完全な文字列に対応します。
解決されたスタイルを読み取るには(すべてのクラスを考慮し、すべてのCSSが適用され、最終値が計算された後)
getComputedStyle(elem, [pseudo])
は、それらを含むスタイルライクなオブジェクトを返します。読み取り専用です。
コメント
<code>
タグを使用し、数行の場合は<pre>
タグで囲み、10行を超える場合はサンドボックス(plnkr、jsbin、codepen…)を使用してください。