スタイルとクラスを扱うための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…)を使用してください。