[TOC]

获取标签的宽高及例子

1. 常用的获取宽高的属性

// 1. 获取屏幕的高度和宽度(屏幕分辨率):
window.screen.height 		// 1440
window.screen.width			// 2560

// 3. 获取浏览器可视区域宽高
window.innerHeight			// 899 等于css中 vw
window.innerWidth			// 1598

// 2. 获取浏览器相对于屏幕距离
window.screenTop; 			//  浏览器上面距离屏幕顶部距离
window.screenLeft;			// 浏览器左边距离屏幕左边的距离

// 2. 获取屏幕工作区域的高度和宽度(去掉状态栏):
window.screen.availHeight  	// 1363
window.screen.availWidth 	// 2560

// 3. 网页全文的高度和宽度:
document.body.scrollHeight	// 9969
document.body.scrollWidth 	// 1124

// 4. 滚动条卷上去的高度和向右卷的宽度:body和documentElement有一个是有效的
document.body.scrollTop  	// 0 : 如果body没有滚动条则为0
document.body.scrollLeft 
document.documentElement.scrollTop	
document.documentElement.scrollLeft

// 5. 网页可见区域的高度和宽度(不加边线):
document.body.clientHeight  // 9969
document.body.clientWidth 	// 845
document.documentElement.clientHeight
document.documentElement.lientWidth

// 6. 网页可见区域的高度和宽度(加边线):
document.body.offsetHeight 	// 9969
document.body.offsetWidth	// 845

2. 关于offset的5个属性

2.1 offsetWidth与offsetHeight

元素的offsetWidth:元素的IE盒模型的宽度

元素的offsetHeight:元素的IE盒模型的高度

2.3 offsetLeft与offsetTop

HTMLElement.offsetLeft:只读属性,返回当前元素左上角相对于  HTMLElement.offsetParent 节点的左边界偏移的像素值

HTMLElement.offsetTop 只读属性,它返回当前元素相对于其 offsetParent 元素的顶部的距离。

2.4 offsetParent

  1. 如果当前元素的父级元素没有进行CSS定位(position为absolute或relative),则 offsetParent 为最近的 tabletable cell 或根元素(标准模式下为 html;quirks 模式下为 body)。
  2. 如果当前元素的父级元素中有CSS定位(position为absolute或relative),offsetParent取最近的那个父级元素。
  3. offsetParent 很有用,因为 offsetTop 和 offsetLeft 都是相对于其内边距边界的。

3. 关于宽高的实际应用

3.1 判断滚动条到底的条件

scrollTop + clientHeight == scrollHeight

// 已经滚动了多少距离
function getScrollTop(){
  var scrollTop = 0, bodyScrollTop = 0, documentScrollTop = 0;
  if(document.body){ bodyScrollTop = document.body.scrollTop; }
  if(document.documentElement){
    documentScrollTop = document.documentElement.scrollTop;
  }
  scrollTop = (bodyScrollTop - documentScrollTop > 0) ? bodyScrollTop : documentScrollTop;
  return scrollTop;
}
//文档的总高度
function getScrollHeight(){
  var scrollHeight = 0, bodyScrollHeight = 0, documentScrollHeight = 0;
  if(document.body){ bodyScrollHeight = document.body.scrollHeight; }
  if(document.documentElement){
    documentScrollHeight = document.documentElement.scrollHeight;
  }
  scrollHeight = (bodyScrollHeight - documentScrollHeight > 0) ? bodyScrollHeight : documentScrollHeight;
  return scrollHeight;
}
// 获取浏览器可见部分的高度
function getWindowHeight(){
  var windowHeight = 0;
  if(document.compatMode == "CSS1Compat"){
    windowHeight = document.documentElement.clientHeight;
  }else{ windowHeight = document.body.clientHeight; }
  return windowHeight;
}
// 绑定滚动事件
window.onscroll = function(){
  if(getScrollTop() + getWindowHeight() == getScrollHeight()){
    console.log("已经到最底部了!!");
  }
};

