我遇到了 scrollIntoView 有时工作好,有时不行(在大多数情况下不好)的问题。所以我试图找到一种替代方法,这就是这篇文章。
但是在我的程序中,我还需要水平滚动到元素和垂直滚动显示父窗口顶部的元素。
所以我修改了文章中的代码。
/* This is the main function where which pass two ref parameters of Parent element & Child element */
function scrollIntoView(parent, child) {
const parentBounding = parent.getBoundingClientRect(),
clientBounding = child.getBoundingClientRect();
const parentTop = parentBounding.top,
clientTop = clientBounding.top,
parentLeft = parentBounding.left,
clientLeft = clientBounding.left - 400; /* 400 is a shift so that each difference is not nailed to the upper left edge. You can delete it */
if (parentTop >= clientTop) {
scrollTo(parent, -(parentTop - clientTop), 300, 'vertical');
}
else {
scrollTo(parent, clientTop - parentTop, 300, 'vertical');
}
if (parentLeft >= clientLeft) {
scrollTo(parent, -(parentLeft - clientLeft), 300, 'horizontal');
}
else {
scrollTo(parent, clientLeft - parentLeft, 300, 'horizontal');
}
}
function scrollTo(element, to, duration, type) {
let start = (type == 'vertical') ? element.scrollTop : element.scrollLeft,
currentTime = 0,
increment = 20;
let animateScroll = function() {
currentTime += increment;
let val = easeInOutQuad(currentTime, start, to, duration);
if (type == 'vertical') {
element.scrollTop = val;
}
else {
element.scrollLeft = val;
}
if (currentTime < duration) {
setTimeout(animateScroll, increment);
}
}
animateScroll();
}
/* Function for smooth scroll animation with the time duration */
function easeInOutQuad(time, startPos, endPos, duration) {
time /= duration / 2;
if (time < 1) return (endPos / 2) * time * time + startPos;
time--;
return (-endPos / 2) * (time * (time - 2) - 1) + startPos;
}