我们默认都统一是采用 offsetWidth 或者 offsetHeight 取值了,但我们知道关于这2个尺寸的算法是这样的:
offsetWidth = border-left-width + padding-left + width + padding-right + border-right-width;
offsetHeight = border-top-width + padding-top + height + padding-bottom + border-bottom-width;
不再考虑 box-sizing 的情况下,也就差不多了。但是关于尺寸的接口不是还有,innerWidth、innerHeight、outerWidth、outerHeight,这些类似的处理吗?当然虽然都是获取尺寸还是有区别的。
innerWidth、innerHeight
用于获得匹配集合中第一个元素的当前计算的内部宽高(包括padding,但不包括border),或 设置每一个匹配元素的内部宽高。
outerWidth、outerHeight
获取元素集合中第一个元素的当前计算宽高度值,包括padding,border和选择性的margin。
针对这些情况,jQuery不得不给出一个方法用来去掉对应的值,这个是对应的augmentWidthOrHeight方法。
我们具体看看怎么计算的:
innerWidth = ele.offsetWidth –ele .borderRightWidth –ele .borderLeftWidth
innerHeight = ele.offseHeight –ele. borderTopHeight –ele .borderBottomHeight
outerWidth如果不传递参数,那么算法就跟offsetWidth一样,如果传递outerWidth(true)就需要加上margin。
outerWidth(true) = ele.offsetWidth + ele. marginLeft + ele. marginRight
outerHeigth(true) = ele.offsetHeigth + ele.marginTop + ele. marginBottom
关于jQuery6个尺寸方法的具体实现,我们参考右边的代码。
<!doctype html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<title>jQuery.width</title>
<style type="text/css">
div{
width: 3000px;
height: 100px;
border: 5px solid #ccc;
}
</style>
</head>
<body>
<div id="aaron" style="background:red;border:20px solid #ccc;">尺寸算法</div>
<button id="test1">Width</button>
<button id="test2">Height</button>
<button id="test3">innerWidth</button>
<button id="test4">innerHeight</button>
<button id="test5">outerWidth(true)</button>
<button id="test6">outerHeight(true)</button>
<script type="text/javascript">
var cssExpand = ["Top", "Right", "Bottom", "Left"];
//例如: augmentWidthOrHeight(elem, 'width', "padding", true, styles) innerWidth
function augmentWidthOrHeight(elem, name, extra, isBorderBox, styles) { //extra为padding或border
var i = extra === (isBorderBox ? "border" : "content") ?
// If we already have the right measurement, avoid augmentation
4 :
// Otherwise initialize for horizontal or vertical properties
name === "width" ? 1 : 0,
val = 0;
for (; i < 4; i += 2) {
// both box models exclude margin, so add it if we want it
// 如果引入了margin
// outerWidth(true)
// outerHeigth(true)
// marginRight
// marginLeft
// marginTop
// marginBottom
if (extra === "margin") {
val += jQuery.css(elem, extra + cssExpand[i], true, styles);
}
if (isBorderBox) {
// border-box includes padding, so remove it if we want content
//paddingRight
//paddingLeft
if (extra === "content") {
val -= jQuery.css(elem, "padding" + cssExpand[i], true, styles);
}
// at this point, extra isn't border nor margin, so remove border
// 减去2边的宽度
//borderRightWidth
//borderLeftWidth
//borderTopHeight
//borderBottomHeight
if (extra !== "margin") {
val -= jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
}
} else {
// at this point, extra isn't content, so add padding
val += jQuery.css(elem, "padding" + cssExpand[i], true, styles);
// at this point, extra isn't content nor padding, so add border
if (extra !== "padding") {
val += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
}
}
}
return val;
}
//获取最终属性
//https://github.com/jquery/jquery/pull/524
var getStyles = function(elem) {
return elem.ownerDocument.defaultView.getComputedStyle(elem, null);
};
var elem = document.getElementById('aaron');
$('#test1').click(function() {
alert( elem.offsetWidth)
})
$('#test2').click(function() {
alert(elem.offsetHeight)
})
$('#test3').click(function() { //innerWidth
var val = elem.offsetWidth;
var styles = getStyles(elem)
alert(val + augmentWidthOrHeight(elem, 'width', "padding", true, styles))
})
$('#test4').click(function() { //innerHeight
var val = elem.offsetHeight;
var styles = getStyles(elem)
alert(val + augmentWidthOrHeight(elem, 'height', "padding", true, styles))
})
$('#test5').click(function(){ //outerWidth(true)
var val = elem.offsetWidth;
var styles = getStyles(elem)
alert(val + augmentWidthOrHeight(elem, 'width', "border", true, styles))
})
$('#test6').click(function(){ //
var val = elem.offsetHeight;
var styles = getStyles(elem)
alert(val + augmentWidthOrHeight(elem, 'height', "border", true, styles))
})
</script>
</body>
</html>