Javascript cssレンダリングスタイル値の取得テクニック

4992 ワード

ずっと忙しくて更新していないので、最近開発で使用したcssレンダリングツリースタイルの抽出方法についてまとめます.
 
レンダースタイルの抽出(Extract Render Style)
IEはdomElementからcurrentStyleオブジェクトからインスタント計算を抽出するスタイル標準ブラウザはwindowを使用する.getComputedStyleメソッド取得IEの下にruntimeStyleオブジェクトがあり、DOMのstyleプロパティを変更せずにスタイルを適用できます.runtimeStyleはランタイム書き込みスタイル、currentStyleはレンダリング後のスタイルを読み込むために使用されます.
*jQueryのcss()メソッドは両方の互換性を処理しており、css()メソッドでレンダリングされたスタイル値を抽出できますが、実際のアプリケーションではいくつかの問題が発生します.以下、これらの問題を解決する方法について説明します.
 
 
擬似クラススタイルの取得方法
標準ブラウザはgetComputedStyleメソッドによって擬似クラスstyleオブジェクトを得ることができ、以下の方法window.getComputedStyle(domElement,':after);jQuery css()メソッドでは後のパラメータがnullであるため、偽クラスのスタイルを取ることができない.
ieこの方発をサポートしないで、ただ、スタイルシートのオブジェクトを遍歴して、セレクタに一致して検索することができて、このようにcssの書く比較基準とセレクタの特徴を約束してこそ、正確で効果的に必要なスタイルを見つけることができます
 
...
	var more=$('span.morelink');
	if(window.getComputedStyle){
		style=window.getComputedStyle(more[0],':after');
	}else{
		style=getStyleSheet('span.morelink a:after');
	}

	//ie  styleSheets   
	function getStyleSheet(selector){
		var sheets=document.styleSheets,regxp=new RegExp(".*"+selector+"\\s*$","i");
		for(var is=sheets.length-1;is>=0;is--){//  , css      
			var rules=sheets[is].rules||sheets[is].cssRules;
			for(var ir=rules.length-1;ir>=0;ir--){
				var rule=rules[ir];
				if(rule.selectorText&&regxp.test(rule.selectorText)){
					return rule.style;
				}
			}
		}
	}

 
 
 
カラー16進標準値の取得
ieにおいてレンダリングスタイルcolorやbackgroundColorを得る値は一般にFFFFという16進数の形式である、ffなどの標準ブラウザで得られるのはrgb(255,0,0)という形式であり、以下の方法でいずれも16進数の形式に変換することができる.chromeブラウザで透過(transparent)するとrgba(0,0,0,0)が得られ、メソッドでも処理する.
 
               function rgb2hex(rgb) {
	 if('rgba(0, 0, 0, 0)'==rgb)rgb='transparent';
	 var m= rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/i);
	 if(!m)return rgb;
	 function hex(x) {
	  return ("0" + parseInt(x).toString(16)).slice(-2);
	 }
	 return "#" + hex(m[1]) + hex(m[2]) + hex(m[3]);
	}

 
 
 
background-position値の取得
ieでレンダリングされたスタイルではbackground-positionは得られず、対応するスタイルをbackground-position-xとbackground-position-yに分解するには以下の方法で得ることができる.
 
               //    jquery css()        
	function getBackgroundPosition(t){
		var v=t.css('background-position');
		if(!v){
			v=t.css('background-position-x')+' '+t.css('background-position-y');
		}
		return v;
	}

 
background-positionでパーセンテージを使用する場合、ieではレンダリングスタイルのパーセンテージ値を得ることができず、スタイル設定background-position:20%10 pxのような即時計算px値しか得ることができず、ieでは対応するpx値しか得ることができない.(幅、高さ、top、leftなどの値も同様)パーセンテージ値を得るには、スタイルシートオブジェクトを巡回することができる.(同じくgetStyleSheetメソッドを使用)
 
 
2012-5-11更新
 
現在のページのすべてのスタイル(import参照を含むcss)から、指定したファイルのパラメータに一致するセレクタのスタイルを検索します.
selectorRegExp--セレクタをフィルタする正規表現
cssFileName-cssファイル名(オプションパラメータ)
アイテムに直接接着する
Ex.fn.getStyle4Sheet=function(selectorRegExp,cssFileName){
		var sheets=document.styleSheets,regexp=selectorRegExp;
		var styles=[];
		var fNameRegex=new RegExp('(.*/)?'+cssFileName+'(\\?.*)?');
		for(var is=sheets.length-1;is>=0;is--){
			var sheet=sheets[is],imports=sheet.imports||getImports(sheet.cssRules);
			var rules=sheet.rules||sheet.cssRules;
			if(!cssFileName||fNameRegex.test(sheet.href)){
				var t=getStyle4Rules(rules,regexp);
			}
			try{
				findInImports(imports,cssFileName,regexp);
			}catch(e){}
		}
		var style=styles.length?{}:null;
		for(var i=styles.length-1;i>=0;i--){
			for(var k in styles[i]){
				var v=styles[i][k];
				if(v!=''||i==styles.length-1)style[k]=v;
			}
		}
		return style;
		function getImports(rs){
			var result=[];
			if(!rs)return result;
			for(var i=0,n=rs.length;i<n;i++){
				if(rs[i].type==3)result.push(rs[i]);
			}
			return result;
		}
		function findInImports(imports,cssFileName,regexp){
			for(var i=0,n=imports.length;i<n;i++){
				var imp=imports[i];
				if(!cssFileName||fNameRegex.test(imp.href)){
					var rules=imp.rules||imp.styleSheet.cssRules;
					var t=getStyle4Rules(rules,regexp);
				}
				findInImports(imp.imports||getImports(imp.styleSheet.cssRules),cssFileName,regexp);
			}
		}
		function getStyle4Rules(rules,regexp){
				for(var ir=rules.length-1;ir>=0;ir--){
					var rule=rules[ir];
					if(rule.selectorText&&regexp.test(rule.selectorText)){
						styles.push(rule.style);
					}
				}
		}
}

 
このテクニックを再整理すると本編が更新されます....