JavaScript视口宽高、元素位置、滚动高度、尺寸属性

本章将全面学习JavaScript各种位置信息属性和方法。在我参考了大量文章之后,有的文章很全面但是缺乏直观的图片。有的文章有图片,但是描述信息较少。还有的虽然很详细,但总会漏掉一些属性。希望自己能写一篇文章,让自己更全面理解这些属性。因为很多效果都离不开JS各种位置信息的属性计算,只有理解和记住了这些属性,才能更好的使用,更好的实现比较复杂的效果。

这篇文章不再说明浏览器兼容问题,如果需要请参考最后的参考链接文章。

一、window视图位置属性

1.1、window对象获取视口(浏览器窗口)宽高
console.log(window.innerHeight) // 939
console.log(window.outerHeight) // 1050
console.log(window.innerWidth)  // 809
console.log(window.outerWidth)  // 1680
innerHeight、outerHeight

innerHeight、outerHeight、innerWidth、outerWidth
属性名 描述 备注
window.innerHeight 浏览器窗口高度,如果存在水平滚动条,则包括滚动条 只读属性,没有默认值,不支持的浏览器则是undefined
window.innerWidth 浏览器窗口宽度,如果存在垂直滚动条,则包括滚动条 只读属性,没有默认值,不支持的浏览器则是undefined
window.outerWidth 浏览器窗口整个宽度,包括侧边栏,窗口镶边和调正窗口大小的边框 只读属性,没有默认值,不支持的浏览器则是undefined
window.outerHeight 浏览器窗口整个高度,包括窗口标题、工具栏、状态栏等 只读属性,没有默认值,不支持的浏览器则是undefined

注意:IE8及以下版本不支持window.innerHeightwindow.innerWidth等属性。
对于不支持window.innerHeight等属性的浏览器中,可以读取documentElementbody的高度。最佳方式为:


let width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth
let height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
document.documentElement.clientHeight和document.body.clientHeight的区别

document.documentElement.clientHeightdocument.body.clientHeight的区别:

  • document.documentElement.clientHeight:不包括整个文档的滚动条,但包括<html>元素的边框。
  • document.body.clientHeight:不包括整个文档的滚动条,也不包括<html>元素的边框,也不包括<body>的边框和滚动条。
1.2、window对象获取整个页面滚动的像素值
pageYOffset
属性名 描述 备注 别名
window.pageXOffset 返回文档在水平方向滚动的像素值 只读属性,没有默认值,不支持的浏览器则是undefined pageXOffsetscrollX的别名
window.pageYOffset 返回文档在垂直方向已滚动的像素值 只读属性,没有默认值,不支持的浏览器则是undefined pageYOffsetscrollY的别名
window.pageXOffset == window.scrollX; // 总是 true
window.pageYOffset == window.scrollY; // 总是 true
1.3、window对象获取浏览器窗口在显示器中的位置
screenX、screenY、screenLeft、screenTop
属性名 描述 备注
window.screenX 浏览器窗口在显示器中的水平位置 不支持的浏览器则是undefined
window.screenY 浏览器窗口在显示器中的垂直位置 不支持的浏览器则是undefined
window.screenLeft 浏览器可用空间左边距离屏幕(系统桌面)左边界的距离 不支持的浏览器则是undefined
window.screenTop 浏览器窗口在屏幕上的可占用空间上边距离屏幕上边界的距离 不支持的浏览器则是undefined
1.4、Screen对象视图属性:有关显示器(用户屏幕)信息的一些属性
window.screen.width、window.screen.height

window.screen.availWidth、window.screen. availHeight
window.screen.width、window.screen.height、window.screen.availWidth、window.screen. availHeight
属性名 描述 备注
window.screen.height 显示器屏幕的高度,包括工具栏、状态栏等。
window.screen.width 显示器屏幕的宽度,包括工具栏、状态栏等。
window.screen.availHeight 浏览器窗口在屏幕上可占用的高度。
window.screen.availWidth 浏览器窗口在屏幕上可占用的宽度。
window.screen.colorDepth 表示显示器的颜色深度。
window.screen.pixelDepth 该属性基本上与colorDepth一样。

二、元素视图位置属性

关于元素大小位置等信息的一些属性有三个家族(为了自己好记~):

  • client家族:clientLeftclientTopclientWidthclientHeightheightwidth
  • offset家族:offsetLeftoffsetTopoffsetWidthoffsetHeightoffsetParent
  • scroll家族:scrollLeftscrollTopscrollWidthscrollHeight
2.1、client家族介绍
clientTop、clientLeft

