在做動畫時,我們需要對元素的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]; }