Ни одно из решений на этой странице не работает, когда контейнер, кроме окна / документа, прокручивается.Подход getBoundingClientRect
терпит неудачу с элементами с абсолютным позиционированием.
В этом случае нам нужно сначала определить прокручиваемый родительский элемент и прокрутить его вместо окна.Вот решение, которое работает во всех текущих версиях браузера и должно работать даже с IE8 и друзьями.Хитрость заключается в том, чтобы прокрутить элемент до верхней части контейнера, чтобы мы точно знали, где он находится, а затем вычесть половину высоты экрана.
function getScrollParent(element, includeHidden, documentObj) {
let style = getComputedStyle(element);
const excludeStaticParent = style.position === 'absolute';
const overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/;
if (style.position === 'fixed') {
return documentObj.body;
}
let parent = element.parentElement;
while (parent) {
style = getComputedStyle(parent);
if (excludeStaticParent && style.position === 'static') {
continue;
}
if (overflowRegex.test(style.overflow + style.overflowY + style.overflowX)) {
return parent;
}
parent = parent.parentElement;
}
return documentObj.body;
}
function scrollIntoViewCentered(element, windowObj = window, documentObj = document) {
const parentElement = getScrollParent(element, false, documentObj);
const viewportHeight = windowObj.innerHeight || 0;
element.scrollIntoView(true);
parentElement.scrollTop = parentElement.scrollTop - viewportHeight / 2;
// some browsers (like FireFox) sometimes bounce back after scrolling
// re-apply before the user notices.
window.setTimeout(() => {
element.scrollIntoView(true);
parentElement.scrollTop = parentElement.scrollTop - viewportHeight / 2;
}, 0);
}