w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr"); 0 ? 0 : w;
Prototype의 구현보다 더 나빠서 다른 부분에서 수정할 수 없는 매우 위험한 접근 방식이므로 UI의 크기가 너무 큽니다. 또한 측면에서 뛰어난 JQuery 구현 방법을 강조합니다. 그러나 JQuery의 구현도 상당히 복잡합니다. 이 요소의 정확한 값을 얻을 수 없으면 상위 요소부터 시작해야 합니다. 이 순회에는 많은 비용이 소요됩니다. 또한 Dean Edwards로부터 훌륭한 해킹을 빌렸습니다.
코드는 다음과 같습니다.
if (/^(height|width)$/.test(style)){
var 값 = (style == 'width') ? ['left', 'right'] : ['top' , 'bottom'], size = 0;
if(isQuirk){
return el[camelize("offset-" style)]
}else{
var client = parseFloat(el[camelize ("client-" 스타일)]),
paddingA = parseFloat(getStyle(el, "padding-" 값[0])),
paddingB = parseFloat(getStyle(el, "padding) -" 값[1 ]));
return (클라이언트 - 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 parsFloat(getStyle(el.parentNode, "너비" )) * parsFloat(값) /100 "px"
}
}
반환 값;//예: 0px
}else{
if(style == "float "){
style = propFloat;
}
return document.defaultView.getCompulatedStyle(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 |
//테두리를 얇은 중간 두께로 변환
(/^(테두리).(너비)$/.test(스타일)){
var s = style.replace("너비","스타일"),
b = {
thin:[ "1px" ,"2px"],
중간:["3px","4px"],
두꺼운:["5px","6px"]
}
if(값 = = "medium" && getStyle(el,s) == "none"){
return "0px";
return !!window.XDomainRequest ? b[ value][ 1]
}
위, 왼쪽, 오른쪽, 아래를 보니 파이어폭스와 사파리가 게으르고 자동만 반환할 줄은 몰랐습니다. 정직하게 평가하세요. Microsoft의 유용한 기능이 이미 모든 브라우저에서 지원되기 때문에 솔루션도 매우 간단합니다.
//위로 변환|왼쪽|오른쪽| 하단의 자동
if(/(top|left|right|bottom)/.test(style) && value == "auto"){
return el.getBoundingClientRect()[style]
}
글이 벌써 너무 길어졌네요. 나머지 부분은 다음에 이야기하겠습니다.