clientTop、clientLeft
clientWidth、clientHeight
属性名 描述 备注
clientLeft 表示内容区域的左上角相对于整个元素左上角水平位置(包括边框和滚动条但是不包含元素的padding或margin) 单纯就是border宽度,返回该方向的border宽度。
clientTop 表示内容区域的左上角相对于整个元素左上角垂直位置(包括边框和滚动条但是不包含元素的padding或margin) 单纯就是border高度,返回该方向的border高度。
clientWidth 表示内容区域的宽度,包括padding大小,但是不包括边框和滚动条。
clientHeight 表示内容区域的高度,包括padding大小,但是不包括边框和滚动条。
height 表示内容区域的高度,不包括padding大小、边框和滚动条。
width 表示内容区域的高度,不包括padding大小、边框和滚动条。
2.2、offset家族介绍
offsetLeft、offsetTop
<main style="position: relative" id="main">
  <article>
    <div id="example" style="position: absolute; left: 180px; top: 180px">...</div>
  </article>
</main>
<script>
  alert(example.offsetParent.id); // main
  alert(example.offsetLeft); // 180 (note: a number, not a string "180px")
  alert(example.offsetTop); // 180
</script>
offsetWidth、offsetHeight
属性名 描述 备注
offsetLeft 相对于最近的祖先定位元素(CSS position 属性被设置为 relative、absolute 或 fixed 的元素)的左偏移值
offsetTop 相对于最近的祖先定位元素(CSS position 属性被设置为 relative、absolute 或 fixed 的元素)的上偏移值)。
offsetWidth 整个元素的宽度(包括边框)。
offsetHeight 整个元素的高度(包括边框)。
offsetParent 第一个祖定位元素 offsetParent元素只可能是:<body>、position不是static的元素、<table>, <th> 或<td>,但必须要position: static
2.3、scroll家族介绍
scroll家族介绍
scroll家族介绍
属性名 描述 备注
scrollLeft 表示元素滚动的宽度 可读可写
scrollTop 表示元素滚动的高度 可读可写
scrollWidth 表示整个内容区域的宽度,包括隐藏的部分。如果元素没有隐藏的部分,则相关的值应该等用于clientWidth和clientHeight。当你向下滚动滚动条的时候,scrollWidth应该等用于scrollTop + clientHeight
scrollHeight 表示整个内容区域的高度,包括隐藏的部分。如果元素没有隐藏的部分,则相关的值应该等用于clientWidth和clientHeight。当你向下滚动滚动条的时候,scrollHeight应该等用于scrollLeft + clientWidth

三、文档视图(DocumentView)和元素视图(ElementView)方法

关于文档和元素视图的方法有一下几种

  • elementFromPoint()
  • getBoundingClientRect()
  • getClientRects()
  • scrollIntoView()

下面会一一介绍这几种方法。

3.1、elementFromPoint()方法介绍

返回给定坐标处所在的元素。

3.2、getBoundingClientRect()方法介绍
image.png

得到矩形元素的界线,返回的是一个对象,包含 top, left, right, 和 bottom四个属性值,大小都是相对于文档视图左上角计算而来。

{
   bottom: 252
   height: 92
   left: 704
   right: 976
   top: 160
   width: 272
   x: 704
   y: 160
}

3.3、getClientRects()方法介绍

获取元素占据页面的所有矩形区域。返回元素的数个矩形区域,返回的结果是个对象列表,具有数组特性。这里的矩形选区只针对inline box,因此,只针对a, span, em这类标签元素。

3.4、scrollIntoView()方法介绍

让元素滚动到可视区域。可以实现元素的锚点跳转功能。

四、小案例

4.1、返回顶部demo
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    html {
      height: 5000px;
    }
  </style>
</head>
<body>
  
<div id="backToTop" style="position:fixed;bottom:80px;right:20px;display: none;cursor: pointer;">返回顶部</div>

<script>

if (!window.requestAnimationFrame) {
  requestAnimationFrame = function(fn) {
    setTimeout(fn, 17)
  };    
}

if (!window.cancelAnimationFrame) {
  window.cancelAnimationFrame = function(id) {
    clearTimeout(id)
  } 
}
const topEl = document.getElementById('backToTop')
window.addEventListener('scroll',function() {
  const winScrollTop = getWinScrollTop()
  if(winScrollTop > 200) {
    topEl.style.display = 'block'
  } else {
    topEl.style.display = 'none'
  }
})

//使用定时器,将scrollTop的值每次减少,直到减少到0,则动画完毕
document.getElementById('backToTop').onclick = function() {
  let timer = null
  timer = requestAnimationFrame(function fn() {
    const backToTop = getWinScrollTop()
    if(backToTop > 0) {
      document.body.scrollTop = document.documentElement.scrollTop = backToTop - 100
      timer = requestAnimationFrame(fn)
    } else {
      cancelAnimationFrame(timer)
    }
  })
}
function getWinScrollTop() {
  return window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
}
</script>
</body>
</html>

五、参考链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容