在做动画时,我们需要对元素的display进行处理,如内联元素要设置其display:inline-block,才能进行缩放变化。
首先我们要确定哪些元素是经常被人们用来做动画的,如"div","span",而且它们的默认display也显然易见,不需要检测就知。像jQuery的defaultDisplay就不行,只要元素的nodeName不在elemdisplay之列,就要创建一个临时iframe来测量,真是够呛。
因此我的elemdisplay 应该预填一些常用值进去。如,下面这些元素的display肯定为inline。
var cacheDisplay = dom.oneObject("a,abbr,b,span,strong,em,font,i,img,kbd","inline");
如下元素的display也肯定为block:
var blocks = dom.oneObject("div,h1,h2,h3,h4,h5,h6,section,p","block"); dom.mix(cacheDisplay ,blocks);
像ul,li,table,td,th等都有其特殊的display默认值,随着浏览器的不同,版本的不同,出入很大,这时才像jQuery那样创建一个iframe去取。
为了最大限度地制用iframe,我搞了一个callCasual方法。
var casual,casualDoc;//by 司徒正美 function callCasual(parent,callback){ if ( !casual ) { casual = DOC.createElement( "iframe" ); casual.frameBorder = casual.width = casual.height = 0; } parent.appendChild(casual); if ( !casualDoc || !casual.createElement ) { casualDoc = ( casual.contentWindow || casual.contentDocument ).document; iframeDoc.write( ( DOC.compatMode === "CSS1Compat" ? "<!doctype html>" : "" ) + "<html><body>" ); casualDoc.close(); } callback(casualDoc); parent.removeChild(casual); }
有了callCasual,我们就可以开始计算此元素的display值了。parseDisplay的逻辑很简单,如果能从当前文档中取得最好,否则就从一个干净的重复利用的iframe文档中取得目标值。
var cacheDisplay = dom.oneObject("a,abbr,b,span,strong,em,font,i,img,kbd","inline"); var blocks = dom.oneObject("div,h1,h2,h3,h4,h5,h6,section,p","block"); dom.mix(cacheDisplay ,blocks); function parseDisplay( nodeName ) { if ( !cacheDisplay[ nodeName ] ) { var body = DOC.body, elem = DOC.createElement(nodeName);//DOC为当前文档 body.appendChild(elem) var display = dom.css(elem, "display" ); body.removeChild(elem); // 先尝试连结到当前DOM树去取,但如果此元素的默认样式被污染了,就使用iframe去取 if ( display === "none" || display === "" ) { callCasual(body,function(doc){ elem = doc.createElement( nodeName ); doc.body.appendChild( elem ); display = dom.css( elem, "display" ); }); } cacheDisplay[ nodeName ] = display; } return cacheDisplay[ nodeName ]; }
顺便提一下,在颜色渐变的动画时,我们要用rgb(aa,bb,cc)这样的值,IE默认是返回颜色名与十六进制的颜色值,我们可以使用parseColor进行转换。
function parseColor(color) { var value; callCasual(DOC.documentElement,function(doc){ var range = doc.body.createTextRange(); doc.body.style.color = color; value = range.queryCommandValue("ForeColor"); }); return [value & 0xff, (value & 0xff00) >> 8, (value & 0xff0000) >> 16]; }