//jquery 实现
$(window).scroll(function(){
  var scrollTop = $(this).scrollTop();
  var scrollHeight = $(document).height();
  var windowHeight = $(this).height();
  if(scrollTop + windowHeight == scrollHeight){
    console.log("已经到最底部了!");
  }
});

3.2 JS判断滚动条离开顶部、到达指定位置、滚动到达底部:

<style>
    body { margin: 0; }
    .one { border: 1px solid; height: 300px; width: 300px;
      overflow: scroll; position: relative;
    }
    p { margin: 30px 0; border: 1px solid red; }
  </style>
  <p>123</p><p>9999</p>
  <div class="one">
    <p>1</p><p>2</p><p>3</p> <p>4</p><p>5</p><p>6</p>
    <p>7</p><p>8</p><p>9</p> <p>10</p><p>11</p><p>12</p>
    <p>13</p><p class=f>ffffffffffffffffffffffffff</p><p>14</p>
    <p>15</p><p>16</p><p>17</p> <p>18</p><p>19</p><p>20</p>
  </div>
  <script>
      var one = document.querySelector(".one");
      var f = document.querySelector(".f");
      // one.scrollTop = f.offsetTop;	设置 直接滚动到指定位置
      var leave = false;
      var fflag = false;	// 判断是否已经出发了条件
      one.onscroll = function() {
          console.log(f.offsetTop)
          if (this.scrollTop > 0 && leave === false){
              console.log('离开顶部了'); leave = true;
          }
          if (this.scrollTop === 0 && leave === true) {
              console.log('在顶部了'); leave = false;
          }
          if (this.scrollTop + this.clientHeight === this.scrollHeight) {
              console.log('到底部了');
          }
          if (this.scrollTop > f.offsetTop && !fflag) {
            console.log('到达指定位置了');
            fflag = true; // 过了指定位置后,关闭指定提示, 
          }
          // 小于指定位置后,从新打开指定位置
          if (this.scrollTop < f.offsetTop  && fflag) {
            fflag = false;
          }
      }
      console.log(f.offsetTop)
  </script>

3.3 获取浏览器窗口宽度

//浏览器窗口的宽度
  getClientWidth(){
    var clientWidth = 0, bodyClientWidth = 0, documentClientWidth = 0;
    if(document.body){ bodyClientWidth = document.body.clientWidth; }
    if(document.documentElement){
      documentClientWidth = document.documentElement.clientWidth;
    }
    clientWidth = (bodyClientWidth - documentClientWidth > 0) ? bodyClientWidth : documentClientWidth;
    return clientWidth;
  }

4. document.compatMode对获取浏览器窗口大小的影响

document.compatMode MDN

怪异模式和标准模式 MDN

document.compatMode用来判断当前浏览器采用的渲染方式,分为怪异模式(Quirks Mode)和标准模式(Standards mode)。它有两个值:

BackCompat: 标准兼容模式关闭,Quirks Mode,即使用了IE盒模型:width = border + padding + content

CSS1Compat:标准兼容模式开启,Standards Mode,即使用了标准盒模型: width: content

在很久以前的网络上,页面通常有两种版本:为网景(Netscape)的 Navigator 准备的版本,以及为微软(Microsoft)的 Internet Explorer 准备的版本。当 W3C 创立网络标准后,为了不破坏当时既有的网站,浏览器不能直接弃用这些标准。因此,浏览器采用了两种模式,用以把能符合新规范的网站和老旧网站区分开。

目前浏览器的排版引擎使用三种模式:怪异模式(Quirks mode)、接近标准模式(Almost standards mode)、以及标准模式(Standards mode)。在怪异模式下,排版会模拟 Navigator 4 与 Internet Explorer 5 的非标准行为。为了支持在网络标准被广泛采用前,就已经建好的网站,这么做是必要的。在标准模式下,行为即(但愿如此)由 HTML 与 CSS 的规范描述的行为。在接近标准模式下,只有少数的怪异行为被实现。

浏览器如何决定使用哪个模式?

HTML 文件来说,浏览器使用文件开头的 DOCTYPE 来决定用怪异模式处理或标准模式处理。为了确保你的页面使用标准模式,请确认你的页面如同本范例一样拥有 DOCTYPE:

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
  </body>
