diff options
author | Allan Wang <me@allanwang.ca> | 2019-07-02 16:29:28 -0700 |
---|---|---|
committer | Allan Wang <me@allanwang.ca> | 2019-07-02 16:29:28 -0700 |
commit | 4c551386b100ea4b694c1e8f44596ba369e6b068 (patch) | |
tree | f18e167cf804e70820703e6951060004ef12e774 /app/src/web/ts | |
parent | 99e70f4489ce210e514c9194cdac288d2de651c4 (diff) | |
download | frost-4c551386b100ea4b694c1e8f44596ba369e6b068.tar.gz frost-4c551386b100ea4b694c1e8f44596ba369e6b068.tar.bz2 frost-4c551386b100ea4b694c1e8f44596ba369e6b068.zip |
Prevent horizontal swipes if html element can scroll horizontally
Diffstat (limited to 'app/src/web/ts')
-rw-r--r-- | app/src/web/ts/click_a.ts | 10 | ||||
-rw-r--r-- | app/src/web/ts/horizontal_scrolling.ts | 61 |
2 files changed, 67 insertions, 4 deletions
diff --git a/app/src/web/ts/click_a.ts b/app/src/web/ts/click_a.ts index 8d1d545b..1fd63683 100644 --- a/app/src/web/ts/click_a.ts +++ b/app/src/web/ts/click_a.ts @@ -91,14 +91,16 @@ prevented = true; }; + const _frostAllowClick = () => { + prevented = false; + clearTimeout(clickTimeout) + }; + document.addEventListener('click', _frostAClick, true); let clickTimeout: number | undefined = undefined; document.addEventListener('touchstart', () => { clickTimeout = setTimeout(_frostPreventClick, 400); }, true); - document.addEventListener('touchend', () => { - prevented = false; - clearTimeout(clickTimeout) - }, true); + document.addEventListener('touchend', _frostAllowClick, true); }).call(undefined); diff --git a/app/src/web/ts/horizontal_scrolling.ts b/app/src/web/ts/horizontal_scrolling.ts new file mode 100644 index 00000000..b104725e --- /dev/null +++ b/app/src/web/ts/horizontal_scrolling.ts @@ -0,0 +1,61 @@ +(function () { + + /** + * Go up at most [depth] times, to retrieve a parent matching the provided predicate + * If one is found, it is returned immediately. + * Otherwise, null is returned. + */ + function _parentEl(el: HTMLElement, depth: number, predicate: (el: HTMLElement) => boolean): HTMLElement | null { + for (let i = 0; i < depth + 1; i++) { + if (predicate(el)) { + return el + } + const parent = el.parentElement; + if (!parent) { + return null + } + el = parent + } + return null + } + + /** + * Check if element can scroll horizontally. + * We primarily rely on the overflow-x field. + * For performance reasons, we will check scrollWidth first to see if scrolling is a possibility + */ + function _canScrollHorizontally(el: HTMLElement): boolean { + /* + * Sometimes the offsetWidth is off by < 10px. We use the multiplier + * since the trays are typically more than 2 times greater + */ + if (el.scrollWidth > el.offsetWidth * 1.2) { + return true + } + const styles = window.getComputedStyle(el); + /* + * Works well in testing, but on mobile it just shows 'visible' + */ + return styles.overflowX === 'scroll'; + } + + const _frostCheckHorizontalScrolling = (e: Event) => { + const target = e.target || e.currentTarget || e.srcElement; + if (!(target instanceof HTMLElement)) { + return + } + const scrollable = _parentEl(target, 5, _canScrollHorizontally) !== null; + if (scrollable) { + console.log('Pause horizontal scrolling'); + Frost.allowHorizontalScrolling(false); + } + }; + + const _frostResetHorizontalScrolling = (e: Event) => { + Frost.allowHorizontalScrolling(true) + }; + + document.addEventListener('touchstart', _frostCheckHorizontalScrolling, true); + document.addEventListener('touchend', _frostResetHorizontalScrolling, true); +}).call(undefined); + |