我们默认都统一是采用 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如果不传递参数,那么算法就跟innerWidth一样,如果传递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"]; function augmentWidthOrHeight(elem, name, extra, isBorderBox, styles) { 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() { var val = elem.offsetWidth; var styles = getStyles(elem) alert(val + augmentWidthOrHeight(elem, 'width', "padding", true, styles)) }) $('#test4').click(function() { var val = elem.offsetHeight; var styles = getStyles(elem) alert(val + augmentWidthOrHeight(elem, 'height', "padding", true, styles)) }) $('#test5').click(function(){ 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>