</html>

4.1 BackCompat: 浏览器高度使用body的值

**BackCompat:**标准兼容模式关闭,当document.compatMode等于BackCompat时,浏览器客户区宽度为document.body.clientWidth;

4.2 CSS1Compat:浏览器高度使用documentElement的值

**CSS1Compat:**标准兼容模式开启,当document.compatMode等于CSS1Compat时浏览器客户区宽度为document.documentElement.clientWidth;

4.3 DOCTYPE 会影响document.compatMode

当文档有了标准声明时, document.compatMode 的值就等于 "CSS1compat", 因此, 我们可以根据 document.compatMode 的值来判断文档是否加了标准声明

// HTML文件头部没有 <!DOCTYPE html>
document.compatMode	// BackCompat
// HTML文件头部有 <!DOCTYPE html>
document.compatMode	// CSS1Compat

4.4 documentElement和body

body是DOM对象里的body子节点,即 <body> 标签;

documentElement 是整个节点树的根节点root,即<html>标签;

5. 浏览器兼容性问题

5.1 各浏览器下 scrollTop的差异

https://segmentfault.com/a/1190000008065472

IE6/7/8:

可以使用 document.documentElement.scrollTop

IE9及以上: 可以使用window.pageYOffset或者document.documentElement.scrollTop

Safari: safari: window.pageYOffset 与document.body.scrollTop都可以;

Firefox: 火狐等等相对标准些的浏览器就省心多了,直接用window.pageYOffset 或者 document.documentElement.scrollTop

Chrome: 谷歌浏览器只认识document.body.scrollTop; 注:标准浏览器是只认识documentElement.scrollTop的,但chrome虽然我感觉比firefox还标准,但却不认识这个,在有文档声明时,chrome也只认识document.body.scrollTop.

document.body.scrollTop与document.documentElement.scrollTop两者有个特点,就是同时只会有一个值生效。

为了兼容,不管有没有 DTD,可以使用如下代码:

var scrollTop = window.pageYOffset  //用于FF
                || document.documentElement.scrollTop  
                || document.body.scrollTop || 0;

documentElement 和 body 相关说明:

body是DOM对象里的body子节点,即<body>标签;

documentElement 是整个节点树的根节点root,即<html>标签;

6. 一些问题

6.1 document.body.scrollTop总是0的原因

document.body.scrollTop与document.documentElement.scrollTop兼容

JS基础篇-- body.scrollTop与documentElement.scrollTop

当判断页面滚动的时候,使用document.body.scrollTop发现页面滚动时总是返回0,经查找:

页面指定了DTD,即指定了DOCTYPE时,使用document.documentElement。

页面没有DTD,即没指定DOCTYPE时,使用document.body。

IE和Firefox都是如此。

但document.body.scrollTop与document.documentElement.scrollTop同时只会有一个值生效。比如document.body.scrollTop能取到值的时候,document.documentElement.scrollTop就会始终为0;反之亦然。所以,如果要得到网页的真正的scrollTop值,可以这样:

var sTop=document.body.scrollTop+document.documentElement.scrollTop;

也可以使用下面的函数:

function getScrollTop() {
    var scrollTop;
    if (typeof window.pageYOffset != 'undefined'){
        scrollTop = window.pageYOffset; 
    } else if (typeof document.compatMode != 'undefined' &&    document.compatMode != 'BackCompat') {
        scrollTop = document.documentElement.scrollTop;
    } else if (typeof document.body != 'undefined') {
        scrollTop = document.body.scrollTop; 
    }
    return scrollTop;
}
console.log(getScrollTop())

6.2 给body标签设置高度后,显示的效果是一实际高度算的

参考资料

JS如何判断滚动条是否滚到底部

HTMLElement.offsetLeft MDN

HTMLElement.offsetParent MDN

HTML 获取屏幕、浏览器、页面的高度宽度

document.compatMode介绍

获取scrollTop兼容各浏览器的方法,以及body和documentElement是啥?

网址在线测试 JSBIN

一张了解元素宽高的图:

Last Updated: 6/23/2020, 11:36:36 AM