//首先編寫一個scrollToBottom函數(shù)
function scrollToBottom(el){
if(!el){
el=container;
}
//原始值
let startTop=el.scrollTop;
//最終值
let endTop=el.scrollHeight-el.clientHeight;
//生成一個動畫控制函數(shù)
let scrollAnimationFn=doAnimation(startTop,endTop,300,el);
//執(zhí)行動畫,每10ms執(zhí)行一次
let interval=setInterval(()=>{
scrollAnimationFn(interval)
},10)
}
/**
* @description: 一個生成動畫控制函數(shù)的工廠函數(shù)(使用閉包)
* @param {
startValue:變量原始值
endValue:變量最終值
duration:動畫時長
el:執(zhí)行滾動動畫的元素
}
* @return: null
*/
function doAnimation(startValue,endValue,duration,el){
//使用閉包保存變量dy和step(每次動畫滾動的距離)
let dy=0;
let step=(endValue-startValue)/(duration/10);
//返回動畫控制函數(shù)
return function(interval){
dy+=step;
if(dy>=endValue-startValue){
clearInterval(interval);
}
el.scrollTop+=step;
}
}
修改addItem函數(shù)添加滾動到底部動畫:
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>
滾動到頂部
按照上面的方法也可以實現(xiàn)一個常用的帶動畫滾動到頂部:
//編寫一個scrollToTop函數(shù)
function scrollToTop(el){
if(!el){
el=container;
}
//原始值
let startTop=el.scrollTop;
//最終值
let endTop=0;
//生成一個動畫控制函數(shù)
let scrollAnimationFn=doAnimation(startTop,endTop,300,el);
//執(zhí)行動畫,每10ms執(zhí)行一次
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;//已經(jīng)執(zhí)行的偏移量
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);
}
}