SimpleBoxes

style.js - CSSスタイルを取り扱うライブラリ

JavaScriptでCSSスタイルを取り扱うライブラリstyle.jsを自作していました。

今回、IT戦記にて書かれた、getComputedStyleについて調べてたら深みにハマったのでメモという記事を参考にバージョンアップしてみました

使い方は簡単です。style.jsで定義されたStyleのインスタンスを取得して、任意のCSSプロパティを指定します。

<script src="style.js" type="text/javascript"></script>
<script type="text/javascript">
// <![CDATA[
var style = new Style();
style.set('color','red'); // set メソッドでスタイルを指定
style.set('background-color','white'); // set メソッドではプロパティ名は CSS 書式と同等
style.set('borderColor','blue'); // JavaScript 書式のプロパティ名ももちろん使えます
var hoge = document.getElementById('hoge');
style.affect(hoge); // affect メソッドでスタイルを hoge に割り付ける
var fuga = document.getElementById('fuga');
style.importStyle(fuga); // fuga からスタイルを取得する
style.affect(hoge); // fuga のスタイルを hoge にコピー
// ]]>
</script>

Styleのサンプルコード

特定のスタイルをバッファしておいて、DOMオブジェクトに適用するという感じの利用方法を想定しています。

style.jsは、以下のようなスクリプトになります。

// spica javascript libraries - style.js
// == written by Takuya Otani <takuya.otani@gmail.com> ===
// == Copyright (C) 2006 SimpleBoxes/SerendipityNZ Ltd. ==

function Style()
{
  this._style = {};
  return this;
}
Style.prototype = {
  set : function(elem,value)
  {
    this._style[this.camelize(elem)] = value;
    return true;
  },
  get : function(elem)
  {
    return this._style[elem];
  },
  getStyle : function()
  {
    return this._style;
  },
  importStyle : function(object)
  {
    var style = object.currentStyle || document.defaultView.getComputedStyle(object, '');
    if (!style) return false;
    var property = StyleProperties();
    for (var i=0,n=property.length;i<n;i++)
    {
      if (style[property[i]] != undefined)
        this._style[property[i]] = style[property[i]];
    }
    return true;
  },
  affect : function(object)
  {
    if (!object || !object.style) return;
    for (var elem in this._style)
    {
      object.style[elem] = this._style[elem];
    }
  },
  camelize : function(name)
  {
    if (!name.match(/-/)) return name;
    return name.replace(/-(\w)/g,function(str,chr) { return( chr.toUpperCase() ) });
  }
};

強調したStyleProperties()は、CSS level 2プロパティ一覧を返す関数です。style.js内で定義しますが、長くなるので内容は「続き」に。

わざわざ配列として定義しなくても済めばいいんですが、SafariだとgetComputedStyleで取得したstyleオブジェクトに対して、inで回しても、プロパティのリストが返ってきません。

Safari 2.0.4で確認。Safari 3.0では、異なる結果でしたが、プロパティのリストが返ってこないのは、現状では一緒でした。

var style = object.currentStyle || document.defaultView.getComputedStyle(object, '');
for (var property in style)
{
  document.write([property,' : ',style[property],'<br />\n'].join(''));
}

上記のようなコードを実行しても、「color」や「backgroundColor」のような値はpropertyに現れません。しかしながら、style['color']と指定すると、ちゃんとカラーコードが返ってきたりします。

上述の理由のため、StyleProperties()というプロパティのリストを返す関数を定義します。必要ないプロパティは削ってしまうというような使い方もできると思います。

var StyleProperties = function()
{
  // based on DOM level 2 CSS interface. http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSS2Properties
  return [
    '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',
    'playDuring',
    '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'
  ];
};

スポンサーリンク

<< Path Finder 4.7 :: sb/Serene Bachの静的生成に対するコンセプト >>