Ruby's Louvre

每天学习一点点算法

导航

取得元素节点的默认display值

在做动画时,我们需要对元素的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];
        }

posted on 2011-09-16 14:50  司徒正美  阅读(3064)  评论(3编辑  收藏  举报