javascript 精确获取样式属性(上)(3)


var getStyle = function (el, style){
if(!+"\v1"){
if(style == "opacity"){
return getIEOpacity(el)
}
var value = el.currentStyle[memorize(style)];
if (/^(height|width)$/.test(style)){
var values = (style == 'width') ? ['left', 'right'] : ['top', 'bottom'], size = 0;
if(isQuirk){
return el[camelize("offset-"+style)]
}else{
var client = parseFloat(el[camelize("client-"+style)]),
paddingA = parseFloat(getStyle(el, "padding-"+ values[0])),
paddingB = parseFloat(getStyle(el, "padding-"+ values[1]));
return (client - paddingA - paddingB)+"px";
}
}
if(!/^\d+px$/.test(value)){
//转换可度量的值
if(/(em|pt|mm|cm|pc|in|ex|rem|vw|vh|vm|ch|gr)$/.test(value)){
return convertPixelValue(el,value);
}
//转换百分比
if(/%/.test(value)){
return parseFloat(getStyle(el.parentNode,"width")) * parseFloat(value) /100 + "px"
}
}
return value;//如 0px
}else{
if(style == "float"){
style = propFloat;
}
return document.defaultView.getComputedStyle(el, null).getPropertyValue(style)
}
}


说多无谓,我们测试一下吧。
<div id ="text">父元素
<div>子元素</div>
</div>
window.onload = function(){
alert(getStyle(_("text"),"width"))
alert(getStyle(_("text2"),'width'))
alert(getStyle(_("text2"),'padding-left'))
};


[Ctrl+A 全选 注:引入外部Js需再刷新一下页面才能执行]


发现在IE取得值太精确了,比火狐还准确,不过我也不打算在程序内部设置取精度的运算,因为我不确定现实中究竟会向上遍历多少次。在某一父元素的padding与width取精度,很可能会严重影响其最终值的精度。基本上,width与height与padding的取值就到此为止,我们再来看盒子模型的两个东西:margin与border。
margin的auto通常为0px,但在IE6下,当我们将其父元素的text-align设为center,它不但把文本居中,连块级元素本身也忧患中了,这是IE6居中布局的基石。很难说这是BUG,就像IE5的怪癖模式的盒子模型那样,很符合人通常的思维习惯,但是较难实现,加之W3C是偏袒被微软阴死的网景,于是网景的盒子模型成为标准了。IE6庞大的用户基础不容忽视,我们不能随便给0px了事。我也说了,auto有个对称性,因此好办,我们求出其父元素的width然后减于其offsetWidth再除以2就行了。因为offsetWidth是针对于offsertParent的,因此我们用时临时把其父元素的position设为relative,让子元素来得offsetWidth后,再将父元素的position还原。

复制代码 代码如下:


//转换margin的auto
if(/^(margin).+/.test(style) && value == "auto"){
var father = el.parentNode;
if(/MSIE 6/.test(navigator.userAgent) && getStyle(father,"text-align") == "center"){
var fatherWidth = parseFloat(getStyle(father,"width")),
_temp = getStyle(father,"position");
father.runtimeStyle.postion = "relative";
var offsetWidth = el.offsetWidth;
father.runtimeStyle.postion = _temp;
return (fatherWidth - offsetWidth)/2 + "px";
}
return "0px";
}


borderWidth的默认值为medium,即使它为0px,但如果我们显式地设置其宽为medium呢?!它就不为0px了。这个比较恶心,我们需要判定这值是我们自己加上的还是浏览器的默认值。不过我们发现如果是默认的,其border-XX-style为none。另,除了medium外,还存在两个模糊值thin与thick。它们在浏览器的精确值见下表:
IE8 ,firefox等标准浏览器 IE4-7
thin   1px   2px  
medium   3px   4px  
thick   5px   6px  

复制代码 代码如下:


//转换border的thin medium thick
if(/^(border).+(width)$/.test(style)){
var s = style.replace("width","style"),
b = {
thin:["1px","2px"],
medium:["3px","4px"],
thick:["5px","6px"]
};
if(value == "medium" && getStyle(el,s) == "none"){
return "0px";
}
return !!window.XDomainRequest ? b[value][0] : b[value][1];
}


再看top,left,right与bottom,想不到firefox,safari都会偷懒,会返回auto,只有opera老老实实地返回精确值。解决办法也很简单,因为微软一个好用的函数已被所有浏览器支持了。

复制代码 代码如下:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wdpgxy.html