jquery源码解析(第3章元素之偏移算法)

来源:互联网 发布:如何用信用卡支付淘宝 编辑:程序博客网 时间:2024/06/03 18:50

我们默认都统一是采用 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 .borderLeftWidthinnerHeight = ele.offseHeight –ele. borderTopHeight –ele .borderBottomHeight

outerWidth如果不传递参数,那么算法就跟offsetWidth一样,如果传递outerWidth(true)就需要加上margin。

outerWidth(true) = ele.offsetWidth + ele. marginLeft + ele. marginRightouterHeigth(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>