前言:document和body和浏览器可视窗口
- 浏览器可视窗口就是浏览器的可视区域的大小
- document是指当前页面的大小,没有滚动条,document和浏览器可视窗口是一样的。但是比如高度方向上有滚动条,那么document指的就是带上滚动内容的高度了,就是内容的实际高度了,比可是区域肯定是要高的。
- body正常理解大小和document一样大,暂时就这样,先不过多理解document.body,就当作两个大小一样
1、offset
1.1、offsetHeight
他是一个只读属性,它返回该元素的像素高度,高度包含该元素的垂直内边距和边框,且是一个整数。注意我们说的内边距就是padding,外边距就是margin.
我们看下下面的图是有滚动效果的,但是这不影响offset。offset就是我们设置的css高度加上边框和内边距。
1.2、offsetWidth
测量包含元素的边框 (border)、水平线上的内边距 (padding)、竖直方向滚动条 (scrollbar)(如果存在的话)、以及 CSS 设置的宽度 (width) 的值。
和offsetHeight一摸一样,但是需要注意的是,offsetWidth会计算滚动条的宽度哦!!!!
这里必须要记住一个东西:滚动条是在padding和border中间的一个独立的宽度!!!!!
1.3、offsetParent
如果你想继续研究offsetTop和offsetLeft的话,那你就必须线搞明白offsetParent是什么东西哦。。
只读属性,返回一个指向最近的(指包含关系层级上的最近)包含该元素的定位元素或者最近的 table, td, th, body 元素。当元素的 style.display 设置为 “none” 时,offsetParent 返回 null。offsetParent 很有用,因为 offsetTop 和 offsetLeft 都是相对于其内边距边界的。
东西不多,提取几个点:
- 首先是最近的,并且注意是包含关系的,也就是不断的找父级,一直找到有定位元素的
- 或者父级元素里找到了table, td, th, body这四个也就听下来了
- 我们后面要说的 offsetTop 和 offsetLeft 都是相对于offsetParent内边距的距离
1.4、offsetTop
只读属性,它返回当前元素外边距的顶部相对于其offsetParent元素的顶部内边距的距离。注意这个距离很有意思的,当我们设置一个元素滚动到另一个元素的顶部的时候,这个元素很有意思。比如说:
从上图看,如果我们希望B滚动到A的顶端,那其实只要如下就行,只需要两个offsetTop相减就行。是不是很好理解这个。
const ADom: any = document.querySelector('A');
const BDom: any = containerDom.querySelector('B');
ADom.scrollTo({
top: BDom.offsetTop - ADom.offsetTop,
behavior: 'smooth'
});
当然,如果有另一种情况,就不一样了,比如说A也加了定位,那么B的offsetParent就是A了,那么就成了如下
从上图看,想要B滚动到A的顶端只要如下
const ADom: any = document.querySelector('A');
const BDom: any = containerDom.querySelector('B');
ADom.scrollTo({
top: BDom.offsetTop,
behavior: 'smooth'
});
再说下面这种情况,把B滚动到container的顶端。
const containerDom: any = document.querySelector('container');
const ADom: any = document.querySelector('A');
const BDom: any = containerDom.querySelector('B');
containerDom.scrollTo({
top: BDom.offsetTop + ADom.offsetTop - containerDom.offsetTop,
behavior: 'smooth'
});
除此之外,需要注意一点,如果当前定位元素本身是固定定位(position:fixed;),那么就别费心找爹了,返回的是当前元素与可视窗口的距离。
上面看完就应该基本了解了,然后要学会举一反三哦!!!
2、scroll
2.1、scrollHeight
只读属性是一个元素内容高度的度量,包括由于溢出导致的视图中不可见内容。
下面的解释很重要:
scrollHeight 的值等于该元素在不使用滚动条的情况下为了适应视口中所用内容所需的最小高度。高度的度量方式与 clientHeight 相同:包括元素的内边距,但不包括,注意是不包括元素的边框、外边距以及水平滚动条(如果存在)。但是它包括 ::before 和 ::after 这样的伪元素的高度。看看什么是前后伪元素,
主要看实际的dom解构:伪元素是在div内部的!!!!
2.2、scrollWidth
解释和scrollHeight一样:等于元素在不使用水平滚动条的情况下适合视口中的所有内容所需的最小宽度。宽度的测量方式与clientWidth相同:它包含元素的内边距,但不包括边框,外边距或垂直滚动条(如果存在)。它还可以包括伪元素的宽度,例如::before或::after。如果元素的内容可以适合而不需要水平滚动条,则其scrollWidth等于clientWidth。
到此我们先来看个问题:如果有一个div高度是100px,内外边距都是0,边框也为0。div里面的文本内容高度是200px。如果我给这个div设置了overflow:hidden的话,那么文本内容的高度超出了div设定高度,我们知道超出的内容会被隐藏,但是请问此时这个div的scrollHeight和clientHeight分别是多少呢?
以下是gpt的回答:
在这种情况下:div 的 clientHeight 是该 div 的内部可视区域的高度,不包括滚动条、边框和边距。因为 div 的高度是100px,并且边框和内外边距都是0,所以 clientHeight 将是100px。div 的 scrollHeight 是该 div 所包含的所有内容的总高度,包括那些由于溢出(overflow)而不可见的内容。由于 div 内的文本内容实际高度是200px,即使部分内容因为溢出被隐藏了,scrollHeight 也会是200px。因此,这个 div 的 clientHeight 应该是100px,而 scrollHeight 应该是200px。
上面的问题可以总结出:scrollHeight的高度和有没有滚动条没关系,他就在那里,不管你滚不滚动,只要超出那么scrollHeight和clientHeight就会不一样!!
2.3、scrollTop
一个元素的 scrollTop 值是这个元素的内容顶部(卷起来的)到它的视口可见内容(的顶部)的距离的度量。当一个元素的内容没有产生垂直方向的滚动条,那么它的 scrollTop 值为0。内容顶部和视口可见内容顶部基本百分百重合,有内边距,那就重合在内边距的顶部,没有内边距那就是重合在内容的顶部。看下面的图就行了,很好理解的。
2.4、scrollLeft
和scrollTop一样没啥好说的
3、client
3.1、clientTop
只读属性 Element.clientHeight 对于没有定义 CSS 或者内联布局盒子的元素为 0;否则,它是元素内部的高度(以像素为单位),包含内边距,但不包括边框、外边距和水平滚动条(如果存在)。
3.2、clientWidth
只读属性 Element.clientWidth 对于内联元素以及没有 CSS 样式的元素为 0;否则,它是元素内部的宽度(以像素为单位)。该属性包括内边距(padding),但不包括边框(border)、外边距(margin)和垂直滚动条(如果存在)。
3.3、clientHeight
一个元素顶部边框的宽度(以像素表示)。不包括顶部外边距或内边距。clientTop 是只读的。注意就是指头部边框的宽度
3.4、clientLeft
表示一个元素的左边框的宽度,以像素表示。如果元素的文本方向是从右向左(RTL, right-to-left),并且由于内容溢出导致左边出现了一个垂直滚动条,则该属性包括滚动条的宽度。clientLeft 不包括左外边距和左内边距。clientLeft 是只读的。
4、client与page
注意:这个不是节点属性了哈,是鼠标事件属性
event.clientX /event.clientY是目标点距离浏览器可视范围的X轴/Y轴坐标
event.pageX /event.pageY 是目标点距离document最左上角的X轴/Y轴坐标
两者都是只读属性,咱们来直接看下面的打印结果
5、style
注意注意:这个是可写属性啦啦啦啦啦!!!
5.1、style.width和style.height
style.width仅仅能返回在HTML中定义的内部样式表的width属性值,如果定义在CSS中就获取不到。
offsetHeight,offsetWidth返回纯数字小数会四舍五入,style.height,style.width返回字符串,带单位(px)。
style.height/style.width是不包含边框的哦。还是用和公式表示一下:offsetWidth = style.width + style.padding + style.border
如果没有为元素设置高度,offsetHeight会根据内容获取高度值,style.height会返回undefind
可读写性不一样:offsetHeight/offsetWidth只读,style.height/style.width可读写。
5.2、style.top和style.left
style.left/style.top和offsetLeft/offsetTop的功能一样,那么它们有什么区别呢?
返回值不一样:style.left/style.top返回的是字符串,带了单位(px)的,而offsetLeft/offsetTop只返回数字(小数会四舍五入
可读写性不同:offsetLeft/offsetTop只读,而style.left/style.top 可读写。
若是没有给 HTML 元素指定过 top 样式,则 style.top 返回的是空字符串(而且必须要定义在html里,如果定义在css里,style.left的值仍然为空,这也是个坑啊,大家谨慎)。
这里附加一个掘金相关的文章,可以看看的。
https://juejin.cn/post/6844904133921619982?searchId=2024040315271452BB4674335D877F1A47