clientHeight offsetHeight scrollHeight offsetTop scrollTop

2024-01-20 13:18

本文主要是介绍clientHeight offsetHeight scrollHeight offsetTop scrollTop,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 各属性详解
      • 实现
  • offsetParent、offsetLeft/offsetTop深度剖析
  • element.offsetParent
    • 定义
    • 祖先元素中不存在定位元素
    • webkit内核、Firefox下的特殊情况
  • element.offsetWidth / element.offsetHeight
    • 定义
  • element.offsetLeft / element.offsetTop
    • 定义
    • element在正常文档流中
      • element与element.offsetParent之间存在浮动元素
    • element脱离文档流

每个HTML元素都具有clientHeight offsetHeight scrollHeight offsetTop scrollTop 这5个和元素高度、滚动、位置相关的属性,单凭单词很难搞清楚分别代表什么意思之间有什么区别。通过阅读它们的文档总结出规律如下:

各属性详解

clientHeight和offsetHeight属性和元素的滚动、位置没有关系它代表元素的高度,其中:
clientHeight:包括padding但不包括border、水平滚动条、margin的元素的高度。对于inline的元素这个属性一直是0,单位px,只读元素。

请添加图片描述

offsetHeight:包括padding、border、水平滚动条,但不包括margin的元素的高度。对于inline的元素这个属性一直是0,单位px,只读元素。

请添加图片描述

接下来讨论出现有滚动条时的情况:
当本元素的子元素比本元素高且overflow=scroll时,本元素会scroll,这时:
scrollHeight: 因为子元素比父元素高,父元素不想被子元素撑的一样高就显示出了滚动条,在滚动的过程中本元素有部分被隐藏了,scrollHeight代表包括当前不可见部分的元素的高度。而可见部分的高度其实就是clientHeight,也就是scrollHeight>=clientHeight恒成立。在有滚动条时讨论scrollHeight才有意义,在没有滚动条时scrollHeight==clientHeight恒成立。单位px,只读元素。
在这里插入图片描述

scrollTop: 代表在有滚动条时,滚动条向下滚动的距离也就是元素顶部被遮住部分的高度。在没有滚动条时scrollTop==0恒成立。单位px,可读可设置。
offsetTop: 当前元素顶部距离最近父元素顶部的距离,和有没有滚动条没有关系。单位px,只读元素。
在这里插入图片描述offsetTop: 当前元素顶部距离最近父元素顶部的距离,和有没有滚动条没有关系。单位px,只读元素。

在这里插入图片描述

  • 网页可见区域高:document.body.clientHeight //返回元素的高度(包括元素高度、内边距,不包括边框和外边距)

  • 网页正文全文高:document.body.scrollHeight //返回元素的高度(包括元素高度、内边距和溢出尺寸,不包括边框和外边距),无溢出的情况,与clientHeight相同

  • 网页可见区域高(包括边线的高):document.body.offsetHeight //返回元素的高度(包括元素高度、内边距和边框,不包括外边距)

  • scrollTop //此属性可以获取或者设置对象的最顶部到对象在当前窗口显示的范围内的顶边的距离,也就是元素滚动条被向下拉动的距离。 返回值是一个整数,单位是像素。此属性是可读写的

  • 网页被卷去的高:document.body.scrollTop

  • 屏幕分辨率高:window.screen.height

  • style.height //返回元素的高度(包括元素高度,不包括内边距、边框和外边距)

  • offsetTop //返回元素的上外缘距离最近采用定位父元素内壁的距离,如果父元素中没有采用非静态定位的,则是获取上外边缘距离body的距离。


下面是理解应用
(在IOS移动端上,当使用overflow: scroll;属性时,滚动效果慢且不流畅,该情况可以使用

-webkit-overflow-scrolling: touch;属性,让滚动条产生回弹效果,增加滚动的流畅性,提高用户的体验。)。在手指在移动设备的触摸屏上滑动的过程中,监听手指开始滑动,滑动过程中及滑动结束3个事件。在滑动中事件中检查当前滑动的位置是否到达滚动区域的底部,若已到达底部则停止滑动。

