JS 各种宽高的理解

Window和document对象的区别

  • window对象
    1. window对象表示浏览器中打开的窗口
    2. window对象是可以省略的 window.alert(1)
  • document对象
    1. document对象是window对象的一部分, 可以写成window.document.body = document.body
    2. 浏览器的HTML文档成为Document对象
  • window.location和document.location
    1. window.location == document.location //true
    2. 在iframe中 也是全等的

与window相关的高宽

  • window.innerWidth

  • window.innerHeight 去掉console控制台栏 不包括导航栏 菜单栏 地址栏(不包括资源管理器栏)

  • window.outerWidth

  • window.outerHeight 包括导航栏 菜单栏 地址栏(不包括资源管理器栏)

  • window.screen 包含用户屏幕的信息 (支持所有的浏览器 尽量screen是小写)

    • window.screen.height 整个屏幕的高
    • window.screen.width
    • window.screen.availHeight 去掉mac上无线网音量图标 去掉windows下面资源管理器一块
    • window.screen.availWidth
    • window.screenTop 浏览器距离顶部的距离
    • window.screenLeft 浏览器距离最左侧的距离
  • window相关的高宽兼容性表述

    • innerHeight IE9+
    • outerHeight IE9+
  • 对于IE8,7,6,5 代替innerHeight 和 innerWidth

        var w = document.documentElement.clientWidth || document.body.clientWidth;
        var h = document.documentElement.clientHeight || document.body.clientHeight;
    

document相关的宽高

  1. 与client相关的宽高

    • document.body.clientWidth
      • 1)元素可视部分的宽, 即padding+content, 如果没有滚动条,就是元素设定的宽高
      • 2)如果有滚动条,滚动条覆盖元素的宽高, 该属性就是元素本来宽高减去滚动条宽高
    • document.body.clientHeight
    • document.body.clientLeft
      • 返回元素周围边框的厚度border, 如果不指定一个边框或者不定位该元素,其值就是0
      • clientTop = border-top的宽
      • clientLeft = border-left的宽
    • document.body.clientTop
  2. 与offset相关的宽高

    • document.body.offsetWidth

      • 指的是元素的border+padding+content的宽度和高度
      • 该属性和其内部的内容是否超出元素的大小无关, 只和本来设定的border以及width和height有关
      • 假如没有无padding无滚动无border offsetWidth = clientWidth = style.width
      • 假如有padding无滚动有border offsetWidth=style.width+style.aadding2+(borderWidth)2
      • 假如有padding有滚动 offsetWidth = style.width + style.padding2 + borderWidth2 或者
      • offsetWidth = clientWidth + 滚动轴宽度 + border宽度*2
    • document.body.offsetHeight

    • document.body.offsetLeft

      • offsetParent 如果当前元素的父级元素没有进行css定位(position为absolute或者relative), offsetParent为body
      • 如果单钱元素的父级元素中有css定位(position为absolute或者relative),offsetParent取最近的父级元素
      • 兼容性问题
      • 在IE6 7中 offsetLeft = offsetParent的padding-left+(当前元素的margin-left)
      • 在IE8/9/10 chrome中, offsetLeft=(offsetParent的margin-left)+(offsetParent的border宽度)+(offsetParent的padding-left宽度) + (当前元素的margin-left)
      • 在firefox中 offsetLeft=(offsetParent的margin-left)+(当前元素的margin-left)+(offsetParent的padding-left宽度)
    • document.body.offsetTop

  3. 与scroll相关的宽高

    • document.body.scrollWidth document.body.scrollHeight 针对body 的scrollWidth和scrollHeight

      • 给定的宽高小于浏览器窗口的时候, scrollWidth和scrollHeight通常是浏览器窗口的宽高
      • 给定的宽高大于浏览器窗口且内容小于给定的宽高的时候, scrollWidth=给定的宽度+其所有的padding和magin以及border
      • 给定的宽高大于浏览器窗口且内容大于给定的宽高的时候, scrollWidth=内容宽度+其所有的padding,margin,border
    • oDiv.scrollWidth oDiv.scrollHeight 针对某个div的情况

      • 在无滚动轴的情况下, scrollWidth= clientWidth = style.width + style.padding*2
      • 有滚动轴的情况下, scrollWidth = 实际内容的宽度 + padding2, scrollHeight = 实际内容的高度+padding2
    • document.body.scrollLeft document.body.scrollTop

      • 该属性是可读写的, 值得是当元素其中的内容超出其宽高的时候, 元素被卷起的高度和宽度
  4. document, documentElement, body

    • document.documentElement = html
    • document.documentElement.childeNodes[1] = body
    • document.body = body
  5. document宽高兼容问题

    • client 各个浏览器的解析都一样
      • 获取可视区域的宽高的时候, document.documentElement.clientWidth || document.body.clientWidth
    • offset
      • offsetLeft offsetTop有兼容性问题
      • offsetHeight offsetWidth 各个浏览器解析基本一致
    • scroll
      • 在ff下 document.body.scrollHeight 将body当做一个div来处理,这里会有点不同 如果是在div下面是一样的
  6. event对象中五种坐标

    • clientX和clientY
      • 可视区域的, 相对于浏览器(可视区域左上角0,0)的坐标
      • 鼠标相对于浏览器窗口可视区域的X,Y坐标(窗口坐标),可视区域不包括工具栏和滚动条。IE事件和标准事件都定义了这2个属性
    • screenX和screenY
      • 鼠标相对于设备屏幕左上角(0,0)的坐标
    • offsetX和offsetY
      • 鼠标相对于事件源左上角(0,0)的坐标
    • pageX和pageY
      • 鼠标相对于整个网页左上角(0,0)的坐标 (比如滚上去的区域也算在里面)
      • 这2个属性不是标准属性,但得到了广泛支持。IE事件中没有这2个属性。
    • X和Y
      • 本来是IE属性, 相对于CSS动态定位的最内层的包容元素

