一、clientwidth 和 offsetwidth 和scrollWidth
1、clientwidth 和 offsetwidth
clientwidth是content+padding
offsetwidth是content+padding+border
区别是box-sizing = border-box的时候,设置的width会被挤压。
content、padding、border都会在设置的width内挤压,即border会挤压clientwidth的宽度。而offsetwidth则会一直等于width。
clientwidth = 设置的width-border ,offsetwidth = 设置的width
box-sizing=content-box的时候,设置的width不会被挤压。
clientwidth = 设置的width+padding,offsetwidth = 设置的width+padding+border
2、scrollWidth
(1)在内容区没有发生溢出的情况下,scrollWidth = clientWidth 因为它们都是代表内容区的宽度。
(2)在内容区发生了溢出,并且设置了 overflow-scroll 之类的属性的情况下,clientWidth 代表dom 当前状态下,实际上展示在可视区域的 内容区(content) 的宽度,而 scrollWidth 则代表了真实的内容区的宽度,包括了那些没有展现在用户面前的,需要滚动才可以看到的内容的宽度。这时候 scrollWidth= clientWidth + 溢出的内容区的宽度。
所以 clientWidth 更确切的中文翻译应该是---客户端可视区域内,内容区的宽度。
总结:
(1)在内容区没有溢出的情况下:scrollWidth = clientWidth
(2)在内容区溢出的情况下:scrollWidth = clientWidth + 溢出的内容区的宽度
二、scrollTop 和 clientleft 和 offsetleft
1、scrollTop
(1)在内容区没有溢出的情况下:
scrollTop一直为0
(2)在内容区溢出的情况下:
没开始滚动时,scrollTop = 0,滚动到底时,scrollTop = scrollHeight - clientHeight
(3)滚动的几种方式:
i、ref.current.scrollTop = xxxx 一般没有负数,负数相当于0
ii 、ref.current.scrollTo (x,y) 或者 element.scrollTo({ top: 100,left: 100,behavior: "smooth"});
滚动到顶部设置为0,滚动到底部可以设置为一个无限大数
注意这个数字和scrollTop的数字是一样的
往上滚动是正数,一般没有负数,负数相当于0
iii、scrollBy 相对于现在的位置增量或者减量多少(有负数,负数就是减量)
iiii、scrollIntoView
经过测试不是很好用,父容器不是document,而是自定义元素的时候,有溢出的元素滚动了的同时,最外层的父容器也一起滚动了。不太可控。
测试区别代码地址:https://codepen.io/zymbth/pen/NWYgqdB
<script setup>
import { ref } from 'vue'
// 菜单、区域
const blocks = ref([
{ label: 'Home', id: 'home' },
{ label: 'Platform', id: 'platform' },
{ label: 'Career', id: 'career' },
{ label: 'Contact', id: 'contact' },
{ label: 'About', id: 'about' }
])
const scrollWrap = ref()
function execScrollTo(x = 200, y = 200) {
// scrollWrap.value.scrollTo(x, y)
scrollWrap.value.scrollTo({
top: x,
left: y,
behavior: 'smooth'
})
}
function execScrollBy(x = 20, y = 50) {
scrollWrap.value.scrollBy({
top: x,
left: y,
behavior: 'smooth'
})
}
function execScrollIntoView() {
document.getElementById('career').scrollIntoView({
block: 'start',
inline: 'start',
behavior: 'smooth'
})
}
</script>
<template>
<div class="scroll-wrap" ref="scrollWrap">
<div class="scroll-view">
<div
class="container"
v-for="block in blocks"
:key="block.id"
:id="block.id"
v-html="block.label"
/>
</div>
</div>
<div>
<button @click="execScrollTo()">scrollTo</button>
<button @click="execScrollBy()">scrollBy</button>
<button @click="execScrollIntoView()">scrollIntoView</button>
</div>
</template>
<style>
html,body {margin:0}
body {
margin: 10px;
}
.scroll-wrap {
height: 500px;
width: 260px;
padding: 10px;
margin: 0 10px 10px 0;
overflow: auto;
background-color: #f5f7f9;
border: 1px solid #ccc;
}
.scroll-view {
min-height: 2000px;
}
button+button {margin-left:10px}
.container {
padding: 10px;
border-radius: 6px;
background-color: #fff;
min-height: 300px;
width: 600px;
}
.container + .container {
margin-top: 10px;
}
</style>
scrollTop=xxx的时候是瞬时滚动,可以可滚动元素使用scrollTo
的 behavior
属性可以做滚动动画#el.scrollTo({ top: 0, behavior: 'smooth' })
也可以自己写滚动动画,实现平滑滚动,该方法支持向上和向下滚动
// 滚动到距离页面顶部500px的位置 动画时间为200ms
ScrollTop(500, 200);
优化scrollTop滚动效果,有平滑过渡效果
const ScrollTop = (number = 0, time) => {
if (!time) {
document.body.scrollTop = document.documentElement.scrollTop = number;
return number;
}
const spacingTime = 20; // 设置循环的间隔时间 值越小消耗性能越高
let spacingInex = time / spacingTime; // 计算循环的次数
let nowTop = document.body.scrollTop + document.documentElement.scrollTop; // 获取当前滚动条位置
let everTop = (number - nowTop) / spacingInex; // 计算每次滑动的距离
let scrollTimer = setInterval(() => {
if (spacingInex > 0) {
spacingInex--;
ScrollTop(nowTop += everTop);
} else {
clearInterval(scrollTimer); // 清除计时器
}
}, spacingTime);
};
2、clientleft:元素到边界的距离,有border属性的话,clientleft就是border的值
clientLeft:相当于元素左border(border-left)的宽度
clientTop:相当于元素上border(border-top)的宽度
3、offsetleft:元素距离父元素的左边界,如果父元素没有设置position为relation和absolute,就是元素到窗口的距离
offsetLeft:元素左外边框距离父元素左内边框的距离(简单来说就是元素相对父元素左边的距离)
offsetTop:元素上外边框距离父元素上内边框的距离(简单来说就是元素相对父元素上边的距离)
三、getBoundingClientRect()
getBoundingClientRect()获取元素位置,这个方法没有参数
getBoundingClientRect()用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置。
getBoundingClientRect()是DOM元素到浏览器可视范围的距离(不包含文档卷起的部分)。
该函数返回一个Object对象,该对象有6个属性:top,lef,right,bottom,width,height;
<div id="box"></div>
var object=document.getElementById('box');
rectObject = object.getBoundingClientRect();
rectObject.top:元素上边到视窗上边的距离;
rectObject.right:元素右边到视窗左边的距离;
rectObject.bottom:元素下边到视窗上边的距离;
rectObject.left:元素左边到视窗左边的距离;
rectObject.width:是元素自身的宽
rectObject.height是元素自身的高
四、tip
1、不展示滚动条css:
scrollbarWidth: "none",
MsOverflowStyle: "none",
"&::-webkit-scrollbar": {
display: "none",
},