import { isIOS as checkIsIOS } from '../validate/system'; type ScrollElement = Element | Window; function isWindow(val: unknown): val is Window { return val === window; } export function getScrollTop(el: ScrollElement): number { const top = 'scrollTop' in el ? el.scrollTop : el.pageYOffset; // iOS scroll bounce cause minus scrollTop return Math.max(top, 0); } export function setScrollTop(el: ScrollElement, value: number) { if ('scrollTop' in el) { el.scrollTop = value; } else { el.scrollTo(el.scrollX, value); } } export function getRootScrollTop(): number { return ( window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0 ); } export function setRootScrollTop(value: number) { setScrollTop(window, value); setScrollTop(document.body, value); } // get distance from element top to page top or scroller top export function getElementTop(el: ScrollElement, scroller?: HTMLElement) { if (isWindow(el)) { return 0; } const scrollTop = scroller ? getScrollTop(scroller) : getRootScrollTop(); return el.getBoundingClientRect().top + scrollTop; } export function getVisibleHeight(el: ScrollElement) { if (isWindow(el)) { return el.innerHeight; } return el.getBoundingClientRect().height; } export function getVisibleTop(el: ScrollElement) { if (isWindow(el)) { return 0; } return el.getBoundingClientRect().top; } const isIOS = checkIsIOS(); // hack for iOS12 page scroll // see: https://developers.weixin.qq.com/community/develop/doc/00044ae90742f8c82fb78fcae56800 export function resetScroll() { if (isIOS) { setRootScrollTop(getRootScrollTop()); } }