JS各种宽高的应用

  1. JS可视区域的加载 (div是否滚动到了可视区域之内)
          <style>
          #showDiv {
            width: 500px;
            height: 350px;
            background: dodgerblue;
            margin: 1000px auto 0;
          }
  
          @-webkit-keyframes fadeInLeft {
            0% {
              opacity: 0;
              -webkit-transform: translate3d(-100%, 0, 0);
              transform: translate3d(-100%, 0, 0);
           }
            100% {
              opacity: 1;
              -webkit-transform: none;
              transform: none;
            }
          }
  
          @keyframes fadeInLeft {
            from {
              opacity: 0;
              -webkit-transform: translate3d(-100%, 0, 0);
              transform: translate3d(-100%, 0, 0);
            }
            to {
              opacity: 1;
              -webkit-transform: none;
              transform: none;
            }
          }
  
          .fadeInLeft {
            animation: fadeInLeft 2s ease;
            -webkit-animation: fadeInLeft 2s ease;
          }
          </style>
          <div id="showDiv" class=""></div>
          <script>
          function showDiv() {
            var oDiv = document.getElementById('showDiv');

            // window.innerHeight IE9及以上  表示可视区域的距离
            var clientsHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;

            // getBoundingClientRect  表示当前元素离顶部的距离 (距离浏览器顶部, 不包括卷起的高度)
            var top = oDiv.getBoundingClientRect().top;
            if (top < clientsHeight) {
              oDiv.classList.add("fadeInLeft");
            }
          }
          window.onscroll = function() {
            showDiv();
          };
          </script>
  1. 网页滚动到底部 (可视区域+卷起高度 == 页面高度)
    <style>
        .scrolldiv {
            width: 500px;
            height: 400px;
            margin: 1000px auto 100px auto;
            background: #FF0000;
        }
    </style>
    <div class="scrolldiv" id="showDiv"></div>
    <script>
        // 卷上去的高度 加上  可视区域的高度 ==  网页的高度  表示已经滚动到底部
        function scrollBottomOrTop() {
            var oDiv = document.getElementById('showDiv');

        // window.innerHeight IE9及以上  表示可视区域的距离
        var clientsHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;

        // 卷起的高度
        var scrollTop = document.body.scrollTop

        //整个的高度
        var wholeHeight = document.body.scrollHeight;

        // 可视区域 + 卷上去的高度  == 整个高度的时候
        console.log('clientsHeight:', clientsHeight) //
        console.log('scrollTop:', scrollTop)  //网页卷起的高度  滑动的时候变化
        console.log('wholeHeight:', wholeHeight) // 网页的body区域

        if (clientsHeight + scrollTop >= wholeHeight) {
            alert('滚动到底部了');
            // 通过ajax请求数据
        }

        if (scrollTop == 0) {
            alert('你到了顶部哟');
        }
        }

        window.onscroll = function() {
            scrollBottomOrTop();
        }
    </script>
  1. div滚动到底部加载 头部
          <style>
            .scrolldiv {
                width: 500px;
                height: 400px;
                margin: 10 auto;
                background-color: #FF0000;
                overflow-y: scroll;
                padding: 10px;
            }
          </style>
          <div class="scrolldiv" id="testDiv"> <!-- 撑得足够大-->
           <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
          </div>
          <script>
            var divscroll = document.getElementById('testDiv')
            function divScroll() {
                // 获取div整个部分的高度
                var wholeHeight = divscroll.scrollHeight;
                // 获取div卷起的高度
                var scrollTop = divscroll.scrollTop;
                //获取div的高度  oDiv.style.height 获取的是内联样式的高度  取不到padding
                //var divHeight = divscroll.clientHeight;
                var divHeight = divscroll.offsetHeight;

                if (scrollTop + divHeight >= wholeHeight) {
                    alert("div滚动到了底部")
                }
                if (scrollTop == 0) {
                    alert("div滚动到了头部")
                }
            }

            divscroll.onscroll = function() {
                divScroll();
            }
          </script>
  1. 计算滚动轴的宽度
    • mac 下 滚动轴是不占用宽度的 会消失
    • 但是windows系统下滚动轴是占用一定宽度的\
    • offsetWidth是包含滚动轴的 clientWidth如果文档有滚动轴是要减去滚动轴的
    • scrollWidth = el.offsetWidth - el.clientWidth;
      // 通过offsetWidth - clientWidth计算
      function getScrollBar() {
        var el = document.createElement("p");
        var styles = {
          width: '100px',
          height:'100px',
          overflowY:'scroll'
        };
        var i, scrollBarWidth
        for (i in styles) {
          el.style[i] = styles[i]
        }
        document.body.appendChild(el);
      
        var scrollBarWidth = el.offsetWidth - el.clientWidth;
        el.remove();
        return scrollBarWidth;
        }
        console.log(getScrollBar())
      
    • 添加滚动轴 clientWidth会变
      function getScrollBar() {
        var el = document.createElement("p");
        var styles = {
          width: '100px',
          height:'100px',
        };
        var i, scrollBarWidth
        for (i in styles) {
          el.style[i] = styles[i]
        }
        document.body.appendChild(el);
      
        var clientWidth1 = el.clientWidth; // 没有滚动轴下的宽度
        el.style.overflowY = "scroll"
        var clientWidth2 = el.clientWidth; //添加了滚动轴之后的宽度
      
        var scrollBarWidth = clientWidth1 - clientWidth2;
        el.remove();
        return scrollBarWidth;
      }
      console.log(getScrollBar())
      

