This repository has been archived by the owner on Dec 24, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 36
/
scrollToPosition.ts
57 lines (47 loc) · 1.85 KB
/
scrollToPosition.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/**
* Scroll to a x = 0 and y = variable position in the screen
* Sometimes a scroll can't be done on the window, so the scroll needs to be done on the largest
* element on the screen
*/
export default function scrollToPosition(yPosition: number): void {
const initialScroll = document.documentElement.scrollTop;
// If for some reason the scroll didn't work, find the first largest element and use that to scroll on
let largestNode: HTMLElement;
// Scroll with the default way of scrolling
window.scrollTo(0, yPosition);
/* istanbul ignore else */
if (initialScroll === document.documentElement.scrollTop && yPosition > 0) {
largestFirstNode(document.documentElement.childNodes).scrollTo(0, yPosition);
}
/**
* Find the first largest node in the page so it can be used for scrolling
*/
function largestFirstNode(nodesList: any) {
let node: HTMLElement;
// Loop over the nodes
for (let i = nodesList.length - 1; i >= 0; i--) {
node = nodesList[i];
// Stop if the largest node has been found
/* istanbul ignore next */
if (largestNode) {
break;
}
// Check if the element has a scroll / client height
/* istanbul ignore next */
if (node.scrollHeight && node.clientHeight) {
const viewPortHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
const elHeight = Math.max(node.scrollHeight, node.clientHeight);
// If the element is bigger than the viewport, then we got our scroll container
if (elHeight > viewPortHeight) {
largestNode = node;
break;
}
}
if (node.childNodes.length) {
largestFirstNode(node.childNodes);
}
}
// If the largestNode is the body then return the window
return (document.body === largestNode || !largestNode) ? window : largestNode;
}
}