需求
- 我有个侧面的菜单 , 点击对应的菜单标题, 可以让左侧的容易里对应标题滑到最顶上
- 于是我封装了一个缓动函数
这个函数接受3个参数
- 需要滚动的最外层的容器
- 滚动到什么距离
- 滚动时间
注意点
第一个参数的最外层的容器 , 需要滚动条( 没滚动条是没有办法滚动的 )
第二个参数是滚动的距离 , 其实也就是内部需要置顶的子元素的offsetTop ( 子元素距离顶部的距离 )
第三个参数可以不传,有默认值
smoothScrollToTop(element, targetScrollTop, duration = 500) {
const startingScrollTop = element.scrollTop;
console.log(startingScrollTop, "startingScrollTop11111");
const startTime = performance.now();
const scrollDistance = targetScrollTop - startingScrollTop;
function animateScroll(currentTime) {
const elapsedTime = currentTime - startTime;
const progress = Math.min(elapsedTime / duration, 1);
const easeInOutQuad = (t) =>
t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
element.scrollTop =
startingScrollTop + scrollDistance * easeInOutQuad(progress);
if (progress < 1) {
requestAnimationFrame(animateScroll);
}
}
requestAnimationFrame(animateScroll);
},
使用demo
- 直接复制保存html预览
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="btn">我要让元素滑动置顶</button>
<div id="box">
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1 id="top">需要置顶的元素</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
<h1>1</h1>
</div>
</body>
<script>
function smoothScrollToTop(element, targetScrollTop, duration = 500) {
const startingScrollTop = element.scrollTop;
const startTime = performance.now();
const scrollDistance = targetScrollTop - startingScrollTop;
function animateScroll(currentTime) {
const elapsedTime = currentTime - startTime;
const progress = Math.min(elapsedTime / duration, 1);
const easeInOutQuad = (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
element.scrollTop = startingScrollTop + (scrollDistance * easeInOutQuad(progress));
if (progress < 1) {
requestAnimationFrame(animateScroll);
}
}
requestAnimationFrame(animateScroll);
}
const btn = document.querySelector(`#btn`)
btn.addEventListener(`click`, () => {
const element = document.querySelector(`#top`)
const offsetTop = element.offsetTop;
smoothScrollToTop(box, offsetTop);
})
</script>
</html>
<style>
#btn {
position: fixed;
top: 0;
left: 0;
width: 100px;
height: 100px;
}
#box {
height: 500px;
background-color: red;
overflow: scroll;
margin-left: 100px;
}
</style>