jQuery宽高理解

  1. .width() .height()

    • 不包括padding border margin
    • 可读写的 (对于document和window 只能读不能写)
    • 对于普通元素是可以读写的 width(value) width(function() {})
    • width([value])和css("width"[,value])的区别
      • width返回的结果是没有单位的
      • css("width")返回的结果是有单位的
  2. .innerWidth() .innerHeight()

    • 在element的基础上包括了padding 但是不包括border margin
    • 对于document和window是只读的不写的
    • 对于普通元素是可以读写的 innerWidth(value) innerWidth(function() {})
  3. .outerWidth() .outerHeight()

    • outerHeight(true) 是包含border和margin的
    • outerHeight(false) 是只包含border不包含margin
    • 对于window和document只读不写 和width()是相等的 不推荐使用
    • 对于普通元素是可以读写的 outerWidth(value) outerWidth(function() {})
  4. scrollLeft和scrollTop()

    • 和js的是一样的
    • scrollLeft(): 相对于水品滚动条左边的距离, 如果滚动条非常左或者不能滚动, 那么scrollLeft为0 即卷进去的部分为0
    • scrollTop() 相对于纵向滚动条上边的距离, 如果滚动条非常上, 或者元素不能滚动, 那么这个值为0, 即卷上去的部分为0
    <style>
        html, body {
            margin: 10px;
            border: 5px solid red;
            padding: 20px;
        }
    
        .parentDiv {
            width: 800px;
            height: 500px;
            margin: 5px auto;
            background: #FF6600;
            border: 5px dashed green;
            padding: 30px;
            position: relative;
        }
    
        .childrenDiv {
            width: 300px;
            height: 300px;
            margin: 50px auto;
            background: yellow;
            border: 5px solid black;
            padding: 5px;
            box-sizing: border-box;
        }
    </style>
    <div class="parentDiv">
        <div class="childrenDiv"></div>
    </div>
    <script>
        // window是可视区域的高度 随着窗口变化而变化 document是文档的高度是不变化的
        console.log($(window).height())
        console.log($(document).height())
    
        console.log($(window).innerHeight())
        console.log($(document).innerHeight())
    
        console.log($(window).outerHeight())
        console.log($(document).outerHeight())
    
        console.log("-----------------")
        // 普通元素的高度
        console.log($(".childrenDiv").height())   //280 = 300 - border*2 - padding * 2
        console.log($(".childrenDiv").innerHeight())  // 290 = 300 - padding * 2
        console.log($(".childrenDiv").outerHeight(true))  // 300 包括padding+border 但是设置了属性box-sizing:border-box;
        console.log($(".childrenDiv").outerHeight(true))  // 400 = 300 + margin * 2 包括padding+border+margin
    
        // scrollTop  scrollLeft
        $(window).scroll(function() {
            console.log($(this).scrollTop()) //输出滚动轴卷曲的高度
        })
    
        $(".parentDiv").scroll(function() {
            console.log($(this).scrollTop()) //输出滚动轴卷曲的高度
        })
    
        //offset position
    </script>
    
  5. offset() .position()

    • offset(): 相对于document的当前坐标值(相对于body左上角的left和top值)
    • position(): 相对于offsetParent()(最近的一个父级有position属性)的一个偏移坐标值
    <style>
        html, body {
            margin: 10px;
            border: 5px solid red;
            padding: 20px;
        }
    
        .parentDiv {
            width: 800px;
            height: 500px;
            margin: 5px auto;
            background: #FF6600;
            border: 5px dashed green;
            padding: 30px;
            position: relative;
        }
    
        .childrenDiv {
            width: 300px;
            height: 300px;
            margin: 50px auto;
            background: yellow;
            border: 5px solid black;
            padding: 5px;
            position: relative;
            left: 10px;
            top: 30px;
        }
    </style>
    <div class="parentDiv">
        <div class="childrenDiv"></div>
    </div>
    
    <script>
        //offset position
        console.log($(".childrenDiv").offset().top) // 155
        console.log($(".childrenDiv").offset().left) // 582
    
        // position有兼容性问题
        // 如果父元素没有设置position  距离浏览器顶端   看margin的左上角
        console.log($(".childrenDiv").position().top)  // 30 + 30
        console.log($(".childrenDiv").position().left) // 30 + 10
    </script>
    

