//首先编写一个scrollToBottom函数
function scrollToBottom(el){
if(!el){
el=container;
}
//原始值
let startTop=el.scrollTop;
//最终值
let endTop=el.scrollHeight-el.clientHeight;
//生成一个动画控制函数
let scrollAnimationFn=doAnimation(startTop,endTop,300,el);
//执行动画,每10ms执行一次
let interval=setInterval(()=>{
scrollAnimationFn(interval)
},10)
}
/**
* @description: 一个生成动画控制函数的工厂函数(使用闭包)
* @param {
startValue:变量原始值
endValue:变量最终值
duration:动画时长
el:执行滚动动画的元素
}
* @return: null
*/
function doAnimation(startValue,endValue,duration,el){
//使用闭包保存变量dy和step(每次动画滚动的距离)
let dy=0;
let step=(endValue-startValue)/(duration/10);
//返回动画控制函数
return function(interval){
dy+=step;
if(dy>=endValue-startValue){
clearInterval(interval);
}
el.scrollTop+=step;
}
}
修改addItem函数添加滚动到底部动画:
function addItem(){
index+=1;
let item=`<div id="${'item'+index}" class="scroll_item">
<span>${index}</span>
</div>`;
container.innerHTML+=item;
setTimeout(()=>{
// scrollToIndex();
scrollToBottom(container);
})
}
然后为html加入一个滚动到底部的按钮:
<button onclick="scrollToBottom()">滚动到底部</button>
滚动到顶部
按照上面的方法也可以实现一个常用的带动画滚动到顶部:
//编写一个scrollToTop函数
function scrollToTop(el){
if(!el){
el=container;
}
//原始值
let startTop=el.scrollTop;
//最终值
let endTop=0;
//生成一个动画控制函数
let scrollAnimationFn=doAnimation(startTop,endTop,300,el);
//执行动画,每10ms执行一次
let interval=setInterval(()=>{
scrollAnimationFn(interval)
},10)
}
function scrollToElement(containerEl,el){
if(!containerEl){
//父元素
containerEl=container;
}
if(!el){
//获取到要滚动到的元素
let input=document.getElementsByTagName('input')[0];
let id='item'+input.value;
if(!input.value){
id='item'+index;
}
el=document.getElementById(id);
}
let startTop=containerEl.scrollTop;
let endTop=startTop+el.getBoundingClientRect().top;
let scrollAnimationFn=doAnimation(startTop,endTop,300,containerEl);
let interval=setInterval(()=>{
scrollAnimationFn(interval)
},10)
}
function scrollToElement(containerEl,el){
//因为getBoundingClientRect().top即为子元素顶部距离父元素顶部的距离,所以这个值就是子元素相对于父元素的偏移量,我们传入这个值到scrollBy中,即滚动到指定元素
containerEl.scrollBy(0,el.getBoundingClientRect().top);
}
滚动到底部:
function scrollToBottom(containerEl){
let dy=containerEl.scrollHeight-containerEl.clientHeight;
containerEl.scrollBy(0,dy);
}
滚动到顶部
function scrollToTop(containerEl){
let dy=-(containerEl.scrollHeight-containerEl.clientHeight);
containerEl.scrollBy(0,dy);
}
function scrollToBottom(containerEl){
if(!containerEl){
containerEl=container;
}
//dy即为偏移量
let dy=containerEl.scrollHeight-containerEl.clientHeight;
let scrollAnimationFn=doAnimation(dy,300,containerEl);
let interval=setInterval(()=>{
scrollAnimationFn(interval)
},10)
}
function scrollToTop(containerEl){
if(!containerEl){
containerEl=container;
}
//dy即为偏移量
let dy=-(containerEl.scrollHeight-containerEl.clientHeight);
let scrollAnimationFn=doAnimation(dy,300,containerEl);
let interval=setInterval(()=>{
scrollAnimationFn(interval)
},10)
}
function scrollToElement(containerEl,el){
if(!containerEl){
containerEl=container;
}
if(!el){
let input=document.getElementsByTagName('input')[0];
let id='item'+input.value;
if(!input.value){
id='item'+index;
}
el=document.getElementById(id);
}
//dy即为偏移量
let dy=el.getBoundingClientRect().top;
let scrollAnimationFn=doAnimation(dy,300,containerEl);
let interval=setInterval(()=>{
scrollAnimationFn(interval)
},10)
}
/**
* @description:
* @param {type}
* @return:
*/
function doAnimation(dy,duration,el){
//使用闭包保存变量exe_dy和step等变量(每次动画滚动的距离)
let exe_dy=0;//已经执行的偏移量
let step=dy/(duration/10);
return function(interval){
exe_dy+=step;
if(Math.abs(exe_dy)>=Math.abs(dy)){
clearInterval(interval);
}
el.scrollBy(0,step);
}
}