w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr"); 0 ? 0 :
非常に危険なアプローチであり、プロトタイプの実装よりも悪いため、他の部分を修正することはできません。これが、その UI のサイズが非常に大きい理由でもあります。また、側面からの優れた JQuery 実装方法も強調しています。ただし、JQuery の実装も非常に複雑です。この要素の正確な値を取得できない場合、この走査は多大なコストを消費します。また、Dean Edwards から素晴らしいハックを借用しました:
return getIEOpacity(el)
}
var value = el.currentStyle[memorize(style) )];
if (/^(height|width)$/.test(style)){
var 値 = (style == 'width') ['left', 'right'] : ['top' , 'bottom']、サイズ = 0;
if(isQuirk){
return el[camelize("offset-" style)]
}else{
var client = parseFloat(el[camelize ("client-" style)]),
paddingA = parseFloat(getStyle(el, "padding-" value[0])),
paddingB = parseFloat(getStyle(el, "padding -" 値[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"
}
}
戻り値;//0px など
}else{
if(style == "float "){
style = propFloat;
}
return document.defaultView.getComputedStyle(el, null).getPropertyValue(style)
}
}
说多无谓,我们测试一下吧。
window.onload = function(){
alert(getStyle(_("text"),"width"))
alert(getStyle(_("text2"),'width'))
alert(getStyle(_("text2"),'padding-left'))
};
发现在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 |
//境界線を細い中太に変換します
if (/^ (border).(width)$/.test(style)){
var s = style.replace("width","style"),
b = {
thin:[ "1px" ,"2px"],
medium:["3px","4px"],
thick:["5px","6px"]
}; = "medium " && getStyle(el,s) == "none"){
return "0px";
}
return !!window.XDomainRequest b[value][0] : b[ value][ 1];
}
上、左、右、下を見ると、Firefox と safari が遅延して auto を返すとは予想していませんでした。正直に大切にします。 Microsoft の便利な機能がすべてのブラウザですでにサポートされているため、解決策も非常に簡単です。
//top|left|right| を変換します。ボトムの auto
if(/(top|left|right|bottom)/.test(style) && value == "auto"){
return el.getBoundingClientRect()[style]
}
さて、記事が長くなってしまいましたので、続きは次回にお話します。