« Yahooニュースでの不幸を是正するグリモン | メイン | QuickTime Proでなくても録音・録画ができる理由 »

JavaScriptからCSSを操作する方法を結構詳しく調べてみた

以下、ほとんどがFirefoxの話です。
実行環境はFirebug。
javascirpt側からcssを指定するとき、よく使われるのは次のような方法。
obj.style.color="#000000";
obj.style.fontSize="12px";
このような方法ではなく、次のような方法でできないかなと思うときがある。
//???は不明部分
obj.???="color:#000000;font-size:12px;";
obj.???("color:#000000;font-size:12px;");
実はこれは簡単で次のようにすればいい。
obj.setAttribute("style","color:#000000;font-size:12px;");
どちらの方法にしろ、style属性は独自の動作をするらしく、cssにはないものを指定しても無効にしてくれる。
例えば以下のcodeを実行してみる。
var obj=document.createElement("div");
obj.setAttribute("style","z-index:inherit;dummy:inherit;color:dummy;");
obj.style.backgroundColor="inherit";
obj.style.dummy="inherit";
obj.style.fontSize="dummy";
console.log(obj.getAttribute("style"));
結果は、次の通り。
z-index: inherit; background-color: inherit;
独自属性に対して同じような処理を行ってみる。
var obj=document.createElement("div");
obj.setAttribute("dummy","z-index:inherit;dummy:inherit;color:dummy;");
console.log(obj.getAttribute("dummy"));
結果はこんな感じ。
z-index:inherit;dummy:inherit;color:dummy;
style属性の時は何か特殊な処理が挟まっているようだ。
調べてみた。
var obj=document.createElement("div");
console.log(obj.style); //=>CSSStyleDeclaration length=0
「CSSStyleDeclaration」という見たこともないobject。
(Kanasan.JSで出てきたのならごめんなさい。自分の記憶にはないです。)
とりあえず、「CSSStyleDeclaration」をgoogleで調べてみた。
hitしたsiteからリンクをたどって見つけたのがこれ。
JavaとFlex?
CSSStyleDeclarationなんて長い名前なのに同じって事はDOMにでも定義されているのか?
でも、JavaとFlexではmethodがあまり一致していない。
以下のcodeを実行して調査。
var obj=document.createElement("div");
var keys=[];
for(var key in obj.style){keys.push(key);}
//console.log(keys.join("\n"));
//以下entry用コード
var step=5,lines=[];
for(var i=0;i<keys.length;i+=step){
    lines.push(keys.slice(i,i+step).join(" "));
}
console.log(lines.join("\n"));
実行結果がこれ。
length cssText getPropertyValue getPropertyCSSValue removeProperty
getPropertyPriority setProperty item parentRule azimuth
background backgroundAttachment backgroundColor backgroundImage backgroundPosition
backgroundRepeat border borderCollapse borderColor borderSpacing
borderStyle borderTop borderRight borderBottom borderLeft
borderTopColor borderRightColor borderBottomColor borderLeftColor borderTopStyle
borderRightStyle borderBottomStyle borderLeftStyle borderTopWidth borderRightWidth
borderBottomWidth borderLeftWidth borderWidth bottom captionSide
clear clip color content counterIncrement
counterReset cue cueAfter cueBefore cursor
direction display elevation emptyCells cssFloat
font fontFamily fontSize fontSizeAdjust fontStretch
fontStyle fontVariant fontWeight height left
letterSpacing lineHeight listStyle listStyleImage listStylePosition
listStyleType margin marginTop marginRight marginBottom
marginLeft markerOffset marks maxHeight maxWidth
minHeight minWidth orphans outline outlineColor
outlineStyle outlineWidth overflow padding paddingTop
paddingRight paddingBottom paddingLeft page pageBreakAfter
pageBreakBefore pageBreakInside pause pauseAfter pauseBefore
pitch pitchRange position quotes richness
right size speak speakHeader speakNumeral
speakPunctuation speechRate stress tableLayout textAlign
textDecoration textIndent textShadow textTransform top
unicodeBidi verticalAlign visibility voiceFamily volume
whiteSpace widows width wordSpacing zIndex
MozAppearance MozBackgroundClip MozBackgroundInlinePolicy MozBackgroundOrigin MozBinding
MozBorderBottomColors MozBorderLeftColors MozBorderRightColors MozBorderTopColors MozBorderRadius
MozBorderRadiusTopleft MozBorderRadiusTopright MozBorderRadiusBottomleft MozBorderRadiusBottomright MozBoxAlign
MozBoxDirection MozBoxFlex MozBoxOrient MozBoxOrdinalGroup MozBoxPack
MozBoxSizing MozColumnCount MozColumnWidth MozColumnGap MozFloatEdge
MozForceBrokenImageIcon MozImageRegion MozMarginEnd MozMarginStart MozOpacity
MozOutline MozOutlineColor MozOutlineRadius MozOutlineRadiusTopleft MozOutlineRadiusTopright
MozOutlineRadiusBottomleft MozOutlineRadiusBottomright MozOutlineStyle MozOutlineWidth MozOutlineOffset
MozPaddingEnd MozPaddingStart MozUserFocus MozUserInput MozUserModify
MozUserSelect opacity outlineOffset overflowX overflowY
imeMode MozBorderEnd MozBorderEndColor MozBorderEndStyle MozBorderEndWidth
MozBorderStart MozBorderStartColor MozBorderStartStyle MozBorderStartWidth
なんか、FlexのCSSStyleDeclarationにあったのと同じようなものがちらほらと...。
(Mozで始まるのはFirefoxの独自実装のはずなのでここでは無視。)
cssText
getPropertyValue
getPropertyCSSValue
removeProperty
getPropertyPriority
setProperty
「length」や「item」なんてものもある。使い方もなんとなく想像できるかも。
試してみる。
var obj=document.createElement("div");
obj.setAttribute("style","z-index:inherit;dummy:inherit;color:dummy;");
obj.style.backgroundColor="inherit";
obj.style.dummy="inherit";
obj.style.fontSize="dummy";
for(var i=0;i<obj.style.length;i++){
    console.log(obj.style.item(i));
}
結果は次の通り。
z-index
background-color
余りにも想像したとおりで逆にびっくり。
for(key in style)でやると、定義していないものまで取得してしまうけど、こっちは定義済みのものだけ。
これは使えそう。
次、cssText。
多分こちらも想像した通りだと思う。
var obj=document.createElement("div");
obj.style.cssText="z-index:inherit;dummy:inherit;color:dummy;";
obj.style.backgroundColor="inherit";
obj.style.dummy="inherit";
obj.style.fontSize="dummy";
console.log(obj.getAttribute("style"));
var obj=document.createElement("div");
obj.setAttribute("style","z-index:inherit;dummy:inherit;color:dummy;");
obj.style.backgroundColor="inherit";
obj.style.dummy="inherit";
obj.style.fontSize="dummy";
console.log(obj.style.cssText);
結果は両方ともこれ。
z-index: inherit; background-color: inherit;
やっぱり。
というか、これって前からあった?
なんか、以前やったようなやってないような。
頭にcss-ってついているのはcssFloatと同じ名前の衝突が理由なのかな。
で、一番気になる以下のmethodを試す。
getPropertyValue
getPropertyCSSValue
removeProperty
getPropertyPriority
setProperty
実行したのはこれ。
var obj=document.createElement("div");
obj.style.color="#000000";
console.log(obj.style.getPropertyValue("color"));
obj.style.backgroundColor="red";
console.log(obj.style.getPropertyValue("background-color"));
console.log(obj.style.getPropertyCSSValue("background-color"));
obj.style.setProperty("z-index","3");
console.log(obj.style.getPropertyValue("z-index"));
で、処理結果。
rgb(0, 0, 0)
red
null
[Exception(略)
ん?あれ?
getPropertyCSSValueがnullを返してる。
setPropertyで落ちてる?
まずはgetPropertyCSSValueから調査。
googleで検索すると、ここが引っかかった。
ああ、なるほど。
上記codeでは、「#000000」で指定したはずの文字色を取得すると「rgb(0,0,0)」に変わってる。
文字列で取得すると、#000・#000000・rgb(0,0,0)の相互変換がプログラマがやらなくてはならない。
この変換を可能とするためにCSSValueというobjectを定義して、変換用のmethodを提供しようとしたらしい。
でも、ややこしいためか廃案となったと。
IEとOperaには実装されておらず、Firefoxは常にnullを返す。
でも、Safariには何故か実装されていると...。
そういえば、さっきgetPropertyCSSValueを調べたときにこれがhitしたけど、まさにCSSValueの話なのね。
前に読んだときはぜんぜん理解できなかったけど、やっと意味がわかった。
で、今気づいたけど、CSSStyleDeclarationを調べたときに、「CSSStyleDeclaration javascript」で検索していれば途中の調査いらなかったのか...。
次は、setProperty。
次のsiteを見つけた。
すごく詳しく書いてある。
いや、というか、はじめからここ探しきれていたら、ここまでやってきた調査っていらなかった...。
setProperty以外は見なかったことにして続き。
setPropertyは第一引数にcss名、第二引数に値、そして第三引数に優先度の指定が必要らしい。
なるほど。
getPropertyPriorityがあるのにsetPropertyPriorityがないので気にはなっていたけどそうゆうことか。
つまり、cssを設定するときには一緒に優先度も指定しなければならないが、逆に値と優先度の取得は別々にしなくてはならないと。
これを踏まえてcodeを書いた。
var obj=document.createElement("div");
obj.style.setProperty("color","#000000","");
obj.style.setProperty("background-color","red","important");
console.log(obj.style.cssText);
console.log(obj.style.getPropertyPriority("color"));
console.log(obj.style.getPropertyPriority("background-color"));
obj.style.removeProperty("color");
console.log(obj.style.cssText);
結果がこれ。
color: rgb(0, 0, 0); background-color: red ! important;
(空行)
important
background-color: red ! important;
これは楽しい。
かなりすっきりした。

トラックバック

このエントリーのトラックバックURL:
http://www.kanasansoft.com/cgi/mt/mt-tb.cgi/152

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)

Google