实现

给滑动区域添加手势触摸的相关事件

<div @touchstart="touchStart" @touchmove="touchMove" @touchEnd="touchEnd"><!-- 这是一个滚动区域 -->
</div>

定义一个变量用来记录上一次手势滑动过程中最新位置的纵坐标值

export default {data () {lastScrollY: 0 // 上一次手势滑动过程中最新位置的纵坐标}
}

通过手势滑动过程中出发的事件监听滚动区域是否已经到达底部

export default {methods: {touchStart(e) {// 滑动开始时记录起始位置纵坐标this.lastScrollY = e.touches[0].clientY},touchMove(e) {// 滑动过程中记录当前位置纵坐标let top = e.touches[0].clientY// 当前滚动条距离顶部的距离let scrollTop = e.currentTarget.scrollTop// 判断滚动条滚动的方向let direction = (this.lastScrollY - top) < 0 ? 'up' : 'down'// (若滚动条距离顶部的距离 >= 滚动区域的高度 - 滚动可视区域的高度) && 滚动条滚动方向向下 :已到达滚动区域的底部if (scrollTop >= (e.currentTarget.scrollHeight - e.currentTarget.offsetHeight) && direction === 'down') {// 取消事件的默认行为e.preventDefault()// 还原记录的坐标值this.lastScrollY = 0} else {// 否则更新记录的当前位置纵坐标this.lastScrollY = top}},touchEnd() {// 每一次滑动结束时还原记录的坐标值this.lastScrollY = 0}}
}

offsetParent、offsetLeft/offsetTop深度剖析

element.offsetParent

定义

element.offsetParent为包含element的祖先元素中,层级最近的定位元素。 也就是说,offsetParent必须满足三个条件:

  • 是element的祖先元素
  • 最靠近element
  • 是定位元素,即position属性不为static
<div class="position-outer" style="position: relative;"><div class="position" style="postion: relative;"><div class="not-position"><div class="box"></div></div></div>
</div>

打印box元素的offsetParent:

img

由此可见,box祖先元素中存在:

  • 层级为3的定位元素 position-outer
  • 层级为2的定位元素 position-inner
  • 层级为1的非定位元素 not-position

position-inner是同时满足层级最近和定位两个条件的。

祖先元素中不存在定位元素

<div class="box"></div>

img

webkit内核、Firefox下的特殊情况

  • element自身的display属性为none
<div class="position-outer" style="position: relative;"><div class="position-inner" style="postion: relative;"><div class="not-position"><div class="box" style="display: none;"> <!-- 注意这里! --></div></div></div>
</div>

img

  • element自身的position属性为fixed
<div class="position-outer" style="position: relative;"><div class="position" style="postion: relative;"><div class="not-position"><div class="box" style="position: fixed;"> <!-- 注意这里! --></div></div></div>
</div>

img

element.offsetWidth / element.offsetHeight

定义

offsetWidth = content + (垂直滚动条的宽度) + padding + border

  • 无滚动条情况下
<div class="box" style="">
</div>
.box {width: 200px;height: 100px;padding: 20px;border: 12px solid red;margin: 25px;
}

img

打印element.offsetWidth:

img

offsetWidth = 200(content) + 20 * 2(padding) + 12 * 2(border) = 264

  • 有滚动条情况下

img

可以看到,滚动条包含在padding中,因此,offsetWidth与在无滚动条情况下,大小不变。

element.offsetLeft / element.offsetTop

定义

element左上角相对于offsetParent左边界的偏移值。

有个疑问? element的左上角 与 offsetParent的左边界如何定义?是content-box、padding-box还是margin-box?

<div class="position"><div class="box"></div>
</div>
.position {position: relative;top:  0;left:  0;width: 400px;height: 200px;padding:  35px;border: 15px solid purple;
}.box {width: 200px;height: 100px;padding: 20px;border:  12px solid red;margin:  25px;
}

很明显,box的offsetParent为postion

img

打印box.offsetLeft和box.offsetTop:

img

在文档流中,box的整个margin-box是在position的content-box中的,由此可猜测:

box.offsetLeft = position.paddingLeft + box.marginleft = 35 + 25 = 60

真的是这样吗?其实并没有那么简单,需要分两种情况讨论:

element在正常文档流中

element.offsetLeft是指element的border-box左上角相对offsetParent的content-box的偏移量

由于position: relative的元素并没有脱离文档流,因此,也需要加入到offseLeft/offsetTop的计算中

修改box css属性:

.box {position: relative; /* 新增的 */top: 31px;          /* 新增的 */left: 31px;         /* 新增的 */width: 200px;height: 100px;padding: 20px;border:  12px solid red;margin:  25px;
}

再次打印box.offsetLeft和box.offsetTop:

img

两者的值都增加了31,也就是top和left属性对应的值,由此更新计算公式:

element.offsetLeft = offsetParent.paddingLeft + element.left + element.marginLeft

但是,以上都是在最简单的情况下计算的,即element与element.offsetParent之间没有其它层级的元素存在!

我们在element与element.offsetParent之间再插入一个元素:

<div class="position"><div class="middle">    <!-- 新增的 --><div class="box"></div></div>
</div>.parent {width: 30px;height: 150px;padding:  11px;border:  12px solid pink;margin-left:  13px;
}

img

打印box.offsetLeft和box.offsetTop:

img

两者的值又变化了!相比上次又增加了36,正好是parent的marginLeft、borderLeft 、paddingLeft之和,11 + 12 + 13 = 36,由此得到最终的计算公式:

element.offsetLeft = offsetParent.paddingLeft + element.left + element.marginLeft + (element与element.offsetParent之间所有 在正常文档流且position属性不为relative的元素 marginLeft、borderLeft、paddingLeft之和)

element与element.offsetParent之间存在浮动元素

现在,我们让parent向右浮动:

.parent {float: right;width: 30px;height: 150px;padding:  11px;border:  12px solid pink;margin-left:  13px;
}

打印box.offsetLeft和box.offsetTop:

img

这次只有box.offsetLeft变化了,而且也可以猜测到是由于parent的右浮,box是其子元素,一起右浮,导致box.offsetLeft变化的。

这下要怎么计算?难道还要算浮动的距离吗?

并不需要!只要借助parent就能计算!仔细想想,element与element.offsetParent一定是没有浮动元素的,那么对于parent,其offsetParent也就是box的offsetParent,即postition。

我们打印下parent.offsetleft:

img

再计算box到parent之间的偏移量: box.left + box.marginLeft + parent.paddingLeft + parent.borderLeft + parent.marginLeft = 31 + 25 + 11 + 12 + 13 = 92

76 + 92 = 168,与box.offsetLeft一致,这也说明我们的计算公式是正确的!

element脱离文档流

也就是说element的display属性为absolute或fixed,由于fixed会导致offsetParent为null,所以我们将box的display设置为absolute:

<div class="position"><div class="box"></div>
</div>
复制代码
.box {position: absolute; /* 新增的 */top: 31px;left:  31px;width: 200px;height: 100px;padding: 20px;border:  12px solid red;margin:  25px;
}.position {position: relative;top:  0;left:  0;width: 400px;height: 200px;padding:  35px;border: 15px solid purple;
}

打印box.offsetLeft和box.offsetTop:

img

我们知道,display属性为absolute或fixed的元素,是相对于包含块的padding-box定位的,因此在计算offsetLeft时,就不需要考虑offsetParent的paddingLeft了。

并且,element是脱离文档流的,也就是说,除了element.offsetParent,不再与其它任何元素产生联系,也就不需要再考虑element与element.offsetParent之间的任何元素了。

因此,计算公式非常简单:

element.offsetLeft = element.left + element.marginLeft

评论1:

纠正一下,插入完parent元素后,box的offsetTop值应为114px,因为parent元素并没有margin-top值,而浮动之后的parent.offsetLeft应为89px,它已经包含了parent元素的margin-left值(13px),再看插入parent后,box的offsetLeft为127px(margin-left的值计算在内),将127px-13px+54px( 89px - 35px(position的padding值) )=168px这就为浮动之后的box的offsetLeft的值。
转载自

这篇关于clientHeight offsetHeight scrollHeight offsetTop scrollTop的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/626130

相关文章

document.body.scrollTop指定位置失效解决办法

近期在vue的pc项目中,做指定位置定位的时候发现使用document.body.scrollTop一直不生效。 解决办法是document.body.scrollTop改成document.documentElement.scrollTop

offsetTop、clientTop、scrollTop、offsetTop定义

页可见区域宽: document.body.clientWidth; 网页可见区域高: document.body.clientHeight; 网页可见区域宽: document.body.offsetWidth (包括边线的宽); 网页可见区域高: document.body.offsetHeight (包括边线的宽); 网页正文全文宽: document.body.scrollWidth; 网

各种位置和高度计算:.position()、.offset()、.outerHeight()、.scrollTop、.scrollHeight、.clientHeight

1、.position()和.offset() jquery的.position()获取相对于最近的position为relative或absolute的父元素的偏移,返回.position().left和.position().top,不算上自己的margin-left; jquery的.offset()获取相对于视口左上角的偏移,返回.offset().left和.offset().top

微信浏览器自带的返回上一页的停留位置 scrollTop

我们做过微信的应该都知道,微信自带的返回上一页,就是重新打开页面。并不是返回历史页面。我们PC端的浏览器是返回历史页面。点击返回页面之后 上一个页面的scrollTop还是之前没有进入新页面的位置。 我看了下京东的微信网站。果然和我想到的方法一样。利用sessionStorage HTML5本地存储 进行存储位置scrollTop以及加载了多少次ajax次数 微信返回上一页(当前页面)之后。就会

vue3中 window绑定scroll事件滚动页面获取不到e.target.scrollTop

遇到的问题 vue3项目 onMounted(() => {window.addEventListener('scroll', (e) => {console.log(e.target.scrollTop)})}) 想要监听页面中的滚动,然后获取滚动距离实现一些功能,发现event参数中获取不到e.target.scrollTop(印象中以前使用这个获取的),发现e.target中根

scrollTop兼容各个浏览器的办法

var scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;alert(scrollTop);

offset、offsetLeft,offsetWidth和offsetHeight的使用方法

转自:http://www.cnblogs.com/rixinren/archive/2010/04/25/1720680.html 假设 obj 为某个 HTML 控件。 obj.offsetTop 指 obj 相对于版面或由 offsetParent 属性指定的父坐标的计算上侧位置,整型 obj.offsetLeft 指 obj 相对于版面或由 offsetParent 属性指

获取scrollTop兼容各浏览器的方法

window.pageYOffset      属于window对象,IE9+ 、firefox、chrome,opera均支持该方式获取页面滚动高度值,并且会忽略Doctype定义规则。 window.scrollY  属于window对象,firefox、chrome,opera支持,IE不支持,忽略Doctype规则。 document.documentElement.scrollT

js滑动操作之-pageYOffset,scrollTop,offsetHeight,scrollHeight

读值 1) window.pageYOffset==window.scrollY it returns the number of pixels the document is currently scrolled along the vertical axis 2) scrollElm.scrollTop   gets or sets the number of pix

文档声明!DOCTYPE html导致document.body.offsetHeight取值为0

关于通过JS获取窗口高度和宽度的问题,如果使用了文档声明(<!DOCTYPE html>),则取得document.body.offsetHeight的值是0,删除文档声明后,则可以取得正确的值,可见文档声明对JS是有影响的,时间关系没有详细调查,下面的一篇文档可以作为参考。   DOCTYPE声明对JS获取窗口宽度和高度的影响