Scroll element in to view using center and for all the scrollable ancestors
Closes #14527
This commit is contained in:
+50
-7
@@ -79,16 +79,59 @@
|
||||
};
|
||||
|
||||
Sao.common.scrollIntoViewIfNeeded = function(element) {
|
||||
element = element[0];
|
||||
if (element) {
|
||||
var rect = element.getBoundingClientRect();
|
||||
if (rect.bottom > window.innerHeight) {
|
||||
element.scrollIntoView(false);
|
||||
function isScrollable(el) {
|
||||
let style = getComputedStyle(el);
|
||||
return /(auto|scroll|overlay)/.test(
|
||||
style.overflow + style.overflowY + style.overflowX
|
||||
);
|
||||
}
|
||||
|
||||
function getScrollableAncestors(el) {
|
||||
let ancestors = [];
|
||||
let parent = el.parentElement;
|
||||
while (parent && parent !== document.body) {
|
||||
if (isScrollable(parent)) {
|
||||
ancestors.push(parent);
|
||||
}
|
||||
parent = parent.parentElement;
|
||||
}
|
||||
if (rect.top < 0) {
|
||||
element.scrollIntoView();
|
||||
ancestors.push(window);
|
||||
return ancestors;
|
||||
}
|
||||
|
||||
function scrollIntoViewWithin(el, container) {
|
||||
let rect = el.getBoundingClientRect();
|
||||
|
||||
if (container === window) {
|
||||
if (rect.top < 0 || rect.bottom > window.innerHeight) {
|
||||
el.scrollIntoView({
|
||||
block: 'center',
|
||||
});
|
||||
}
|
||||
} else {
|
||||
let container_rect = container.getBoundingClientRect();
|
||||
let top_ = rect.top - container_rect.top;
|
||||
let bottom = top_ + rect.height;
|
||||
|
||||
let target_top = container.scrollTop;
|
||||
|
||||
if (top_ < 0) {
|
||||
target_top += top_ - container.clientHeight / 2;
|
||||
} else if (bottom > container.clientHeight) {
|
||||
target_top += bottom - container.clientHeight / 2
|
||||
}
|
||||
container.scrollTo({
|
||||
top: Math.max(0, target_top),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
element.each(function() {
|
||||
let ancestors = getScrollableAncestors(this);
|
||||
for (let ancestor of ancestors) {
|
||||
scrollIntoViewWithin(this, ancestor);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Handle click and Return press event
|
||||
|
||||
Reference in New Issue
Block a user