3-6 偏移算法
本节编程练习不计算学习进度,请电脑登录imooc.com操作

偏移算法

我们默认都统一是采用 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个尺寸方法的具体实现,我们参考右边的代码。

 

任务

  1. <!doctype html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
  5. <script src="http://code.jquery.com/jquery-latest.js"></script>
  6. <title>jQuery.width</title>
  7. <style type="text/css">
  8. div{
  9. width: 3000px;
  10. height: 100px;
  11. border: 5px solid #ccc;
  12. }
  13. </style>
  14. </head>
  15. <body>
  16.  
  17. <div id="aaron" style="background:red;border:20px solid #ccc;">尺寸算法</div>
  18.  
  19. <button id="test1">Width</button>
  20. <button id="test2">Height</button>
  21. <button id="test3">innerWidth</button>
  22. <button id="test4">innerHeight</button>
  23. <button id="test5">outerWidth(true)</button>
  24. <button id="test6">outerHeight(true)</button>
  25.  
  26. <script type="text/javascript">
  27.  
  28.  
  29. var cssExpand = ["Top", "Right", "Bottom", "Left"];
  30.  
  31. function augmentWidthOrHeight(elem, name, extra, isBorderBox, styles) {
  32. var i = extra === (isBorderBox ? "border" : "content") ?
  33. // If we already have the right measurement, avoid augmentation
  34. 4 :
  35. // Otherwise initialize for horizontal or vertical properties
  36. name === "width" ? 1 : 0,
  37. val = 0;
  38.  
  39. for (; i < 4; i += 2) {
  40. // both box models exclude margin, so add it if we want it
  41. // 如果引入了margin
  42. // outerWidth(true)
  43. // outerHeigth(true)
  44. // marginRight
  45. // marginLeft
  46. // marginTop
  47. // marginBottom
  48. if (extra === "margin") {
  49. val += jQuery.css(elem, extra + cssExpand[i], true, styles);
  50. }
  51.  
  52. if (isBorderBox) {
  53. // border-box includes padding, so remove it if we want content
  54. //paddingRight
  55. //paddingLeft
  56. if (extra === "content") {
  57. val -= jQuery.css(elem, "padding" + cssExpand[i], true, styles);
  58. }
  59.  
  60. // at this point, extra isn't border nor margin, so remove border
  61. // 减去2边的宽度
  62. //borderRightWidth
  63. //borderLeftWidth
  64. //borderTopHeight
  65. //borderBottomHeight
  66. if (extra !== "margin") {
  67. val -= jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
  68. }
  69. } else {
  70. // at this point, extra isn't content, so add padding
  71. val += jQuery.css(elem, "padding" + cssExpand[i], true, styles);
  72.  
  73. // at this point, extra isn't content nor padding, so add border
  74. if (extra !== "padding") {
  75. val += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
  76. }
  77. }
  78. }
  79. return val;
  80. }
  81. //获取最终属性
  82. //https://github.com/jquery/jquery/pull/524
  83. var getStyles = function(elem) {
  84. return elem.ownerDocument.defaultView.getComputedStyle(elem, null);
  85. };
  86. var elem = document.getElementById('aaron');
  87. $('#test1').click(function() {
  88. alert( elem.offsetWidth)
  89. })
  90. $('#test2').click(function() {
  91. alert(elem.offsetHeight)
  92. })
  93. $('#test3').click(function() {
  94. var val = elem.offsetWidth;
  95. var styles = getStyles(elem)
  96. alert(val + augmentWidthOrHeight(elem, 'width', "padding", true, styles))
  97. })
  98. $('#test4').click(function() {
  99. var val = elem.offsetHeight;
  100. var styles = getStyles(elem)
  101. alert(val + augmentWidthOrHeight(elem, 'height', "padding", true, styles))
  102. })
  103. $('#test5').click(function(){
  104. var val = elem.offsetWidth;
  105. var styles = getStyles(elem)
  106. alert(val + augmentWidthOrHeight(elem, 'width', "border", true, styles))
  107. })
  108. $('#test6').click(function(){
  109. var val = elem.offsetHeight;
  110. var styles = getStyles(elem)
  111. alert(val + augmentWidthOrHeight(elem, 'height', "border", true, styles))
  112. })
  113. </script>
  114. </body>
  115. </html>
下一节