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

我们默认都统一是采用 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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值