jQuery宽高理解应用

  1. 可视区域的加载
<style>
  #showDiv {
    width: 500px;
    height: 350px;
    background: dodgerblue;
    margin: 1000px auto 0;
  }
  
  @-webkit-keyframes fadeInLeft {
    0% {
      opacity: 0;
      -webkit-transform: translate3d(-100%, 0, 0);
      transform: translate3d(-100%, 0, 0);
    }
    100% {
      opacity: 1;
      -webkit-transform: none;
      transform: none;
    }
  }
  
  @keyframes fadeInLeft {
    from {
      opacity: 0;
      -webkit-transform: translate3d(-100%, 0, 0);
      transform: translate3d(-100%, 0, 0);
    }
    to {
      opacity: 1;
      -webkit-transform: none;
      transform: none;
    }
  }
  
  .fadeInLeft {
    animation: fadeInLeft 2s ease;
    -webkit-animation: fadeInLeft 2s ease;
  }
  </style>
  <script>
  $(window).scroll(function() {
    // 获取可视区域
    var ks_area = $(window).height();
    //卷起的高度
    var scrollHeight = $(window).scrollTop();
    //div距离顶部的距离
    var divtop = $("#showDiv").offset().top;

    console.log(ks_area)
    console.log(scrollHeight)
    console.log(divtop)

    if (ks_area + scrollHeight >= divtop) {
      $("#showDiv").addClass("fadeInLeft");
    }
  });

  </script>
  1. 滚动到底部加载 顶部
<div style="height:3000px; width: 100%; background-color: dodgerblue"></div>
<script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
 // 可视区域的高度
     var ks_area = $(window).height();
    // 整个文档的高度
     var wholeHeight = $(document).height();
     $(window).scroll(function() {  
       // 卷起的高度
      var scrollTop = $(window).scrollTop();

      if (scrollTop == 0) {
          alert("滚动到了顶部")
      }
      if (scrollTop + ks_area >= wholeHeight) {
           alert("滚动到了底部")
      }
    })
</script>

推荐阅读更多精彩内容