[转帖]Mootools源码分析-18 -- Element-5

原帖地址:http://space.flash8.net/space/?uid-18713-action-viewspace-itemid-403396

原作者:我佛山人

 

//Element的styles的setter,setStyles的快捷方式
Element.Properties.styles = {set: function(styles)    {
    
this.setStyles(styles);
}};

//Element的透明度控制在浏览器间差异较大,所以单独处理
Element.Properties.opacity = {
    set: 
function(opacity, novisibility)    {
        
//如果没有指定不控制visibility样式(即仅当novisibility参数为true时不处理)
        if (!novisibility)    {
            
//所以要控制隐藏与显示,可以用this.set('opacity', 1)和this.set('opacity', 0)来控制
            if (opacity == 0)    {
                
//透明度为0时直接隐藏
                if (this.style.visibility != 'hidden')    this.style.visibility = 'hidden';
            }    
else    {
                
//透明度为1时直接显示
                if (this.style.visibility != 'visible')    this.style.visibility = 'visible';
            }
        }
        
//修正ie hasLayout的bug
        if (!this.currentStyle || !this.currentStyle.hasLayout)    this.style.zoom = 1;
        
//ie的透明度控制用滤镜,注意两种opacity值的区别
        if (Browser.Engine.trident)    this.style.filter = (opacity == 1? '' : 'alpha(opacity=' + opacity * 100 + ')';
        
//非ie直接用opacity样式属性
        this.style.opacity = opacity;
        
//存到临时对象,以避免读取时再次进行兼容性判断和操作
        this.store('opacity', opacity);
    },
    
//直接取临时对象数据,省却兼容性问题
    get: function()    {
        
return this.retrieve('opacity'1);
    }
};

Element.implement({
    
//设置透明度的快捷方式
    setOpacity: function(value)    {
        
return this.set('opacity', value, true);
    },
    
//获取透明度
    getOpacity: function()    {
        
return this.get('opacity');
    },
    
//样式设置
    setStyle: function(property, value)    {
        
//两个特殊属性
        switch (property)    {
            
case 'opacity'return this.set('opacity', parseFloat(value));
            
case 'float': property = (Browser.Engine.trident) ? 'styleFloat' : 'cssFloat';
        }
        
/*
        转成骆驼表示,所以其实这里的样式属性同时支持两种写法,如
        setStyle('borderTopWith', 1) 和 setStyle('border-top-with', 1)
        
*/
        property 
= property.camelCase();
        
if ($type(value) != 'string')    {
            
var map = (Element.Styles.get(property) || '@').split(' ');
            
//处理多属性简写时的赋值
            value = $splat(value).map(function(val, i)    {
                
if (!map[i]) return '';
                
return ($type(val) == 'number'? map[i].replace('@', Math.round(val)) : val;
            }).join(
' ');
        }    
else if (value == String(Number(value)))    {
            value 
= Math.round(value);
        }
        
this.style[property] = value;
        
return this;
    },

    
//获取样式值
    getStyle: function(property)    {
        
//还是那两个特殊属性
        switch (property)    {
            
case 'opacity'return this.get('opacity');
            
case 'float': property = (Browser.Engine.trident) ? 'styleFloat' : 'cssFloat';
        }
        
//还是支持两种写法
        property = property.camelCase();
        
var result = this.style[property];
        
//如果取不到值(通常是因为是简写的属性或者属性是在css中指定)
        if (!$chk(result))    {
            result 
= [];
            
//将简写属性还原,逐个取值
            for (var style in Element.ShortStyles)    {
                
if (property != style)    continue;
                
for (var s in Element.ShortStyles[style])    result.push(this.getStyle(s));
                
return result.join(' ');
            }
            
//另一种可能,样式是在<style>中指定或者外部css文件指定,这时需要获取运行时的样式值
            result = this.getComputedStyle(property);
        }
        
if (result)    {
            
//颜色处理,将RGB表示转成HEX表示
            result = String(result);
            
var color = result.match(/rgba?\([\d\s,]+\)/);
            
if (color)    result = result.replace(color[0], color[0].rgbToHex());
        }
        
//在Opera和IE下,获取width和height的处理
        if (Browser.Engine.presto || (Browser.Engine.trident && !$chk(parseInt(result))))    {
            
//IE和Opera的width不会计算边框厚度,而遵循w3c标准的Fx会
            if (property.test(/^(height|width)$/))    {
                
var values = (property == 'width'? ['left''right'] : ['top''bottom'], size = 0;
                values.each(
function(value)    {
                    size 
+= this.getStyle('border-' + value + '-width').toInt() + this.getStyle('padding-' + value).toInt();
                }, 
this);
                
//用offsetWidth/offsetHeight减相应方向的边框厚度即为所求
                return this['offset' + property.capitalize()] - size + 'px';
            }
            
if (Browser.Engine.presto && String(result).test('px'))    return result;
            
if (property.test(/(border(.+)Width|margin|padding)/))    return '0px';
        }
        
return result;
    },

    
//批量设置样式
    setStyles: function(styles)    {
        
for (var style in styles)    this.setStyle(style, styles[style]);
        
return this;
    },

//批量获取样式
    getStyles: function()    {
        
var result = {};
        Array.each(arguments, 
function(key)    {
            result[key] 
= this.getStyle(key);
        }, 
this);
        
return result;
    }
});

//一些特殊的样式,只是待加工的材料
Element.Styles = new Hash({
    left: 
'@px', top: '@px', bottom: '@px', right: '@px',
    width: 
'@px', height: '@px', maxWidth: '@px', maxHeight: '@px', minWidth: '@px', minHeight: '@px',
    backgroundColor: 
'rgb(@, @, @)', backgroundPosition: '@px @px', color: 'rgb(@, @, @)',
    fontSize: 
'@px', letterSpacing: '@px', lineHeight: '@px', clip: 'rect(@px @px @px @px)',
    margin: 
'@px @px @px @px', padding: '@px @px @px @px', border: '@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)',
    borderWidth: 
'@px @px @px @px', borderStyle: '@ @ @ @', borderColor: 'rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)',
    zIndex: 
'@''zoom''@', fontWeight: '@', textIndent: '@px', opacity: '@'
});

//一些缮写的样式,只是待加工的材料
Element.ShortStyles = {margin: {}, padding: {}, border: {}, borderWidth: {}, borderStyle: {}, borderColor: {}};

//对Element.Styles和Element.ShortStyles的再加工
['Top''Right''Bottom''Left'].each(function(direction)    {
    
var Short = Element.ShortStyles;
    
var All = Element.Styles;
    
//构造marginTop,paddingTop之类的属性
    ['margin''padding'].each(function(style)    {
        
var sd = style + direction;
        Short[style][sd] 
= All[sd] = '@px';
    });
    
//构造borderTopWith之类的属性
    var bd = 'border' + direction;
    Short.border[bd] 
= All[bd] = '@px @ rgb(@, @, @)';
    
var bdw = bd + 'Width', bds = bd + 'Style', bdc = bd + 'Color';
    Short[bd] 
= {};
    Short.borderWidth[bdw] 
= Short[bd][bdw] = All[bdw] = '@px';
    Short.borderStyle[bds] 
= Short[bd][bds] = All[bds] = '@';
    Short.borderColor[bdc] 
= Short[bd][bdc] = All[bdc] = 'rgb(@, @, @)';
});

 

posted @ 2009-11-06 11:00  webgis松鼠  阅读(249)  评论(0编辑  收藏  举报